Merge branch 'master' into cmake
This commit is contained in:
commit
81a344d52d
|
|
@ -796,22 +796,6 @@ setup_properties(const InterrogateFunction &ifunc, InterfaceMaker *interface_mak
|
|||
_flags |= F_iter;
|
||||
}
|
||||
|
||||
} else if (fname == "__getbuffer__") {
|
||||
if (_has_this && _parameters.size() == 3 &&
|
||||
TypeManager::is_integer(_return_type->get_new_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() == 2 &&
|
||||
TypeManager::is_pointer_to_Py_buffer(_parameters[1]._remap->get_orig_type())) {
|
||||
|
||||
_flags |= F_releasebuffer;
|
||||
}
|
||||
|
||||
} else if (fname == "compare_to") {
|
||||
if (_has_this && _parameters.size() == 2 &&
|
||||
TypeManager::is_integer(_return_type->get_new_type())) {
|
||||
|
|
@ -833,6 +817,12 @@ setup_properties(const InterrogateFunction &ifunc, InterfaceMaker *interface_mak
|
|||
_flags |= F_divide_float;
|
||||
}
|
||||
|
||||
} else if (fname == "get_key" || fname == "get_hash") {
|
||||
if (_has_this && _parameters.size() == 1 &&
|
||||
TypeManager::is_integer(_return_type->get_new_type())) {
|
||||
_flags |= F_hash;
|
||||
}
|
||||
|
||||
} else if (fname == "operator ()" || fname == "__call__") {
|
||||
// Call operators always take keyword arguments.
|
||||
_args_type = InterfaceMaker::AT_keyword_args;
|
||||
|
|
|
|||
|
|
@ -94,11 +94,10 @@ public:
|
|||
F_copy_constructor = 0x0100,
|
||||
F_explicit_self = 0x0200,
|
||||
F_iter = 0x0400,
|
||||
F_getbuffer = 0x0800,
|
||||
F_releasebuffer = 0x1000,
|
||||
F_compare_to = 0x2000,
|
||||
F_coerce_constructor = 0x4000,
|
||||
F_divide_float = 0x8000,
|
||||
F_compare_to = 0x0800,
|
||||
F_coerce_constructor = 0x1000,
|
||||
F_divide_float = 0x2000,
|
||||
F_hash = 0x4000,
|
||||
};
|
||||
|
||||
typedef vector<Parameter> Parameters;
|
||||
|
|
|
|||
|
|
@ -321,6 +321,7 @@ get_slotted_function_def(Object *obj, Function *func, FunctionRemap *remap,
|
|||
def._answer_location = string();
|
||||
def._wrapper_type = WT_none;
|
||||
def._min_version = 0;
|
||||
def._keep_method = false;
|
||||
|
||||
string method_name = func->_ifunc.get_name();
|
||||
bool is_unary_op = func->_ifunc.is_unary_op();
|
||||
|
|
@ -591,6 +592,14 @@ get_slotted_function_def(Object *obj, Function *func, FunctionRemap *remap,
|
|||
if (method_name == "__cmp__" || (remap->_flags & FunctionRemap::F_compare_to) != 0) {
|
||||
def._answer_location = "tp_compare";
|
||||
def._wrapper_type = WT_compare;
|
||||
def._keep_method = (method_name != "__cmp__");
|
||||
return true;
|
||||
}
|
||||
|
||||
if (method_name == "__hash__" || (remap->_flags & FunctionRemap::F_hash) != 0) {
|
||||
def._answer_location = "tp_hash";
|
||||
def._wrapper_type = WT_hash;
|
||||
def._keep_method = (method_name != "__hash__");
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -1397,7 +1406,6 @@ write_module(ostream &out, ostream *out_h, InterrogateModuleDef *def) {
|
|||
/////////////////////////////////////////////////////////////////////////////////////////////
|
||||
void InterfaceMakerPythonNative::
|
||||
write_module_class(ostream &out, Object *obj) {
|
||||
bool has_local_hash = false;
|
||||
bool has_local_repr = false;
|
||||
bool has_local_str = false;
|
||||
bool has_local_richcompare = false;
|
||||
|
|
@ -1496,6 +1504,9 @@ write_module_class(ostream &out, Object *obj) {
|
|||
slots[key] = slotted_def;
|
||||
slots[key]._remaps.insert(remap);
|
||||
}
|
||||
if (slotted_def._keep_method) {
|
||||
has_nonslotted = true;
|
||||
}
|
||||
|
||||
// Python 3 doesn't support nb_divide. It has nb_true_divide and also
|
||||
// nb_floor_divide, but they have different semantics than in C++. Ugh.
|
||||
|
|
@ -2272,6 +2283,26 @@ write_module_class(ostream &out, Object *obj) {
|
|||
}
|
||||
break;
|
||||
|
||||
case WT_hash:
|
||||
// Py_hash_t func(PyObject *self)
|
||||
{
|
||||
out << "//////////////////\n";
|
||||
out << "// A wrapper function to satisfy Python's internal calling conventions.\n";
|
||||
out << "// " << ClassName << " slot " << rfi->second._answer_location << " -> " << fname << "\n";
|
||||
out << "//////////////////\n";
|
||||
out << "static Py_hash_t " << def._wrapper_name << "(PyObject *self) {\n";
|
||||
out << " " << cClassName << " *local_this = NULL;\n";
|
||||
out << " if (!Dtool_Call_ExtractThisPointer(self, Dtool_" << ClassName << ", (void **)&local_this)) {\n";
|
||||
out << " return -1;\n";
|
||||
out << " }\n\n";
|
||||
|
||||
FunctionRemap *remap = *def._remaps.begin();
|
||||
vector_string params;
|
||||
out << " return (Py_hash_t) " << remap->call_function(out, 4, false, "local_this", params) << ";\n";
|
||||
out << "}\n\n";
|
||||
}
|
||||
break;
|
||||
|
||||
case WT_none:
|
||||
// Nothing special about the wrapper function: just write it normally.
|
||||
string fname = "static PyObject *" + def._wrapper_name + "(PyObject *self, PyObject *args, PyObject *kwds)\n";
|
||||
|
|
@ -2288,37 +2319,6 @@ write_module_class(ostream &out, Object *obj) {
|
|||
}
|
||||
}
|
||||
|
||||
string get_key = HasAGetKeyFunction(obj->_itype);
|
||||
if (!get_key.empty()) {
|
||||
out << "//////////////////\n";
|
||||
out << "// A LocalHash(getKey) Function for this type\n";
|
||||
out << "// " << ClassName << "\n";
|
||||
out << "//////////////////\n";
|
||||
out << "static Py_hash_t Dtool_HashKey_" << ClassName << "(PyObject *self) {\n";
|
||||
out << " " << cClassName << " *local_this = NULL;\n";
|
||||
out << " if (!Dtool_Call_ExtractThisPointer(self, Dtool_" << ClassName << ", (void **)&local_this)) {\n";
|
||||
out << " return -1;\n";
|
||||
out << " }\n\n";
|
||||
out << " return local_this->" << get_key << "();\n";
|
||||
out << "}\n\n";
|
||||
has_local_hash = true;
|
||||
} else {
|
||||
if (bases.size() == 0) {
|
||||
out << "//////////////////\n";
|
||||
out << "// A LocalHash(This Pointer) Function for this type\n";
|
||||
out << "// " << ClassName << "\n";
|
||||
out << "//////////////////\n";
|
||||
out << "static Py_hash_t Dtool_HashKey_" << ClassName << "(PyObject *self) {\n";
|
||||
out << " " << cClassName << " *local_this = NULL;\n";
|
||||
out << " if (!Dtool_Call_ExtractThisPointer(self, Dtool_" << ClassName << ", (void **)&local_this)) {\n";
|
||||
out << " return -1;\n";
|
||||
out << " }\n\n";
|
||||
out << " return (Py_hash_t) local_this;\n";
|
||||
out << "}\n\n";
|
||||
has_local_hash = true;
|
||||
}
|
||||
}
|
||||
|
||||
int need_repr = 0;
|
||||
if (slots.count("tp_repr") == 0) {
|
||||
need_repr = NeedsAReprFunction(obj->_itype);
|
||||
|
|
@ -2532,6 +2532,12 @@ write_module_class(ostream &out, Object *obj) {
|
|||
out << "};\n\n";
|
||||
}
|
||||
|
||||
// These fields are inherited together. We should either write all of them
|
||||
// or none of them so that they are inherited from DTOOL_SUPER_BASE.
|
||||
bool has_hash_compare = (slots.count("tp_hash") != 0 ||
|
||||
slots.count("tp_compare") != 0 ||
|
||||
has_local_richcompare);
|
||||
|
||||
bool has_parent_class = (obj->_itype.number_of_derivations() != 0);
|
||||
|
||||
// Output the type slot tables.
|
||||
|
|
@ -2661,12 +2667,11 @@ write_module_class(ostream &out, Object *obj) {
|
|||
out << "#if PY_MAJOR_VERSION >= 3\n";
|
||||
out << " 0, // tp_reserved\n";
|
||||
out << "#else\n";
|
||||
if (slots.count("tp_compare") != 0) {
|
||||
write_function_slot(out, 4, slots, "tp_compare");
|
||||
if (has_hash_compare) {
|
||||
write_function_slot(out, 4, slots, "tp_compare",
|
||||
"&DTOOL_PyObject_ComparePointers");
|
||||
} else {
|
||||
// We can/should still define a comparison in Python 2 that is more
|
||||
// meaningful that comparing id(x) with id(y).
|
||||
out << " &DTOOL_PyObject_ComparePointers,\n";
|
||||
out << " 0, // tp_compare\n";
|
||||
}
|
||||
out << "#endif\n";
|
||||
|
||||
|
|
@ -2693,10 +2698,10 @@ write_module_class(ostream &out, Object *obj) {
|
|||
}
|
||||
|
||||
// hashfunc tp_hash;
|
||||
if (has_local_hash) {
|
||||
out << " &Dtool_HashKey_" << ClassName << ",\n";
|
||||
if (has_hash_compare) {
|
||||
write_function_slot(out, 4, slots, "tp_hash", "&DTOOL_PyObject_HashPointer");
|
||||
} else {
|
||||
write_function_slot(out, 4, slots, "tp_hash");
|
||||
out << " 0, // tp_hash\n";
|
||||
}
|
||||
|
||||
// ternaryfunc tp_call;
|
||||
|
|
@ -2762,14 +2767,15 @@ write_module_class(ostream &out, Object *obj) {
|
|||
// richcmpfunc tp_richcompare;
|
||||
if (has_local_richcompare) {
|
||||
out << " &Dtool_RichCompare_" << ClassName << ",\n";
|
||||
} else if (has_local_hash) {
|
||||
} else if (has_hash_compare) {
|
||||
// All hashable types need to be comparable.
|
||||
out << "#if PY_MAJOR_VERSION >= 3\n";
|
||||
out << " &DTOOL_PyObject_RichCompare,\n";
|
||||
out << "#else\n";
|
||||
out << " 0,\n";
|
||||
out << " 0, // tp_richcompare\n";
|
||||
out << "#endif\n";
|
||||
} else {
|
||||
write_function_slot(out, 4, slots, "tp_richcompare");
|
||||
out << " 0, // tp_richcompare\n";
|
||||
}
|
||||
|
||||
// Py_ssize_t tp_weaklistoffset;
|
||||
|
|
@ -3114,7 +3120,7 @@ write_function_for_top(ostream &out, InterfaceMaker::Object *obj, InterfaceMaker
|
|||
}
|
||||
|
||||
SlottedFunctionDef slotted_def;
|
||||
if (!get_slotted_function_def(obj, func, remap, slotted_def)) {
|
||||
if (!get_slotted_function_def(obj, func, remap, slotted_def) || slotted_def._keep_method) {
|
||||
// It has a non-slotted remap, so we should write it.
|
||||
has_remaps = true;
|
||||
break;
|
||||
|
|
@ -4659,6 +4665,8 @@ write_function_instance(ostream &out, FunctionRemap *remap,
|
|||
}
|
||||
expected_params += "str";
|
||||
}
|
||||
// Remember to clear the TypeError that any of the above methods raise.
|
||||
clear_error = true;
|
||||
only_pyobjects = false;
|
||||
|
||||
} else if (TypeManager::is_bool(type)) {
|
||||
|
|
@ -6413,8 +6421,9 @@ is_remap_legal(FunctionRemap *remap) {
|
|||
}
|
||||
|
||||
// We don't currently support returning pointers, but we accept
|
||||
// them as function parameters.
|
||||
if (TypeManager::is_pointer_to_simple(remap->_return_type->get_orig_type())) {
|
||||
// them as function parameters. But const char * is an exception.
|
||||
if (!remap->_return_type->new_type_is_atomic_string() &&
|
||||
TypeManager::is_pointer_to_simple(remap->_return_type->get_orig_type())) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
@ -6611,47 +6620,6 @@ DoesInheritFromIsClass(const CPPStructType *inclass, const std::string &name) {
|
|||
return false;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Function : HasAGetKeyFunction
|
||||
//
|
||||
// does the class have a supportable get_key() or get_hash() to return
|
||||
// a usable Python hash? Returns the name of the method, or empty
|
||||
// string if there is no suitable method.
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
string InterfaceMakerPythonNative::
|
||||
HasAGetKeyFunction(const InterrogateType &itype_class) {
|
||||
InterrogateDatabase *idb = InterrogateDatabase::get_ptr();
|
||||
|
||||
int num_methods = itype_class.number_of_methods();
|
||||
int mi;
|
||||
for (mi = 0; mi < num_methods; mi++) {
|
||||
FunctionIndex func_index = itype_class.get_method(mi);
|
||||
const InterrogateFunction &ifunc = idb->get_function(func_index);
|
||||
if (ifunc.get_name() == "get_key" || ifunc.get_name() == "get_hash") {
|
||||
if (ifunc._instances != (InterrogateFunction::Instances *)NULL) {
|
||||
InterrogateFunction::Instances::const_iterator ii;
|
||||
for (ii = ifunc._instances->begin();
|
||||
ii != ifunc._instances->end();
|
||||
++ii) {
|
||||
CPPInstance *cppinst = (*ii).second;
|
||||
CPPFunctionType *cppfunc = cppinst->_type->as_function_type();
|
||||
|
||||
if (cppfunc != NULL) {
|
||||
if (cppfunc->_parameters != NULL &&
|
||||
cppfunc->_return_type != NULL &&
|
||||
TypeManager::is_integer(cppfunc->_return_type)) {
|
||||
if (cppfunc->_parameters->_parameters.size() == 0) {
|
||||
return ifunc.get_name();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return string();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Function : HasAGetClassTypeFunction
|
||||
//
|
||||
|
|
|
|||
|
|
@ -82,6 +82,7 @@ private:
|
|||
WT_inplace_ternary_operator,
|
||||
WT_traverse,
|
||||
WT_compare,
|
||||
WT_hash,
|
||||
};
|
||||
|
||||
// This enum is passed to the wrapper generation functions to indicate
|
||||
|
|
@ -118,6 +119,7 @@ private:
|
|||
int _min_version;
|
||||
string _wrapper_name;
|
||||
set<FunctionRemap*> _remaps;
|
||||
bool _keep_method;
|
||||
};
|
||||
|
||||
typedef std::map<string, SlottedFunctionDef> SlottedFunctions;
|
||||
|
|
@ -197,7 +199,6 @@ public:
|
|||
bool DoesInheritFromIsClass(const CPPStructType * inclass, const std::string &name);
|
||||
bool IsPandaTypedObject(CPPStructType * inclass) { return DoesInheritFromIsClass(inclass,"TypedObject"); };
|
||||
void write_python_instance(ostream &out, int indent_level, const std::string &return_expr, bool owns_memory, const std::string &class_name, CPPType *ctype, bool is_const);
|
||||
string HasAGetKeyFunction(const InterrogateType &itype_class);
|
||||
bool HasAGetClassTypeFunction(const InterrogateType &itype_class);
|
||||
int NeedsAStrFunction(const InterrogateType &itype_class);
|
||||
int NeedsAReprFunction(const InterrogateType &itype_class);
|
||||
|
|
|
|||
|
|
@ -30,14 +30,6 @@ PyMethodDef Dtool_Methods_DTOOL_SUPER_BASE[] = {
|
|||
{ NULL, NULL }
|
||||
};
|
||||
|
||||
static Py_hash_t Dtool_HashKey_DTOOL_SUPER_BASE(PyObject *self) {
|
||||
void *local_this = DTOOL_Call_GetPointerThis(self);
|
||||
if (local_this == NULL) {
|
||||
return -1;
|
||||
}
|
||||
return (Py_hash_t) local_this;
|
||||
};
|
||||
|
||||
EXPCL_DTOOLCONFIG void Dtool_PyModuleClassInit_DTOOL_SUPER_BASE(PyObject *module) {
|
||||
static bool initdone = false;
|
||||
if (!initdone) {
|
||||
|
|
@ -87,13 +79,13 @@ EXPORT_THIS Dtool_PyTypedObject Dtool_DTOOL_SUPER_BASE = {
|
|||
#if PY_MAJOR_VERSION >= 3
|
||||
0,
|
||||
#else
|
||||
&DTOOL_PyObject_Compare,
|
||||
&DTOOL_PyObject_ComparePointers,
|
||||
#endif
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
&Dtool_HashKey_DTOOL_SUPER_BASE,
|
||||
&DTOOL_PyObject_HashPointer,
|
||||
0,
|
||||
0,
|
||||
PyObject_GenericGetAttr,
|
||||
|
|
|
|||
|
|
@ -594,40 +594,13 @@ PyObject *Dtool_AddToDictionary(PyObject *self1, PyObject *args) {
|
|||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
/*
|
||||
inline long DTool_HashKey(PyObject * inst)
|
||||
{
|
||||
long outcome = (long)inst;
|
||||
PyObject *func = PyObject_GetAttrString(inst, "__hash__");
|
||||
if (func == NULL)
|
||||
{
|
||||
if (DtoolCanThisBeAPandaInstance(inst))
|
||||
if (((Dtool_PyInstDef *)inst)->_ptr_to_object != NULL)
|
||||
outcome = (long)((Dtool_PyInstDef *)inst)->_ptr_to_object;
|
||||
}
|
||||
else
|
||||
{
|
||||
PyObject *res = PyEval_CallObject(func, (PyObject *)NULL);
|
||||
Py_DECREF(func);
|
||||
if (res == NULL)
|
||||
return -1;
|
||||
if (PyInt_Check(res))
|
||||
{
|
||||
outcome = PyInt_AsLong(res);
|
||||
if (outcome == -1)
|
||||
outcome = -2;
|
||||
}
|
||||
else
|
||||
{
|
||||
PyErr_SetString(PyExc_TypeError,
|
||||
"__hash__() should return an int");
|
||||
outcome = -1;
|
||||
}
|
||||
Py_DECREF(res);
|
||||
}
|
||||
return outcome;
|
||||
Py_hash_t DTOOL_PyObject_HashPointer(PyObject *self) {
|
||||
if (self != NULL && DtoolCanThisBeAPandaInstance(self)) {
|
||||
Dtool_PyInstDef * pyself = (Dtool_PyInstDef *) self;
|
||||
return (Py_hash_t) pyself->_ptr_to_object;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
*/
|
||||
|
||||
/* Compare v to w. Return
|
||||
-1 if v < w or exception (PyErr_Occurred() true in latter case).
|
||||
|
|
|
|||
|
|
@ -489,40 +489,8 @@ EXPCL_DTOOLCONFIG PyObject *Dtool_BorrowThisReference(PyObject *self, PyObject *
|
|||
EXPCL_DTOOLCONFIG PyObject *Dtool_AddToDictionary(PyObject *self1, PyObject *args);
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
/*
|
||||
EXPCL_DTOOLCONFIG long DTool_HashKey(PyObject * inst)
|
||||
{
|
||||
long outcome = (long)inst;
|
||||
PyObject * func = PyObject_GetAttrString(inst, "__hash__");
|
||||
if (func == NULL)
|
||||
{
|
||||
if(DtoolCanThisBeAPandaInstance(inst))
|
||||
if(((Dtool_PyInstDef *)inst)->_ptr_to_object != NULL)
|
||||
outcome = (long)((Dtool_PyInstDef *)inst)->_ptr_to_object;
|
||||
}
|
||||
else
|
||||
{
|
||||
PyObject *res = PyEval_CallObject(func, (PyObject *)NULL);
|
||||
Py_DECREF(func);
|
||||
if (res == NULL)
|
||||
return -1;
|
||||
if (PyInt_Check(res))
|
||||
{
|
||||
outcome = PyInt_AsLong(res);
|
||||
if (outcome == -1)
|
||||
outcome = -2;
|
||||
}
|
||||
else
|
||||
{
|
||||
PyErr_SetString(PyExc_TypeError,
|
||||
"__hash__() should return an int");
|
||||
outcome = -1;
|
||||
}
|
||||
Py_DECREF(res);
|
||||
}
|
||||
return outcome;
|
||||
}
|
||||
*/
|
||||
|
||||
EXPCL_DTOOLCONFIG Py_hash_t DTOOL_PyObject_HashPointer(PyObject *obj);
|
||||
|
||||
/* Compare v to w. Return
|
||||
-1 if v < w or exception (PyErr_Occurred() true in latter case).
|
||||
|
|
|
|||
|
|
@ -714,7 +714,7 @@ if (COMPILER=="GCC"):
|
|||
SmartPkgEnable("FFMPEG", ffmpeg_libs, ffmpeg_libs, ffmpeg_libs)
|
||||
SmartPkgEnable("SWSCALE", "libswscale", "libswscale", ("libswscale", "libswscale/swscale.h"), target_pkg = "FFMPEG")
|
||||
SmartPkgEnable("SWRESAMPLE","libswresample", "libswresample", ("libswresample", "libswresample/swresample.h"), target_pkg = "FFMPEG")
|
||||
SmartPkgEnable("FFTW", "", ("fftw", "rfftw"), ("fftw.h", "rfftw.h"))
|
||||
SmartPkgEnable("FFTW", "", ("rfftw", "fftw"), ("fftw.h", "rfftw.h"))
|
||||
SmartPkgEnable("FMODEX", "", ("fmodex"), ("fmodex", "fmodex/fmod.h"))
|
||||
SmartPkgEnable("FREETYPE", "freetype2", ("freetype"), ("freetype2", "freetype2/freetype/freetype.h"))
|
||||
SmartPkgEnable("GL", "gl", ("GL"), ("GL/gl.h"), framework = "OpenGL")
|
||||
|
|
|
|||
Loading…
Reference in New Issue