interrogate: clean py_panda.h; use macros to access Dtool_PyInstDef

This commit is contained in:
rdb 2017-12-12 22:01:34 +01:00
parent 18678214ae
commit 193e4b5f59
14 changed files with 184 additions and 174 deletions

View File

@ -55,7 +55,7 @@ __init__(PyObject *path) {
if (Py_TYPE(path) == &Dtool_Filename._PyType) {
// Copy constructor.
(*_this) = *((Filename *)((Dtool_PyInstDef *)path)->_ptr_to_object);
*_this = *(Filename *)DtoolInstance_VOID_PTR(path);
return;
}

View File

@ -1094,14 +1094,14 @@ write_class_details(ostream &out, Object *obj) {
// Write support methods to cast from and to pointers of this type.
{
out << "static void *Dtool_UpcastInterface_" << ClassName << "(PyObject *self, Dtool_PyTypedObject *requested_type) {\n";
out << " Dtool_PyTypedObject *SelfType = ((Dtool_PyInstDef *)self)->_My_Type;\n";
out << " if (SelfType != Dtool_Ptr_" << ClassName << ") {\n";
out << " Dtool_PyTypedObject *type = DtoolInstance_TYPE(self);\n";
out << " if (type != &Dtool_" << ClassName << ") {\n";
out << " printf(\"" << ClassName << " ** Bad Source Type-- Requesting Conversion from %s to %s\\n\", Py_TYPE(self)->tp_name, requested_type->_PyType.tp_name); fflush(NULL);\n";;
out << " return NULL;\n";
out << " }\n";
out << "\n";
out << " " << cClassName << " *local_this = (" << cClassName << " *)((Dtool_PyInstDef *)self)->_ptr_to_object;\n";
out << " if (requested_type == Dtool_Ptr_" << ClassName << ") {\n";
out << " " << cClassName << " *local_this = (" << cClassName << " *)DtoolInstance_VOID_PTR(self);\n";
out << " if (requested_type == &Dtool_" << ClassName << ") {\n";
out << " return local_this;\n";
out << " }\n";
@ -2220,13 +2220,13 @@ write_module_class(ostream &out, Object *obj) {
// provide a writable buffer or a readonly buffer.
const string const_this = "(const " + cClassName + " *)local_this";
if (remap_const != NULL && remap_nonconst != NULL) {
out << " if (!((Dtool_PyInstDef *)self)->_is_const) {\n";
out << " if (!DtoolInstance_IS_CONST(self)) {\n";
out << " return " << remap_nonconst->call_function(out, 4, false, "local_this", params_nonconst) << ";\n";
out << " } else {\n";
out << " return " << remap_const->call_function(out, 4, false, const_this, params_const) << ";\n";
out << " }\n";
} else if (remap_nonconst != NULL) {
out << " if (!((Dtool_PyInstDef *)self)->_is_const) {\n";
out << " if (!DtoolInstance_IS_CONST(self)) {\n";
out << " return " << remap_nonconst->call_function(out, 4, false, "local_this", params_nonconst) << ";\n";
out << " } else {\n";
out << " Dtool_Raise_TypeError(\"Cannot call " << ClassName << ".__getbuffer__() on a const object.\");\n";
@ -2285,7 +2285,7 @@ write_module_class(ostream &out, Object *obj) {
string return_expr;
const string const_this = "(const " + cClassName + " *)local_this";
if (remap_const != NULL && remap_nonconst != NULL) {
out << " if (!((Dtool_PyInstDef *)self)->_is_const) {\n";
out << " if (!DtoolInstance_IS_CONST(self)) {\n";
return_expr = remap_nonconst->call_function(out, 4, false, "local_this", params_nonconst);
if (!return_expr.empty()) {
out << " " << return_expr << ";\n";
@ -3078,7 +3078,7 @@ write_module_class(ostream &out, Object *obj) {
out << " Dtool_" << ClassName << "._PyType.tp_bases = PyTuple_Pack(" << bases.size() << baseargs << ");\n";
} else {
out << " Dtool_" << ClassName << "._PyType.tp_base = (PyTypeObject *)Dtool_Ptr_DTOOL_SUPER_BASE;\n";
out << " Dtool_" << ClassName << "._PyType.tp_base = (PyTypeObject *)&Dtool_DTOOL_SUPER_BASE;\n";
}
int num_nested = obj->_itype.number_of_nested_types();
@ -3515,8 +3515,9 @@ write_function_for_name(ostream &out, Object *obj,
out << " if (!Dtool_Call_ExtractThisPointer_NonConst(self, Dtool_" << ClassName << ", "
<< "(void **)&local_this, \"" << classNameFromCppName(cClassName, false)
<< "." << methodNameFromCppName(remap, cClassName, false) << "\")) {\n";
} else {
out << " if (!Dtool_Call_ExtractThisPointer(self, Dtool_" << ClassName << ", (void **)&local_this)) {\n";
out << " if (!DtoolInstance_GetPointer(self, local_this, Dtool_" << ClassName << ")) {\n";
}
error_return(out, 4, return_flags);
@ -3616,7 +3617,7 @@ write_function_for_name(ostream &out, Object *obj,
if (strip_keyword_args) {
// None of the remaps take any keyword arguments, so let's check that
// we take none. This saves some checks later on.
indent(out, 4) << "if (kwds == NULL || ((PyDictObject *)kwds)->ma_used == 0) {\n";
indent(out, 4) << "if (kwds == NULL || PyDict_GET_SIZE(kwds) == 0) {\n";
if (min_args == 1 && min_args == 1) {
indent(out, 4) << " PyObject *arg = PyTuple_GET_ITEM(args, 0);\n";
write_function_forset(out, mii->second, min_args, max_args, expected_params, 6,
@ -3890,11 +3891,10 @@ write_coerce_constructor(ostream &out, Object *obj, bool is_const) {
// Note: this relies on the PT() being initialized to NULL. This is
// currently the case in all invocations, but this may not be true in the
// future.
out << " DTOOL_Call_ExtractThisPointerForType(args, &Dtool_" << ClassName << ", (void**)&coerced.cheat());\n";
out << " if (coerced != NULL) {\n";
out << " if (DtoolInstance_GetPointer(args, coerced.cheat(), Dtool_" << ClassName << ")) {\n";
out << " // The argument is already of matching type, no need to coerce.\n";
if (!is_const) {
out << " if (!((Dtool_PyInstDef *)args)->_is_const) {\n";
out << " if (!DtoolInstance_IS_CONST(args)) {\n";
out << " // A non-const instance is required, which this is.\n";
out << " coerced->ref();\n";
out << " return true;\n";
@ -3909,9 +3909,8 @@ write_coerce_constructor(ostream &out, Object *obj, bool is_const) {
out << cClassName << " *Dtool_Coerce_" << ClassName << "(PyObject *args, " << cClassName << " &coerced) {\n";
out << " " << cClassName << " *local_this;\n";
out << " DTOOL_Call_ExtractThisPointerForType(args, &Dtool_" << ClassName << ", (void**)&local_this);\n";
out << " if (local_this != NULL) {\n";
out << " if (((Dtool_PyInstDef *)args)->_is_const) {\n";
out << " if (DtoolInstance_GetPointer(args, local_this, Dtool_" << ClassName << ")) {\n";
out << " if (DtoolInstance_IS_CONST(args)) {\n";
out << " // This is a const object. Make a copy.\n";
out << " coerced = *(const " << cClassName << " *)local_this;\n";
out << " return &coerced;\n";
@ -4340,7 +4339,7 @@ write_function_forset(ostream &out,
if (all_nonconst) {
// Yes, they do. Check that the parameter has the required constness.
indent(out, indent_level)
<< "if (!((Dtool_PyInstDef *)self)->_is_const) {\n";
<< "if (!DtoolInstance_IS_CONST(self)) {\n";
indent_level += 2;
verify_const = false;
}
@ -4406,7 +4405,7 @@ write_function_forset(ostream &out,
if (verify_const && (remap->_has_this && !remap->_const_method)) {
// If it's a non-const method, we only allow a non-const this.
indent(out, indent_level)
<< "if (!((Dtool_PyInstDef *)self)->_is_const) {\n";
<< "if (!DtoolInstance_IS_CONST(self)) {\n";
} else {
indent(out, indent_level)
<< "{\n";
@ -4441,7 +4440,7 @@ write_function_forset(ostream &out,
if (verify_const && (remap->_has_this && !remap->_const_method)) {
indent(out, indent_level)
<< "if (!((Dtool_PyInstDef *)self)->_is_const) {\n";
<< "if (!DtoolInstance_IS_CONST(self)) {\n";
} else {
indent(out, indent_level)
<< "{\n";
@ -5525,14 +5524,13 @@ write_function_instance(ostream &out, FunctionRemap *remap,
// This function does the same thing in this case and is slightly
// simpler. But maybe we should just reorganize these functions
// entirely?
extra_convert << ";\n";
if (is_optional) {
extra_convert << " ";
}
extra_convert
<< "DTOOL_Call_ExtractThisPointerForType(" << param_name
<< ", Dtool_Ptr_" << make_safe_name(class_name)
<< ", (void **)&" << param_name << "_this);\n";
extra_convert << " = NULL;\n";
int indent_level = is_optional ? 2 : 0;
indent(extra_convert, indent_level)
<< "DtoolInstance_GetPointer(" << param_name
<< ", " << param_name << "_this"
<< ", *Dtool_Ptr_" << make_safe_name(class_name)
<< ");\n";
} else {
extra_convert << boolalpha
<< " = (" << class_name << " *)"
@ -6796,7 +6794,7 @@ write_getset(ostream &out, Object *obj, Property *property) {
out << " if (wrap != NULL) {\n"
" wrap->_getitem_func = &Dtool_" << ClassName << "_" << ielem.get_name() << "_Mapping_Getitem;\n";
if (!property->_setter_remaps.empty()) {
out << " if (!((Dtool_PyInstDef *)self)->_is_const) {\n";
out << " if (!DtoolInstance_IS_CONST(self)) {\n";
out << " wrap->_setitem_func = &Dtool_" << ClassName << "_" << ielem.get_name() << "_Mapping_Setitem;\n";
out << " }\n";
}
@ -6828,7 +6826,7 @@ write_getset(ostream &out, Object *obj, Property *property) {
" wrap->_len_func = &Dtool_" << ClassName << "_" << ielem.get_name() << "_Len;\n"
" wrap->_getitem_func = &Dtool_" << ClassName << "_" << ielem.get_name() << "_Sequence_Getitem;\n";
if (!property->_setter_remaps.empty()) {
out << " if (!((Dtool_PyInstDef *)self)->_is_const) {\n";
out << " if (!DtoolInstance_IS_CONST(self)) {\n";
out << " wrap->_setitem_func = &Dtool_" << ClassName << "_" << ielem.get_name() << "_Sequence_Setitem;\n";
if (property->_inserter != nullptr) {
out << " wrap->_insert_func = &Dtool_" << ClassName << "_" << ielem.get_name() << "_Sequence_insert;\n";

View File

@ -155,6 +155,12 @@ extern EXPCL_INTERROGATEDB PyTupleObject Dtool_EmptyTuple;
# define PyLong_AsLongLongAndOverflow(x) PyLong_AsLongAndOverflow(x)
#endif
/* Python 3.7 */
#ifndef PyDict_GET_SIZE
# define PyDict_GET_SIZE(mp) (((PyDictObject *)mp)->ma_used)
#endif
/* Other Python implementations */
// _PyErr_OCCURRED is an undocumented macro version of PyErr_Occurred.

View File

@ -11,20 +11,54 @@
* @date 2016-06-06
*/
#ifdef _MSC_VER
#define _IS_FINAL(T) (__is_sealed(T))
#elif defined(__GNUC__)
#define _IS_FINAL(T) (__is_final(T))
#else
#define _IS_FINAL(T) (0)
#endif
/**
* Template function that can be used to extract any TypedObject pointer from
* a wrapped Python object.
*/
template<class T> INLINE bool
DTOOL_Call_ExtractThisPointer(PyObject *self, T *&into) {
if (DtoolCanThisBeAPandaInstance(self)) {
DtoolInstance_GetPointer(PyObject *self, T *&into) {
if (DtoolInstance_Check(self)) {
Dtool_PyTypedObject *target_class = Dtool_RuntimeTypeDtoolType(get_type_handle(T).get_index());
if (target_class != NULL) {
into = (T*) ((Dtool_PyInstDef *)self)->_My_Type->_Dtool_UpcastInterface(self, target_class);
return (into != NULL);
if (target_class != nullptr) {
if (_IS_FINAL(T)) {
if (DtoolInstance_TYPE(self) == target_class) {
into = (T *)DtoolInstance_VOID_PTR(self);
}
} else {
into = (T *)DtoolInstance_UPCAST(self, *target_class);
}
return (into != nullptr);
}
}
into = NULL;
into = nullptr;
return false;
}
/**
* Template function that can be used to extract any TypedObject pointer from
* a wrapped Python object. In this case, the Dtool_PyTypedObject is known.
*/
template<class T> INLINE bool
DtoolInstance_GetPointer(PyObject *self, T *&into, Dtool_PyTypedObject &target_class) {
if (DtoolInstance_Check(self)) {
if (_IS_FINAL(T)) {
if (DtoolInstance_TYPE(self) == &target_class) {
into = (T *)DtoolInstance_VOID_PTR(self);
}
} else {
into = (T *)DtoolInstance_UPCAST(self, target_class);
}
return (into != nullptr);
}
into = nullptr;
return false;
}
@ -73,7 +107,7 @@ Dtool_CheckNoArgs(PyObject *args) {
ALWAYS_INLINE bool
Dtool_CheckNoArgs(PyObject *args, PyObject *kwds) {
return PyTuple_GET_SIZE(args) == 0 &&
(kwds == NULL || ((PyDictObject *)kwds)->ma_used == 0);
(kwds == nullptr || PyDict_GET_SIZE(kwds) == 0);
}
/**

View File

@ -31,34 +31,14 @@ static RuntimeTypeMap runtime_type_map;
static RuntimeTypeSet runtime_type_set;
static NamedTypeMap named_type_map;
/**
* Given a valid (non-NULL) PyObject, does a simple check to see if it might
* be an instance of a Panda type. It does this using a signature that is
* encoded on each instance.
*/
bool DtoolCanThisBeAPandaInstance(PyObject *self) {
// simple sanity check for the class type..size.. will stop basic foobars..
// It is arguably better to use something like this:
// PyType_IsSubtype(Py_TYPE(self), &Dtool_DTOOL_SUPER_BASE._PyType) ...but
// probably not as fast.
if (Py_TYPE(self)->tp_basicsize >= (int)sizeof(Dtool_PyInstDef)) {
Dtool_PyInstDef *pyself = (Dtool_PyInstDef *) self;
if (pyself->_signature == PY_PANDA_SIGNATURE) {
return true;
}
}
return false;
}
/**
*/
void DTOOL_Call_ExtractThisPointerForType(PyObject *self, Dtool_PyTypedObject *classdef, void **answer) {
if (DtoolCanThisBeAPandaInstance(self)) {
*answer = ((Dtool_PyInstDef *)self)->_My_Type->_Dtool_UpcastInterface(self, classdef);
if (DtoolInstance_Check(self)) {
*answer = DtoolInstance_UPCAST(self, *classdef);
} else {
*answer = NULL;
*answer = nullptr;
}
}
@ -68,12 +48,12 @@ void DTOOL_Call_ExtractThisPointerForType(PyObject *self, Dtool_PyTypedObject *c
* was of the wrong type, raises an AttributeError.
*/
bool Dtool_Call_ExtractThisPointer(PyObject *self, Dtool_PyTypedObject &classdef, void **answer) {
if (self == NULL || !DtoolCanThisBeAPandaInstance(self) || ((Dtool_PyInstDef *)self)->_ptr_to_object == NULL) {
if (self == nullptr || !DtoolInstance_Check(self) || DtoolInstance_VOID_PTR(self) == nullptr) {
Dtool_Raise_TypeError("C++ object is not yet constructed, or already destructed.");
return false;
}
*answer = ((Dtool_PyInstDef *)self)->_My_Type->_Dtool_UpcastInterface(self, &classdef);
*answer = DtoolInstance_UPCAST(self, classdef);
return true;
}
@ -88,12 +68,12 @@ bool Dtool_Call_ExtractThisPointer(PyObject *self, Dtool_PyTypedObject &classdef
bool Dtool_Call_ExtractThisPointer_NonConst(PyObject *self, Dtool_PyTypedObject &classdef,
void **answer, const char *method_name) {
if (self == NULL || !DtoolCanThisBeAPandaInstance(self) || ((Dtool_PyInstDef *)self)->_ptr_to_object == NULL) {
if (self == nullptr || !DtoolInstance_Check(self) || DtoolInstance_VOID_PTR(self) == nullptr) {
Dtool_Raise_TypeError("C++ object is not yet constructed, or already destructed.");
return false;
}
if (((Dtool_PyInstDef *)self)->_is_const) {
if (DtoolInstance_IS_CONST(self)) {
// All overloads of this function are non-const.
PyErr_Format(PyExc_TypeError,
"Cannot call %s() on a const object.",
@ -101,7 +81,7 @@ bool Dtool_Call_ExtractThisPointer_NonConst(PyObject *self, Dtool_PyTypedObject
return false;
}
*answer = ((Dtool_PyInstDef *)self)->_My_Type->_Dtool_UpcastInterface(self, &classdef);
*answer = DtoolInstance_UPCAST(self, classdef);
return true;
}
@ -131,19 +111,19 @@ void *
DTOOL_Call_GetPointerThisClass(PyObject *self, Dtool_PyTypedObject *classdef,
int param, const string &function_name, bool const_ok,
bool report_errors) {
// if (PyErr_Occurred()) { return NULL; }
if (self == NULL) {
// if (PyErr_Occurred()) { return nullptr; }
if (self == nullptr) {
if (report_errors) {
return Dtool_Raise_TypeError("self is NULL");
return Dtool_Raise_TypeError("self is nullptr");
}
return NULL;
return nullptr;
}
if (DtoolCanThisBeAPandaInstance(self)) {
void *result = ((Dtool_PyInstDef *)self)->_My_Type->_Dtool_UpcastInterface(self, classdef);
if (DtoolInstance_Check(self)) {
void *result = DtoolInstance_UPCAST(self, *classdef);
if (result != NULL) {
if (const_ok || !((Dtool_PyInstDef *)self)->_is_const) {
if (result != nullptr) {
if (const_ok || !DtoolInstance_IS_CONST(self)) {
return result;
}
@ -152,7 +132,7 @@ DTOOL_Call_GetPointerThisClass(PyObject *self, Dtool_PyTypedObject *classdef,
"%s() argument %d may not be const",
function_name.c_str(), param);
}
return NULL;
return nullptr;
}
}
@ -160,17 +140,14 @@ DTOOL_Call_GetPointerThisClass(PyObject *self, Dtool_PyTypedObject *classdef,
return Dtool_Raise_ArgTypeError(self, param, function_name.c_str(), classdef->_PyType.tp_name);
}
return NULL;
return nullptr;
}
void *DTOOL_Call_GetPointerThis(PyObject *self) {
if (self != NULL) {
if (DtoolCanThisBeAPandaInstance(self)) {
Dtool_PyInstDef * pyself = (Dtool_PyInstDef *) self;
return pyself->_ptr_to_object;
}
if (self != nullptr && DtoolInstance_Check(self)) {
return DtoolInstance_VOID_PTR(self);
}
return NULL;
return nullptr;
}
/**
@ -713,7 +690,7 @@ PyObject *Dtool_BorrowThisReference(PyObject *self, PyObject *args) {
PyObject *to_in = NULL;
if (PyArg_UnpackTuple(args, "Dtool_BorrowThisReference", 2, 2, &to_in, &from_in)) {
if (DtoolCanThisBeAPandaInstance(from_in) && DtoolCanThisBeAPandaInstance(to_in)) {
if (DtoolInstance_Check(from_in) && DtoolInstance_Check(to_in)) {
Dtool_PyInstDef *from = (Dtool_PyInstDef *) from_in;
Dtool_PyInstDef *to = (Dtool_PyInstDef *) to_in;
@ -758,9 +735,8 @@ PyObject *Dtool_AddToDictionary(PyObject *self1, PyObject *args) {
}
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;
if (self != nullptr && DtoolInstance_Check(self)) {
return (Py_hash_t)DtoolInstance_VOID_PTR(self);
}
return -1;
}
@ -933,14 +909,14 @@ bool Dtool_ExtractArg(PyObject **result, PyObject *args, PyObject *kwds,
const char *keyword) {
if (PyTuple_GET_SIZE(args) == 1) {
if (kwds == NULL || ((PyDictObject *)kwds)->ma_used == 0) {
if (kwds == nullptr || PyDict_GET_SIZE(kwds) == 0) {
*result = PyTuple_GET_ITEM(args, 0);
return true;
}
} else if (PyTuple_GET_SIZE(args) == 0) {
PyObject *key;
Py_ssize_t ppos = 0;
if (kwds != NULL && ((PyDictObject *)kwds)->ma_used == 1 &&
if (kwds != nullptr && PyDict_GET_SIZE(kwds) == 1 &&
PyDict_Next(kwds, &ppos, &key, result)) {
// We got the item, we just need to make sure that it had the right key.
#if PY_VERSION_HEX >= 0x03060000
@ -961,7 +937,7 @@ bool Dtool_ExtractArg(PyObject **result, PyObject *args, PyObject *kwds,
*/
bool Dtool_ExtractArg(PyObject **result, PyObject *args, PyObject *kwds) {
if (PyTuple_GET_SIZE(args) == 1 &&
(kwds == NULL || ((PyDictObject *)kwds)->ma_used == 0)) {
(kwds == nullptr || PyDict_GET_SIZE(kwds) == 0)) {
*result = PyTuple_GET_ITEM(args, 0);
return true;
}
@ -979,12 +955,12 @@ bool Dtool_ExtractOptionalArg(PyObject **result, PyObject *args, PyObject *kwds,
const char *keyword) {
if (PyTuple_GET_SIZE(args) == 1) {
if (kwds == NULL || ((PyDictObject *)kwds)->ma_used == 0) {
if (kwds == nullptr || PyDict_GET_SIZE(kwds) == 0) {
*result = PyTuple_GET_ITEM(args, 0);
return true;
}
} else if (PyTuple_GET_SIZE(args) == 0) {
if (kwds != NULL && ((PyDictObject *)kwds)->ma_used == 1) {
if (kwds != nullptr && PyDict_GET_SIZE(kwds) == 1) {
PyObject *key;
Py_ssize_t ppos = 0;
if (!PyDict_Next(kwds, &ppos, &key, result)) {
@ -1011,7 +987,7 @@ bool Dtool_ExtractOptionalArg(PyObject **result, PyObject *args, PyObject *kwds,
* Variant of Dtool_ExtractOptionalArg that does not accept a keyword argument.
*/
bool Dtool_ExtractOptionalArg(PyObject **result, PyObject *args, PyObject *kwds) {
if (kwds != NULL && ((PyDictObject *)kwds)->ma_used != 0) {
if (kwds != nullptr && PyDict_GET_SIZE(kwds) != 0) {
return false;
}
if (PyTuple_GET_SIZE(args) == 1) {

View File

@ -127,7 +127,7 @@ static void Dtool_FreeInstance_##CLASS_NAME(PyObject *self) {\
#else // NDEBUG
#define Define_Dtool_FreeInstance_Private(CLASS_NAME,CNAME)\
static void Dtool_FreeInstance_##CLASS_NAME(PyObject *self) {\
if (((Dtool_PyInstDef *)self)->_ptr_to_object != NULL) {\
if (DtoolInstance_VOID_PTR(self) != nullptr) {\
if (((Dtool_PyInstDef *)self)->_memory_rules) {\
cerr << "Detected leak for " << #CLASS_NAME \
<< " which interrogate cannot delete.\n"; \
@ -139,9 +139,9 @@ static void Dtool_FreeInstance_##CLASS_NAME(PyObject *self) {\
#define Define_Dtool_FreeInstance(CLASS_NAME,CNAME)\
static void Dtool_FreeInstance_##CLASS_NAME(PyObject *self) {\
if (((Dtool_PyInstDef *)self)->_ptr_to_object != NULL) {\
if (DtoolInstance_VOID_PTR(self) != nullptr) {\
if (((Dtool_PyInstDef *)self)->_memory_rules) {\
delete ((CNAME *)((Dtool_PyInstDef *)self)->_ptr_to_object);\
delete (CNAME *)DtoolInstance_VOID_PTR(self);\
}\
}\
Py_TYPE(self)->tp_free(self);\
@ -149,9 +149,9 @@ static void Dtool_FreeInstance_##CLASS_NAME(PyObject *self) {\
#define Define_Dtool_FreeInstanceRef(CLASS_NAME,CNAME)\
static void Dtool_FreeInstance_##CLASS_NAME(PyObject *self) {\
if (((Dtool_PyInstDef *)self)->_ptr_to_object != NULL) {\
if (DtoolInstance_VOID_PTR(self) != nullptr) {\
if (((Dtool_PyInstDef *)self)->_memory_rules) {\
unref_delete((CNAME *)((Dtool_PyInstDef *)self)->_ptr_to_object);\
unref_delete((CNAME *)DtoolInstance_VOID_PTR(self));\
}\
}\
Py_TYPE(self)->tp_free(self);\
@ -163,8 +163,17 @@ static void Dtool_FreeInstance_##CLASS_NAME(PyObject *self) {\
Py_TYPE(self)->tp_free(self);\
}
// Simple Recognition Functions..
EXPCL_INTERROGATEDB bool DtoolCanThisBeAPandaInstance(PyObject *self);
// Use DtoolInstance_Check to check whether a PyObject* is a DtoolInstance.
#define DtoolInstance_Check(obj) \
(Py_TYPE(obj)->tp_basicsize >= (int)sizeof(Dtool_PyInstDef) && \
((Dtool_PyInstDef *)obj)->_signature == PY_PANDA_SIGNATURE)
// These macros access the DtoolInstance without error checking.
#define DtoolInstance_TYPE(obj) (((Dtool_PyInstDef *)obj)->_My_Type)
#define DtoolInstance_IS_CONST(obj) (((Dtool_PyInstDef *)obj)->_is_const)
#define DtoolInstance_VOID_PTR(obj) (((Dtool_PyInstDef *)obj)->_ptr_to_object)
#define DtoolInstance_INIT_PTR(obj, ptr) { ((Dtool_PyInstDef *)obj)->_ptr_to_object = (void*)(ptr); }
#define DtoolInstance_UPCAST(obj, type) (((Dtool_PyInstDef *)(obj))->_My_Type->_Dtool_UpcastInterface((obj), &(type)))
// ** HACK ** allert.. Need to keep a runtime type dictionary ... that is
// forward declared of typed object. We rely on the fact that typed objects
@ -192,20 +201,14 @@ EXPCL_INTERROGATEDB bool Dtool_Call_ExtractThisPointer(PyObject *self, Dtool_PyT
EXPCL_INTERROGATEDB bool Dtool_Call_ExtractThisPointer_NonConst(PyObject *self, Dtool_PyTypedObject &classdef,
void **answer, const char *method_name);
template<class T> INLINE bool DTOOL_Call_ExtractThisPointer(PyObject *self, T *&into);
template<class T> INLINE bool DtoolInstance_GetPointer(PyObject *self, T *&into);
template<class T> INLINE bool DtoolInstance_GetPointer(PyObject *self, T *&into, Dtool_PyTypedObject &classdef);
// Functions related to error reporting.
EXPCL_INTERROGATEDB bool _Dtool_CheckErrorOccurred();
// _PyErr_OCCURRED is an undocumented macro version of PyErr_Occurred.
// Some implementations of the CPython API (e.g. PyPy's cpyext) do not define
// it, so in these cases we just silently fall back to PyErr_Occurred.
#ifndef _PyErr_OCCURRED
#define _PyErr_OCCURRED() PyErr_Occurred()
#endif
#ifdef NDEBUG
#define Dtool_CheckErrorOccurred() (UNLIKELY(_PyErr_OCCURRED() != NULL))
#define Dtool_CheckErrorOccurred() (UNLIKELY(_PyErr_OCCURRED() != nullptr))
#else
#define Dtool_CheckErrorOccurred() (UNLIKELY(_Dtool_CheckErrorOccurred()))
#endif
@ -232,8 +235,8 @@ EXPCL_INTERROGATEDB PyObject *Dtool_Return_Bool(bool value);
EXPCL_INTERROGATEDB PyObject *_Dtool_Return(PyObject *value);
#ifdef NDEBUG
#define Dtool_Return_None() (_PyErr_OCCURRED() != NULL ? NULL : (Py_INCREF(Py_None), Py_None))
#define Dtool_Return(value) (_PyErr_OCCURRED() != NULL ? NULL : value)
#define Dtool_Return_None() (LIKELY(_PyErr_OCCURRED() == nullptr) ? (Py_INCREF(Py_None), Py_None) : nullptr)
#define Dtool_Return(value) (LIKELY(_PyErr_OCCURRED() == nullptr) ? value : nullptr)
#else
#define Dtool_Return_None() _Dtool_Return_None()
#define Dtool_Return(value) _Dtool_Return(value)

View File

@ -583,12 +583,11 @@ do_python_task() {
return DS_done;
}
} else if (DtoolCanThisBeAPandaInstance(result)) {
} else if (DtoolInstance_Check(result)) {
// We are waiting for an AsyncFuture (eg. other task) to finish.
void *ptr = ((Dtool_PyInstDef *)result)->_My_Type->_Dtool_UpcastInterface(result, &Dtool_AsyncFuture);
if (ptr != nullptr) {
AsyncFuture *fut = (AsyncFuture *)DtoolInstance_UPCAST(result, Dtool_AsyncFuture);
if (fut != nullptr) {
// Suspend execution of this task until this other task has completed.
AsyncFuture *fut = (AsyncFuture *)ptr;
AsyncTaskManager *manager = fut->_manager;
if (manager == nullptr) {
manager = _manager;

View File

@ -97,7 +97,7 @@ __init__(PyObject *self, PyObject *source) {
// Now construct the internal list by copying the elements one-at-a-time
// from Python.
PyObject *dict = ((Dtool_PyInstDef *)self)->_My_Type->_PyType.tp_dict;
PyObject *dict = DtoolInstance_TYPE(self)->_PyType.tp_dict;
PyObject *push_back = PyDict_GetItemString(dict, "push_back");
if (push_back == NULL) {
PyErr_BadArgument();
@ -105,7 +105,7 @@ __init__(PyObject *self, PyObject *source) {
}
// We need to initialize the this pointer before we can call push_back.
((Dtool_PyInstDef *)self)->_ptr_to_object = (void *)this->_this;
DtoolInstance_INIT_PTR(self, this->_this);
Py_ssize_t size = PySequence_Size(source);
this->_this->reserve(size);

View File

@ -43,10 +43,10 @@
#include "colorSpace.h"
#include "geomEnums.h"
#include "bamCacheRecord.h"
#include "pnmImage.h"
#include "pfmFile.h"
#include "asyncFuture.h"
class PNMImage;
class PfmFile;
class TextureContext;
class FactoryParams;
class PreparedGraphicsObjects;

View File

@ -33,15 +33,12 @@ set_ram_image(PyObject *image, Texture::CompressionMode compression,
nassertv(compression != Texture::CM_default);
// Check if perhaps a PointerToArray object was passed in.
if (DtoolCanThisBeAPandaInstance(image)) {
Dtool_PyInstDef *inst = (Dtool_PyInstDef *)image;
if (inst->_My_Type == &Dtool_ConstPointerToArray_unsigned_char) {
_this->set_ram_image(*(const CPTA_uchar *)inst->_ptr_to_object, compression, page_size);
if (DtoolInstance_Check(image)) {
if (DtoolInstance_TYPE(image) == &Dtool_ConstPointerToArray_unsigned_char) {
_this->set_ram_image(*(const CPTA_uchar *)DtoolInstance_VOID_PTR(image), compression, page_size);
return;
} else if (inst->_My_Type == &Dtool_PointerToArray_unsigned_char) {
_this->set_ram_image(*(const PTA_uchar *)inst->_ptr_to_object, compression, page_size);
} else if (DtoolInstance_TYPE(image) == &Dtool_PointerToArray_unsigned_char) {
_this->set_ram_image(*(const PTA_uchar *)DtoolInstance_VOID_PTR(image), compression, page_size);
return;
}
}
@ -99,15 +96,12 @@ set_ram_image(PyObject *image, Texture::CompressionMode compression,
void Extension<Texture>::
set_ram_image_as(PyObject *image, const string &provided_format) {
// Check if perhaps a PointerToArray object was passed in.
if (DtoolCanThisBeAPandaInstance(image)) {
Dtool_PyInstDef *inst = (Dtool_PyInstDef *)image;
if (inst->_My_Type == &Dtool_ConstPointerToArray_unsigned_char) {
_this->set_ram_image_as(*(const CPTA_uchar *)inst->_ptr_to_object, provided_format);
if (DtoolInstance_Check(image)) {
if (DtoolInstance_TYPE(image) == &Dtool_ConstPointerToArray_unsigned_char) {
_this->set_ram_image_as(*(const CPTA_uchar *)DtoolInstance_VOID_PTR(image), provided_format);
return;
} else if (inst->_My_Type == &Dtool_PointerToArray_unsigned_char) {
_this->set_ram_image_as(*(const PTA_uchar *)inst->_ptr_to_object, provided_format);
} else if (DtoolInstance_TYPE(image) == &Dtool_PointerToArray_unsigned_char) {
_this->set_ram_image_as(*(const PTA_uchar *)DtoolInstance_VOID_PTR(image), provided_format);
return;
}
}

View File

@ -46,8 +46,7 @@ __init__(PyObject *self, PyObject *sequence) {
}
NodePath *path;
DTOOL_Call_ExtractThisPointerForType(item, &Dtool_NodePath, (void **)&path);
if (path == (NodePath *)NULL) {
if (!DtoolInstance_GetPointer(item, path, Dtool_NodePath)) {
// Unable to add item--probably it wasn't of the appropriate type.
ostringstream stream;
stream << "Element " << i << " in sequence passed to NodePathCollection constructor is not a NodePath";

View File

@ -114,7 +114,7 @@ __reduce_persist__(PyObject *self, PyObject *pickler) const {
// It's OK if there's no bamWriter.
PyErr_Clear();
} else {
DTOOL_Call_ExtractThisPointerForType(py_writer, &Dtool_BamWriter, (void **)&writer);
DtoolInstance_GetPointer(py_writer, writer, Dtool_BamWriter);
Py_DECREF(py_writer);
}
}
@ -228,7 +228,7 @@ py_decode_NodePath_from_bam_stream_persist(PyObject *unpickler, vector_uchar dat
// It's OK if there's no bamReader.
PyErr_Clear();
} else {
DTOOL_Call_ExtractThisPointerForType(py_reader, &Dtool_BamReader, (void **)&reader);
DtoolInstance_GetPointer(py_reader, reader, Dtool_BamReader);
Py_DECREF(py_reader);
}
}

View File

@ -91,80 +91,79 @@ __init__(CPT_InternalName name, PyObject *value, int priority) {
_this->_stored_vector = LCAST(PN_stdfloat, vec);
}
} else if (DtoolCanThisBeAPandaInstance(value)) {
Dtool_PyInstDef *inst = (Dtool_PyInstDef *)value;
} else if (DtoolInstance_Check(value)) {
void *ptr;
if ((ptr = inst->_My_Type->_Dtool_UpcastInterface(value, &Dtool_Texture))) {
if ((ptr = DtoolInstance_UPCAST(value, Dtool_Texture))) {
_this->_type = ShaderInput::M_texture;
_this->_value = (Texture *)ptr;
} else if ((ptr = inst->_My_Type->_Dtool_UpcastInterface(value, &Dtool_NodePath))) {
} else if ((ptr = DtoolInstance_UPCAST(value, Dtool_NodePath))) {
_this->_type = ShaderInput::M_nodepath;
_this->_value = new ParamNodePath(*(const NodePath *)ptr);
} else if (inst->_My_Type->_Dtool_UpcastInterface(value, &Dtool_PointerToVoid)) {
if ((ptr = inst->_My_Type->_Dtool_UpcastInterface(value, &Dtool_PointerToArray_float))) {
} else if (DtoolInstance_UPCAST(value, Dtool_PointerToVoid)) {
if ((ptr = DtoolInstance_UPCAST(value, Dtool_PointerToArray_float))) {
_this->_type = ShaderInput::M_numeric;
_this->_stored_ptr = *(const PTA_float *)ptr;
} else if ((ptr = inst->_My_Type->_Dtool_UpcastInterface(value, &Dtool_PointerToArray_double))) {
} else if ((ptr = DtoolInstance_UPCAST(value, Dtool_PointerToArray_double))) {
_this->_type = ShaderInput::M_numeric;
_this->_stored_ptr = *(const PTA_double *)ptr;
} else if ((ptr = inst->_My_Type->_Dtool_UpcastInterface(value, &Dtool_PointerToArray_int))) {
} else if ((ptr = DtoolInstance_UPCAST(value, Dtool_PointerToArray_int))) {
_this->_type = ShaderInput::M_numeric;
_this->_stored_ptr = *(const PTA_int *)ptr;
} else if ((ptr = inst->_My_Type->_Dtool_UpcastInterface(value, &Dtool_PointerToArray_UnalignedLVecBase4f))) {
} else if ((ptr = DtoolInstance_UPCAST(value, Dtool_PointerToArray_UnalignedLVecBase4f))) {
_this->_type = ShaderInput::M_numeric;
_this->_stored_ptr = *(const PTA_LVecBase4f *)ptr;
} else if ((ptr = inst->_My_Type->_Dtool_UpcastInterface(value, &Dtool_PointerToArray_LVecBase3f))) {
} else if ((ptr = DtoolInstance_UPCAST(value, Dtool_PointerToArray_LVecBase3f))) {
_this->_type = ShaderInput::M_numeric;
_this->_stored_ptr = *(const PTA_LVecBase3f *)ptr;
} else if ((ptr = inst->_My_Type->_Dtool_UpcastInterface(value, &Dtool_PointerToArray_LVecBase2f))) {
} else if ((ptr = DtoolInstance_UPCAST(value, Dtool_PointerToArray_LVecBase2f))) {
_this->_type = ShaderInput::M_numeric;
_this->_stored_ptr = *(const PTA_LVecBase2f *)ptr;
} else if ((ptr = inst->_My_Type->_Dtool_UpcastInterface(value, &Dtool_PointerToArray_UnalignedLMatrix4f))) {
} else if ((ptr = DtoolInstance_UPCAST(value, Dtool_PointerToArray_UnalignedLMatrix4f))) {
_this->_type = ShaderInput::M_numeric;
_this->_stored_ptr = *(const PTA_LMatrix4f *)ptr;
} else if ((ptr = inst->_My_Type->_Dtool_UpcastInterface(value, &Dtool_PointerToArray_LMatrix3f))) {
} else if ((ptr = DtoolInstance_UPCAST(value, Dtool_PointerToArray_LMatrix3f))) {
_this->_type = ShaderInput::M_numeric;
_this->_stored_ptr = *(const PTA_LMatrix3f *)ptr;
} else if ((ptr = inst->_My_Type->_Dtool_UpcastInterface(value, &Dtool_PointerToArray_UnalignedLVecBase4d))) {
} else if ((ptr = DtoolInstance_UPCAST(value, Dtool_PointerToArray_UnalignedLVecBase4d))) {
_this->_type = ShaderInput::M_numeric;
_this->_stored_ptr = *(const PTA_LVecBase4d *)ptr;
} else if ((ptr = inst->_My_Type->_Dtool_UpcastInterface(value, &Dtool_PointerToArray_LVecBase3d))) {
} else if ((ptr = DtoolInstance_UPCAST(value, Dtool_PointerToArray_LVecBase3d))) {
_this->_type = ShaderInput::M_numeric;
_this->_stored_ptr = *(const PTA_LVecBase3d *)ptr;
} else if ((ptr = inst->_My_Type->_Dtool_UpcastInterface(value, &Dtool_PointerToArray_LVecBase2d))) {
} else if ((ptr = DtoolInstance_UPCAST(value, Dtool_PointerToArray_LVecBase2d))) {
_this->_type = ShaderInput::M_numeric;
_this->_stored_ptr = *(const PTA_LVecBase2d *)ptr;
} else if ((ptr = inst->_My_Type->_Dtool_UpcastInterface(value, &Dtool_PointerToArray_UnalignedLMatrix4d))) {
} else if ((ptr = DtoolInstance_UPCAST(value, Dtool_PointerToArray_UnalignedLMatrix4d))) {
_this->_type = ShaderInput::M_numeric;
_this->_stored_ptr = *(const PTA_LMatrix4d *)ptr;
} else if ((ptr = inst->_My_Type->_Dtool_UpcastInterface(value, &Dtool_PointerToArray_LMatrix3d))) {
} else if ((ptr = DtoolInstance_UPCAST(value, Dtool_PointerToArray_LMatrix3d))) {
_this->_type = ShaderInput::M_numeric;
_this->_stored_ptr = *(const PTA_LMatrix3d *)ptr;
} else if ((ptr = inst->_My_Type->_Dtool_UpcastInterface(value, &Dtool_PointerToArray_UnalignedLVecBase4i))) {
} else if ((ptr = DtoolInstance_UPCAST(value, Dtool_PointerToArray_UnalignedLVecBase4i))) {
_this->_type = ShaderInput::M_numeric;
_this->_stored_ptr = *(const PTA_LVecBase4i *)ptr;
} else if ((ptr = inst->_My_Type->_Dtool_UpcastInterface(value, &Dtool_PointerToArray_LVecBase3i))) {
} else if ((ptr = DtoolInstance_UPCAST(value, Dtool_PointerToArray_LVecBase3i))) {
_this->_type = ShaderInput::M_numeric;
_this->_stored_ptr = *(const PTA_LVecBase3i *)ptr;
} else if ((ptr = inst->_My_Type->_Dtool_UpcastInterface(value, &Dtool_PointerToArray_LVecBase2i))) {
} else if ((ptr = DtoolInstance_UPCAST(value, Dtool_PointerToArray_LVecBase2i))) {
_this->_type = ShaderInput::M_numeric;
_this->_stored_ptr = *(const PTA_LVecBase2i *)ptr;
@ -173,81 +172,81 @@ __init__(CPT_InternalName name, PyObject *value, int priority) {
return;
}
} else if ((ptr = inst->_My_Type->_Dtool_UpcastInterface(value, &Dtool_LMatrix4f))) {
} else if ((ptr = DtoolInstance_UPCAST(value, Dtool_LMatrix4f))) {
_this->_type = ShaderInput::M_numeric;
_this->_stored_ptr = *(const LMatrix4f *)ptr;
} else if ((ptr = inst->_My_Type->_Dtool_UpcastInterface(value, &Dtool_LMatrix3f))) {
} else if ((ptr = DtoolInstance_UPCAST(value, Dtool_LMatrix3f))) {
_this->_type = ShaderInput::M_numeric;
_this->_stored_ptr = *(const LMatrix3f *)ptr;
} else if ((ptr = inst->_My_Type->_Dtool_UpcastInterface(value, &Dtool_LMatrix4d))) {
} else if ((ptr = DtoolInstance_UPCAST(value, Dtool_LMatrix4d))) {
_this->_type = ShaderInput::M_numeric;
_this->_stored_ptr = *(const LMatrix4d *)ptr;
} else if ((ptr = inst->_My_Type->_Dtool_UpcastInterface(value, &Dtool_LMatrix3d))) {
} else if ((ptr = DtoolInstance_UPCAST(value, Dtool_LMatrix3d))) {
_this->_type = ShaderInput::M_numeric;
_this->_stored_ptr = *(const LMatrix3d *)ptr;
} else if ((ptr = inst->_My_Type->_Dtool_UpcastInterface(value, &Dtool_LVecBase4f))) {
} else if ((ptr = DtoolInstance_UPCAST(value, Dtool_LVecBase4f))) {
const LVecBase4f &vec = *(const LVecBase4f *)ptr;
_this->_type = ShaderInput::M_vector;
_this->_stored_ptr = vec;
_this->_stored_vector = LCAST(PN_stdfloat, vec);
} else if ((ptr = inst->_My_Type->_Dtool_UpcastInterface(value, &Dtool_LVecBase3f))) {
} else if ((ptr = DtoolInstance_UPCAST(value, Dtool_LVecBase3f))) {
const LVecBase3f &vec = *(const LVecBase3f *)ptr;
_this->_type = ShaderInput::M_vector;
_this->_stored_ptr = vec;
_this->_stored_vector.set(vec[0], vec[1], vec[2], 0);
} else if ((ptr = inst->_My_Type->_Dtool_UpcastInterface(value, &Dtool_LVecBase2f))) {
} else if ((ptr = DtoolInstance_UPCAST(value, Dtool_LVecBase2f))) {
const LVecBase2f &vec = *(const LVecBase2f *)ptr;
_this->_type = ShaderInput::M_vector;
_this->_stored_ptr = vec;
_this->_stored_vector.set(vec[0], vec[1], 0, 0);
} else if ((ptr = inst->_My_Type->_Dtool_UpcastInterface(value, &Dtool_LVecBase4d))) {
} else if ((ptr = DtoolInstance_UPCAST(value, Dtool_LVecBase4d))) {
const LVecBase4d &vec = *(const LVecBase4d *)ptr;
_this->_type = ShaderInput::M_vector;
_this->_stored_ptr = vec;
_this->_stored_vector = LCAST(PN_stdfloat, vec);
} else if ((ptr = inst->_My_Type->_Dtool_UpcastInterface(value, &Dtool_LVecBase3d))) {
} else if ((ptr = DtoolInstance_UPCAST(value, Dtool_LVecBase3d))) {
const LVecBase3d &vec = *(const LVecBase3d *)ptr;
_this->_type = ShaderInput::M_vector;
_this->_stored_ptr = vec;
_this->_stored_vector.set(vec[0], vec[1], vec[2], 0);
} else if ((ptr = inst->_My_Type->_Dtool_UpcastInterface(value, &Dtool_LVecBase2d))) {
} else if ((ptr = DtoolInstance_UPCAST(value, Dtool_LVecBase2d))) {
const LVecBase2d &vec = *(const LVecBase2d *)ptr;
_this->_type = ShaderInput::M_vector;
_this->_stored_ptr = vec;
_this->_stored_vector.set(vec[0], vec[1], 0, 0);
} else if ((ptr = inst->_My_Type->_Dtool_UpcastInterface(value, &Dtool_LVecBase4i))) {
} else if ((ptr = DtoolInstance_UPCAST(value, Dtool_LVecBase4i))) {
const LVecBase4i &vec = *(const LVecBase4i *)ptr;
_this->_type = ShaderInput::M_numeric;
_this->_stored_ptr = vec;
_this->_stored_vector = LCAST(PN_stdfloat, vec);
} else if ((ptr = inst->_My_Type->_Dtool_UpcastInterface(value, &Dtool_LVecBase3i))) {
} else if ((ptr = DtoolInstance_UPCAST(value, Dtool_LVecBase3i))) {
const LVecBase3i &vec = *(const LVecBase3i *)ptr;
_this->_type = ShaderInput::M_numeric;
_this->_stored_ptr = vec;
_this->_stored_vector.set(vec[0], vec[1], vec[2], 0);
} else if ((ptr = inst->_My_Type->_Dtool_UpcastInterface(value, &Dtool_LVecBase2i))) {
} else if ((ptr = DtoolInstance_UPCAST(value, Dtool_LVecBase2i))) {
const LVecBase2i &vec = *(const LVecBase2i *)ptr;
_this->_type = ShaderInput::M_numeric;
_this->_stored_ptr = vec;
_this->_stored_vector.set(vec[0], vec[1], 0, 0);
} else if ((ptr = inst->_My_Type->_Dtool_UpcastInterface(value, &Dtool_ShaderBuffer))) {
} else if ((ptr = DtoolInstance_UPCAST(value, Dtool_ShaderBuffer))) {
_this->_type = ShaderInput::M_buffer;
_this->_value = (ShaderBuffer *)ptr;
} else if ((ptr = inst->_My_Type->_Dtool_UpcastInterface(value, &Dtool_ParamValueBase))) {
} else if ((ptr = DtoolInstance_UPCAST(value, Dtool_ParamValueBase))) {
_this->_type = ShaderInput::M_param;
_this->_value = (ParamValueBase *)ptr;

View File

@ -15,6 +15,8 @@
#ifdef HAVE_PYTHON
#include "bamWriter.h"
#ifndef CPPPARSER
extern Dtool_PyTypedObject Dtool_BamWriter;
#endif // CPPPARSER
@ -65,7 +67,7 @@ __reduce_persist__(PyObject *self, PyObject *pickler) const {
// It's OK if there's no bamWriter.
PyErr_Clear();
} else {
DTOOL_Call_ExtractThisPointerForType(py_writer, &Dtool_BamWriter, (void **)&writer);
DtoolInstance_GetPointer(py_writer, writer, Dtool_BamWriter);
Py_DECREF(py_writer);
}
}