Interrogate overhaul that dramatically increases performance for the simpler methods

This commit is contained in:
rdb 2014-07-18 13:54:38 +00:00
parent a76a011105
commit c257ce624e
17 changed files with 912 additions and 619 deletions

View File

@ -1,3 +1,4 @@
#define PY_SSIZE_T_CLEAN
#include <Python.h>
#ifdef _WIN32
@ -105,7 +106,7 @@ py_extend_frozen_modules(PyObject *self, PyObject *args) {
PyObject *tuple;
const char *name;
const char *code;
int size;
Py_ssize_t size;
tuple = PySequence_GetItem(list, i);
if (!PyArg_ParseTuple(tuple, "ss#", &name, &code, &size)) {
@ -178,7 +179,7 @@ py_get_frozen_module_code(PyObject *self, PyObject *args) {
if (strcmp(PyImport_FrozenModules[i].name, name) == 0) {
int is_package = (PyImport_FrozenModules[i].size < 0);
return Py_BuildValue("(s#i)", PyImport_FrozenModules[i].code,
abs(PyImport_FrozenModules[i].size),
(Py_ssize_t) abs(PyImport_FrozenModules[i].size),
is_package);
}
++i;

View File

@ -16,6 +16,10 @@
#include "typeRegistryNode.h"
#include "atomicAdjust.h"
#ifdef HAVE_PYTHON
#include "Python.h"
#endif
// This is initialized to zero by static initialization.
TypeHandle TypeHandle::_none;

View File

@ -66,7 +66,10 @@
class TypedObject;
#ifdef HAVE_PYTHON
#include "Python.h"
#ifndef PyObject_HEAD
struct _object;
typedef _object PyObject;
#endif
#endif
////////////////////////////////////////////////////////////////////
@ -127,15 +130,15 @@ PUBLISHED:
INLINE TypeHandle get_parent_towards(TypeHandle ancestor,
TypedObject *object = (TypedObject *)NULL) const;
INLINE int get_best_parent_from_Set(const std::set< int > &legal_vals) const;
INLINE int get_best_parent_from_Set(const std::set< int > &legal_vals) const;
#ifdef DO_MEMORY_USAGE
int get_memory_usage(MemoryClass memory_class) const;
void inc_memory_usage(MemoryClass memory_class, int size);
void dec_memory_usage(MemoryClass memory_class, int size);
#else
INLINE int get_memory_usage(MemoryClass) const { return 0; }
CONSTEXPR int get_memory_usage(MemoryClass) const { return 0; }
INLINE void inc_memory_usage(MemoryClass, int) { }
INLINE void dec_memory_usage(MemoryClass, int) { }
#endif // DO_MEMORY_USAGE
@ -170,4 +173,3 @@ EXPCL_DTOOL ostream &operator << (ostream &out, TypeHandle::MemoryClass mem_clas
#include "typeHandle.I"
#endif

View File

@ -303,26 +303,6 @@ make_wrapper_entry(FunctionIndex function_index) {
assert(!iwrapper._parameters.empty());
iwrapper._parameters.front()._parameter_flags |=
InterrogateFunctionWrapper::PF_is_this;
if (_parameters.size() >= 2 && _parameters[1]._name == "self" &&
TypeManager::is_pointer_to_PyObject(_parameters[1]._remap->get_orig_type())) {
// Here's a special case. If the first parameter of a nonstatic
// method is a PyObject * called "self", then we will
// automatically fill it in from the this pointer, and remove it
// from the generated parameter list.
_parameters.erase(_parameters.begin() + 1);
_flags |= F_explicit_self;
}
} else if (_type == T_constructor) {
// We also allow "self" to be passed in to a constructor, even
// though the constructor doesn't normally accept a this pointer.
// But this makes sense to Python programmers.
if (_parameters.size() >= 1 && _parameters[0]._name == "self" &&
TypeManager::is_pointer_to_PyObject(_parameters[0]._remap->get_orig_type())) {
_parameters.erase(_parameters.begin() + 0);
_flags |= F_explicit_self;
}
}
if (!_void_return) {
@ -650,12 +630,32 @@ setup_properties(const InterrogateFunction &ifunc, InterfaceMaker *interface_mak
}
// Check for a special meaning by name and signature.
if (_type == T_normal) {
int first_param = 0;
if (_has_this) {
first_param = 1;
}
int first_param = 0;
if (_has_this) {
first_param = 1;
}
if (_has_this || _type == T_constructor) {
if (_parameters.size() > first_param && _parameters[first_param]._name == "self" &&
TypeManager::is_pointer_to_PyObject(_parameters[first_param]._remap->get_orig_type())) {
// Here's a special case. If the first parameter of a nonstatic
// method is a PyObject * called "self", then we will
// automatically fill it in from the this pointer, and remove it
// from the generated parameter list.
_parameters.erase(_parameters.begin() + first_param);
_flags |= F_explicit_self;
}
}
if (_parameters.size() == first_param) {
_flags |= F_no_args;
} else if (_parameters.size() == first_param + 1) {
_flags |= F_single_arg;
} else {
_flags |= F_varargs;
}
if (_type == T_normal) {
if (fname == "operator []" || fname == "__getitem__") {
_flags |= F_getitem;
if (_has_this && _parameters.size() == 2) {
@ -670,7 +670,7 @@ setup_properties(const InterrogateFunction &ifunc, InterfaceMaker *interface_mak
if (_has_this && _parameters.size() > 2) {
if (TypeManager::is_integer(_parameters[1]._remap->get_new_type())) {
// Its first parameter is an int parameter, presumably an index.
_flags |= F_setitem_int;
_flags |= (F_setitem_int | F_varargs);
}
}
@ -681,55 +681,69 @@ setup_properties(const InterrogateFunction &ifunc, InterfaceMaker *interface_mak
_flags |= F_size;
}
} else if (fname == "make_copy" ) {
} else if (fname == "make_copy") {
if (_has_this && _parameters.size() == 1 &&
TypeManager::is_pointer(_return_type->get_new_type())) {
// It receives no parameters, and returns a pointer.
_flags |= F_make_copy;
}
} else if (fname == "__iter__" ) {
} else if (fname == "__iter__") {
if (_has_this && _parameters.size() == 1 &&
TypeManager::is_pointer(_return_type->get_new_type())) {
// It receives no parameters, and returns a pointer.
_flags |= F_iter;
}
} else if (fname == "__getbuffer__" ) {
if (_has_this && _parameters.size() == 4 &&
} else if (fname == "__getbuffer__") {
if (_has_this && _parameters.size() == 3 &&
TypeManager::is_integer(_return_type->get_new_type()) &&
TypeManager::is_pointer_to_PyObject(_parameters[1]._remap->get_orig_type()) &&
TypeManager::is_pointer_to_Py_buffer(_parameters[2]._remap->get_orig_type()) &&
TypeManager::is_integer(_parameters[3]._remap->get_orig_type())) {
TypeManager::is_pointer_to_Py_buffer(_parameters[1]._remap->get_orig_type()) &&
TypeManager::is_integer(_parameters[2]._remap->get_orig_type())) {
_flags |= F_getbuffer;
}
} else if (fname == "__releasebuffer__" ) {
if (_has_this && _parameters.size() == 3 &&
TypeManager::is_pointer_to_PyObject(_parameters[1]._remap->get_orig_type()) &&
TypeManager::is_pointer_to_Py_buffer(_parameters[2]._remap->get_orig_type())) {
} else if (fname == "__releasebuffer__") {
if (_has_this && _parameters.size() == 2 &&
TypeManager::is_pointer_to_Py_buffer(_parameters[1]._remap->get_orig_type())) {
_flags |= F_releasebuffer;
}
} else if (fname == "compare_to" ) {
} else if (fname == "compare_to") {
if (_has_this && _parameters.size() == 2 &&
TypeManager::is_integer(_return_type->get_new_type())) {
// It receives one parameter, and returns an integer.
_flags |= F_compare_to;
}
} else if (fname == "operator ()" || fname == "__call__") {
// Call operators always take keyword arguments.
_flags |= (F_varargs | F_keyword_args);
} else if (fname == "__setattr__" || fname == "__getattr__") {
// Just to prevent these from getting keyword arguments.
} else {
if (_flags & F_varargs) {
// Every other method can take keyword arguments, if they
// take more than one argument.
_flags |= F_keyword_args;
}
}
} else if (_type == T_constructor) {
if (!_has_this && _parameters.size() == 1) {
if (TypeManager::unwrap(_parameters[0]._remap->get_orig_type()) ==
TypeManager::unwrap(_return_type->get_orig_type())) {
// If this is the only parameter, and it's the same as the
// "this" type, this is a copy constructor.
_flags |= F_copy_constructor;
}
if (!_has_this && _parameters.size() == 1 &&
TypeManager::unwrap(_parameters[0]._remap->get_orig_type()) ==
TypeManager::unwrap(_return_type->get_orig_type())) {
// If this is the only parameter, and it's the same as the
// "this" type, this is a copy constructor.
_flags |= F_copy_constructor;
}
// Constructors always take varargs and keyword args.
_flags |= (F_varargs | F_keyword_args);
}
return true;

View File

@ -91,6 +91,10 @@ public:
F_getbuffer = 0x0200,
F_releasebuffer = 0x0400,
F_compare_to = 0x0800,
F_no_args = 0x1000,
F_single_arg = 0x2000,
F_varargs = 0x4000,
F_keyword_args = 0x8000,
};
typedef vector<Parameter> Parameters;

View File

@ -663,7 +663,7 @@ record_function(const InterrogateType &itype, FunctionIndex func_index) {
make_function_remap(itype, ifunc, cppfunc, num_default_parameters);
if (remap != (FunctionRemap *)NULL) {
func->_remaps.push_back(remap);
// If *any* of the variants of this function has a "this"
// pointer, the entire set of functions is deemed to have a
// "this" pointer.
@ -672,7 +672,7 @@ record_function(const InterrogateType &itype, FunctionIndex func_index) {
}
func->_flags |= remap->_flags;
// Make a wrapper for the function.
FunctionWrapperIndex wrapper_index =
remap->make_wrapper_entry(func_index);
@ -685,6 +685,13 @@ record_function(const InterrogateType &itype, FunctionIndex func_index) {
}
}
// If there's a remap taking no args and a remap
// taking only a single arg, assume we need varargs.
if ((func->_flags & FunctionRemap::F_no_args) &&
(func->_flags & FunctionRemap::F_single_arg)) {
func->_flags |= FunctionRemap::F_varargs;
}
return func;
}

View File

@ -36,17 +36,12 @@ InterfaceMakerPython(InterrogateModuleDef *def) :
void InterfaceMakerPython::
write_includes(ostream &out) {
InterfaceMaker::write_includes(out);
out << "#undef HAVE_LONG_LONG\n"
<< "#undef _POSIX_C_SOURCE\n\n"
out << "#undef _POSIX_C_SOURCE\n\n"
<< "#if PYTHON_FRAMEWORK\n"
<< " #include \"Python/Python.h\"\n"
<< "#else\n"
<< " #include \"Python.h\"\n"
<< "#endif\n"
<< "#ifdef HAVE_LONG_LONG\n"
<< "#undef HAVE_LONG_LONG\n"
<< "#endif \n";
<< "#endif\n";
}
////////////////////////////////////////////////////////////////////

File diff suppressed because it is too large Load Diff

View File

@ -89,25 +89,31 @@ private:
};
static bool get_slotted_function_def(Object *obj, Function *func, SlottedFunctionDef &def);
void write_prototype_for_name(ostream &out, Function *func, const std::string &name);
void write_prototype_for(ostream &out, Function *func);
void write_function_for_name(ostream &out, Object *obj, Function *func, const std::string &name, const std::string &PreProcess, const std::string &ClassName,
bool coercion_allowed, bool &coercion_attempted);
void write_function_for_top(ostream &out, Object *obj, Function *func, const std::string &PreProcess);
void write_function_instance(ostream &out, Object *obj, Function *func,
FunctionRemap *remap, string &expected_params,
int indent_level, bool errors_fatal,
ostream &forwarddecl, const std::string &functionnamestr,
bool is_inplace, bool coercion_allowed,
bool &coercion_attempted,
const string &args_cleanup);
void write_function_for_name(ostream &out, Object *obj, Function *func,
const std::string &name, const std::string &PreProcess,
bool coercion_allowed, bool &coercion_attempted,
bool single_arg, bool have_varargs,
bool have_kwargs, bool return_int);
void write_function_forset(ostream &out, Object *obj, Function *func,
std::set<FunctionRemap*> &remaps, string &expected_params,
int indent_level, ostream &forwarddecl, bool inplace,
bool coercion_allowed, bool &coercion_attempted,
const string &args_cleanup);
int indent_level, bool inplace,
bool coercion_allowed, bool &coercion_attempted,
bool single_arg, bool have_varargs,
bool have_kwargs, bool return_int,
const string &first_expr = string());
void write_function_instance(ostream &out, Object *obj, Function *func,
FunctionRemap *remap, string &expected_params,
int indent_level, bool is_inplace,
bool coercion_allowed, bool &coercion_attempted,
bool single_arg, bool have_varargs,
bool have_kwargs, bool return_int,
const string &first_pexpr = string());
void pack_return_value(ostream &out, int indent_level, FunctionRemap *remap,
const std::string &return_expr, bool in_place);
@ -121,17 +127,16 @@ private:
void write_class_prototypes(ostream &out) ;
void write_class_declarations(ostream &out, ostream *out_h, Object *obj);
void write_class_details(ostream &out, Object *obj);
void do_assert_init(ostream &out, int &indent_level, bool constructor, const string &args_cleanup) const;
public:
bool is_remap_legal(FunctionRemap &remap);
bool is_remap_legal(FunctionRemap *remap);
bool is_function_legal( Function *func);
bool is_cpp_type_legal(CPPType *ctype);
bool isExportThisRun(CPPType *ctype);
bool isExportThisRun(Function *func);
bool isFunctionWithThis( Function *func);
bool IsRunTimeTyped(const InterrogateType &itype);
// comunicates the cast capabilites among methods..
struct CastDetails {
CPPStructType *_structType;

View File

@ -934,7 +934,7 @@ bool TypeManager::
is_double(CPPType *type) {
switch (type->get_subtype()) {
case CPPDeclaration::ST_const:
return is_float(type->as_const_type()->_wrapped_around);
return is_double(type->as_const_type()->_wrapped_around);
case CPPDeclaration::ST_simple:
{
@ -1199,7 +1199,8 @@ is_PyObject(CPPType *type) {
return is_PyObject(type->as_const_type()->_wrapped_around);
case CPPDeclaration::ST_extension:
return (type->get_local_name(&parser) == "PyObject");
return (type->get_local_name(&parser) == "PyObject" ||
type->get_local_name(&parser) == "_object");
default:
return false;

View File

@ -83,7 +83,7 @@ int Dtool_Init_DTOOL_SUPER_BASE(PyObject *self, PyObject *args, PyObject *kwds)
return -1;
}
int Dtool_InitNoCoerce_DTOOL_SUPER_BASE(PyObject *self, PyObject *args, PyObject *kwds) {
int Dtool_InitNoCoerce_DTOOL_SUPER_BASE(PyObject *self, PyObject *args) {
PyErr_SetString(PyExc_TypeError, "cannot init super base");
return -1;
}

View File

@ -79,9 +79,21 @@ attempt_coercion(PyObject *self, Dtool_PyTypedObject *classdef,
if (classdef->_PyType.tp_new != NULL) {
obj = classdef->_PyType.tp_new(&classdef->_PyType, self, NULL);
assert(obj != NULL);
if (classdef->_Dtool_InitNoCoerce(obj, self, NULL) != 0) {
Py_DECREF(obj);
obj = NULL;
if (PyTuple_Check(self)) {
// A tuple was passed, which we assume are the constructor arguments.
if (classdef->_Dtool_InitNoCoerce(obj, self) != 0) {
Py_DECREF(obj);
obj = NULL;
}
} else {
// We need to pack the value into an args tuple.
PyObject *args = PyTuple_Pack(1, self);
if (classdef->_Dtool_InitNoCoerce(obj, args) != 0) {
Py_DECREF(obj);
obj = NULL;
}
Py_DECREF(args);
}
}
if (obj == NULL) {
@ -93,7 +105,11 @@ attempt_coercion(PyObject *self, Dtool_PyTypedObject *classdef,
PyObject *make = PyObject_GetAttrString((PyObject *)classdef, "make");
if (make != NULL) {
PyErr_Clear();
obj = PyObject_Call(make, self, NULL);
if (PyTuple_Check(self)) {
obj = PyObject_CallObject(make, self);
} else {
obj = PyObject_CallFunctionObjArgs(make, self, NULL);
}
Py_DECREF(make);
}
}
@ -598,7 +614,7 @@ int DTOOL_PyObject_Compare(PyObject *v1, PyObject *v2) {
PyErr_Clear();
} else {
PyObject *res = NULL;
PyObject *args = Py_BuildValue("(O)", v2);
PyObject *args = PyTuple_Pack(1, v2);
if (args != NULL) {
res = PyObject_Call(func, args, NULL);
Py_DECREF(args);

View File

@ -42,18 +42,23 @@
#if defined(HAVE_PYTHON) && !defined(CPPPARSER)
#ifdef HAVE_LONG_LONG
#undef HAVE_LONG_LONG
#endif
#ifdef _POSIX_C_SOURCE
#undef _POSIX_C_SOURCE
#endif
#define PY_SSIZE_T_CLEAN 1
#include "Python.h"
#include "structmember.h"
#ifdef HAVE_LONG_LONG
#undef HAVE_LONG_LONG
#endif
#ifndef HAVE_LONG_LONG
#define PyLong_FromLongLong(x) PyLong_FromLong((long) (x))
#define PyLong_FromUnsignedLongLong(x) PyLong_FromUnsignedLong((unsigned long) (x))
#define PyLong_AsLongLong(x) PyLong_AsLong(x)
#define PyLong_AsUnsignedLongLong(x) PyLong_AsUnsignedLong(x)
#define PyLong_AsUnsignedLongLongMask(x) PyLong_AsUnsignedLongMask(x)
#define PyLong_AsLongLongAndOverflow(x) PyLong_AsLongAndOverflow(x)
#endif
#if PY_VERSION_HEX < 0x02050000
@ -139,7 +144,7 @@ typedef void * ( * ConvertFunctionType )(PyObject *,Dtool_PyTypedObject * );
typedef void * ( * ConvertFunctionType1 )(void *, Dtool_PyTypedObject *);
typedef void ( *FreeFunction )(PyObject *);
typedef void ( *PyModuleClassInit)(PyObject *module);
typedef int ( *InitNoCoerce)(PyObject *self, PyObject *args, PyObject *kwds);
typedef int ( *InitNoCoerce)(PyObject *self, PyObject *args);
//inline Dtool_PyTypedObject * Dtool_RuntimeTypeDtoolType(int type);
inline void Dtool_Deallocate_General(PyObject * self);
@ -369,7 +374,7 @@ EXPCL_DTOOLCONFIG PyObject *DTool_CreatePyInstance(void *local_this, Dtool_PyTyp
extern EXPORT_THIS Dtool_PyTypedObject Dtool_##CLASS_NAME;\
extern struct PyMethodDef Dtool_Methods_##CLASS_NAME[];\
int Dtool_Init_##CLASS_NAME(PyObject *self, PyObject *args, PyObject *kwds);\
int Dtool_InitNoCoerce_##CLASS_NAME(PyObject *self, PyObject *args, PyObject *kwds);\
int Dtool_InitNoCoerce_##CLASS_NAME(PyObject *self, PyObject *args);\
PyObject * Dtool_new_##CLASS_NAME(PyTypeObject *type, PyObject *args, PyObject *kwds);\
void * Dtool_UpcastInterface_##CLASS_NAME(PyObject *self, Dtool_PyTypedObject *requested_type);\
void * Dtool_DowncastInterface_##CLASS_NAME(void *self, Dtool_PyTypedObject *requested_type);\

View File

@ -20,7 +20,9 @@
#ifndef PYTHON_H
#define PYTHON_H
class PyObject;
struct _object;
typedef _object PyObject;
class PyThreadState;
typedef int Py_ssize_t;
struct Py_buffer;

View File

@ -18,6 +18,7 @@ extern "C" {
EXPCL_PYSTUB int PyArg_Parse(...);
EXPCL_PYSTUB int PyArg_ParseTuple(...);
EXPCL_PYSTUB int PyArg_ParseTupleAndKeywords(...);
EXPCL_PYSTUB int PyArg_UnpackTuple(...);
EXPCL_PYSTUB int PyBool_FromLong(...);
EXPCL_PYSTUB int PyBuffer_Release(...);
EXPCL_PYSTUB int PyBytes_AsString(...);
@ -84,12 +85,14 @@ extern "C" {
EXPCL_PYSTUB int PyModule_AddObject(...);
EXPCL_PYSTUB int PyModule_AddStringConstant(...);
EXPCL_PYSTUB int PyModule_Create2(...);
EXPCL_PYSTUB int PyNumber_Check(...);
EXPCL_PYSTUB int PyNumber_Float(...);
EXPCL_PYSTUB int PyNumber_Int(...);
EXPCL_PYSTUB int PyNumber_Long(...);
EXPCL_PYSTUB int PyObject_ASCII(...);
EXPCL_PYSTUB int PyObject_Call(...);
EXPCL_PYSTUB int PyObject_CallFunction(...);
EXPCL_PYSTUB int PyObject_CallFunctionObjArgs(...);
EXPCL_PYSTUB int PyObject_CallMethod(...);
EXPCL_PYSTUB int PyObject_CallMethodObjArgs(...);
EXPCL_PYSTUB int PyObject_CallObject(...);
@ -153,8 +156,14 @@ extern "C" {
EXPCL_PYSTUB int Py_InitModule4(...);
EXPCL_PYSTUB int Py_InitModule4_64(...);
EXPCL_PYSTUB int Py_InitModule4TraceRefs(...);
EXPCL_PYSTUB int _PyArg_ParseTuple_SizeT(...);
EXPCL_PYSTUB int _PyArg_ParseTupleAndKeywords_SizeT(...);
EXPCL_PYSTUB int _PyArg_Parse_SizeT(...);
EXPCL_PYSTUB int _PyObject_CallFunction_SizeT(...);
EXPCL_PYSTUB int _PyObject_CallMethod_SizeT(...);
EXPCL_PYSTUB int _PyObject_DebugFree(...);
EXPCL_PYSTUB int _PyObject_Del(...);
EXPCL_PYSTUB int _Py_BuildValue_SizeT(...);
EXPCL_PYSTUB int _Py_Dealloc(...);
EXPCL_PYSTUB int _Py_NegativeRefcount(...);
EXPCL_PYSTUB int _Py_RefTotal(...);
@ -183,6 +192,7 @@ extern "C" {
int PyArg_Parse(...) { return 0; };
int PyArg_ParseTuple(...) { return 0; }
int PyArg_ParseTupleAndKeywords(...) { return 0; }
int PyArg_UnpackTuple(...) { return 0; };
int PyBool_FromLong(...) { return 0; }
int PyBuffer_Release(...) { return 0; }
int PyBytes_AsString(...) { return 0; }
@ -249,12 +259,14 @@ int PyModule_AddIntConstant(...) { return 0; };
int PyModule_AddObject(...) { return 0; };
int PyModule_AddStringConstant(...) { return 0; };
int PyModule_Create2(...) { return 0; };
int PyNumber_Check(...) { return 0; }
int PyNumber_Float(...) { return 0; }
int PyNumber_Int(...) { return 0; }
int PyNumber_Long(...) { return 0; }
int PyObject_ASCII(...) { return 0; }
int PyObject_Call(...) { return 0; }
int PyObject_CallFunction(...) { return 0; }
int PyObject_CallFunctionObjArgs(...) { return 0; }
int PyObject_CallMethod(...) { return 0; }
int PyObject_CallMethodObjArgs(...) { return 0; }
int PyObject_CallObject(...) { return 0; }
@ -318,8 +330,14 @@ int Py_BuildValue(...) { return 0; }
int Py_InitModule4(...) { return 0; }
int Py_InitModule4_64(...) { return 0; }
int Py_InitModule4TraceRefs(...) { return 0; };
int _PyArg_ParseTuple_SizeT(...) { return 0; };
int _PyArg_ParseTupleAndKeywords_SizeT(...) { return 0; };
int _PyArg_Parse_SizeT(...) { return 0; };
int _PyObject_CallFunction_SizeT(...) { return 0; };
int _PyObject_CallMethod_SizeT(...) { return 0; };
int _PyObject_DebugFree(...) { return 0; };
int _PyObject_Del(...) { return 0; };
int _Py_BuildValue_SizeT(...) { return 0; };
int _Py_Dealloc(...) { return 0; };
int _Py_NegativeRefcount(...) { return 0; };
int _Py_RefTotal(...) { return 0; };

View File

@ -168,7 +168,7 @@ __reduce_persist__(PyObject *self, PyObject *pickler) const {
}
}
PyObject *result = Py_BuildValue("(O(s#))", func, bam_stream.data(), bam_stream.size());
PyObject *result = Py_BuildValue("(O(s#))", func, bam_stream.data(), (Py_ssize_t) bam_stream.size());
Py_DECREF(func);
Py_DECREF(this_class);
return result;

View File

@ -119,7 +119,7 @@ __reduce_persist__(PyObject *self, PyObject *pickler) const {
}
}
PyObject *result = Py_BuildValue("(O(Os#))", func, this_class, bam_stream.data(), bam_stream.size());
PyObject *result = Py_BuildValue("(O(Os#))", func, this_class, bam_stream.data(), (Py_ssize_t) bam_stream.size());
Py_DECREF(func);
Py_DECREF(this_class);
return result;
@ -234,10 +234,10 @@ py_decode_TypedWritable_from_bam_stream_persist(PyObject *pickler, PyObject *thi
PyObject *result;
if (py_reader != NULL){
result = PyObject_CallFunction(func, (char *)"(s#O)", data.data(), data.size(), py_reader);
result = PyObject_CallFunction(func, (char *)"(s#O)", data.data(), (Py_ssize_t) data.size(), py_reader);
Py_DECREF(py_reader);
} else {
result = PyObject_CallFunction(func, (char *)"(s#)", data.data(), data.size());
result = PyObject_CallFunction(func, (char *)"(s#)", data.data(), (Py_ssize_t) data.size());
}
if (result == NULL) {