Various interrogate improvements

This commit is contained in:
rdb 2015-02-27 15:01:42 +01:00
parent 238cbad2a1
commit da3f642902
14 changed files with 1601 additions and 733 deletions

View File

@ -226,7 +226,8 @@ call_function(ostream &out, int indent_level, bool convert_result,
return_expr = get_call_str(container, pexprs); return_expr = get_call_str(container, pexprs);
} else { } else {
if (_return_type->return_value_should_be_simple()) { //if (_return_type->return_value_should_be_simple()) {
if (false) {
// We have to assign the result to a temporary first; this makes // We have to assign the result to a temporary first; this makes
// it a bit easier on poor old VC++. // it a bit easier on poor old VC++.
InterfaceMaker::indent(out, indent_level); InterfaceMaker::indent(out, indent_level);
@ -361,7 +362,7 @@ make_wrapper_entry(FunctionIndex function_index) {
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
// Function: FunctionRemap::get_call_str // Function: FunctionRemap::get_call_str
// Access: Private // Access: Public
// Description: Returns a string suitable for calling the wrapped // Description: Returns a string suitable for calling the wrapped
// function. If pexprs is nonempty, it represents // function. If pexprs is nonempty, it represents
// the list of expressions that will evaluate to each // the list of expressions that will evaluate to each
@ -417,7 +418,12 @@ get_call_str(const string &container, const vector_string &pexprs) const {
} else if (_has_this && !container.empty()) { } else if (_has_this && !container.empty()) {
// If we have a "this" parameter, the calling convention is also // If we have a "this" parameter, the calling convention is also
// a bit different. // a bit different.
call << "(" << container << ")->" << _cppfunc->get_local_name(); if (container == "local_this") {
// This isn't important, it just looks a bit prettier.
call << container << "->" << _cppfunc->get_local_name();
} else {
call << "(" << container << ")->" << _cppfunc->get_local_name();
}
} else { } else {
call << _cppfunc->get_local_name(&parser); call << _cppfunc->get_local_name(&parser);

View File

@ -61,6 +61,8 @@ public:
FunctionWrapperIndex make_wrapper_entry(FunctionIndex function_index); FunctionWrapperIndex make_wrapper_entry(FunctionIndex function_index);
string get_call_str(const string &container, const vector_string &pexprs) const;
class Parameter { class Parameter {
public: public:
bool _has_name; bool _has_name;
@ -131,8 +133,8 @@ public:
CPPFunctionType *_ftype; CPPFunctionType *_ftype;
bool _is_valid; bool _is_valid;
private: private:
string get_call_str(const string &container, const vector_string &pexprs) const;
string get_parameter_expr(int n, const vector_string &pexprs) const; string get_parameter_expr(int n, const vector_string &pexprs) const;
bool setup_properties(const InterrogateFunction &ifunc, InterfaceMaker *interface_maker); bool setup_properties(const InterrogateFunction &ifunc, InterfaceMaker *interface_maker);
}; };

File diff suppressed because it is too large Load Diff

View File

@ -112,10 +112,16 @@ private:
WrapperType _wrapper_type; WrapperType _wrapper_type;
int _min_version; int _min_version;
Function *_func; Function *_func;
string _wrapper_name;
set<FunctionRemap*> _remaps; set<FunctionRemap*> _remaps;
}; };
typedef std::map<string, SlottedFunctionDef> SlottedFunctions;
static bool get_slotted_function_def(Object *obj, Function *func, FunctionRemap *remap, SlottedFunctionDef &def); static bool get_slotted_function_def(Object *obj, Function *func, FunctionRemap *remap, SlottedFunctionDef &def);
static void write_function_slot(ostream &out, int indent_level,
const SlottedFunctions &slots,
const string &slot, const string &def = "0");
void write_prototype_for_name(ostream &out, Function *func, const std::string &name); void write_prototype_for_name(ostream &out, Function *func, const std::string &name);
void write_prototype_for(ostream &out, Function *func); void write_prototype_for(ostream &out, Function *func);
@ -138,7 +144,7 @@ private:
bool coercion_allowed, bool report_errors, bool coercion_allowed, bool report_errors,
ArgsType args_type, int return_flags, ArgsType args_type, int return_flags,
bool check_exceptions = true, bool check_exceptions = true,
bool verify_const = false, bool verify_const = true,
const string &first_expr = string()); const string &first_expr = string());
void write_function_instance(ostream &out, FunctionRemap *remap, void write_function_instance(ostream &out, FunctionRemap *remap,
@ -150,11 +156,14 @@ private:
const string &first_pexpr = string()); const string &first_pexpr = string());
void error_return(ostream &out, int indent_level, int return_flags); void error_return(ostream &out, int indent_level, int return_flags);
void error_raise_return(ostream &out, int indent_level, int return_flags,
const string &exc_type, const string &message,
const string &format_args = "");
void pack_return_value(ostream &out, int indent_level, FunctionRemap *remap, void pack_return_value(ostream &out, int indent_level, FunctionRemap *remap,
std::string return_expr); std::string return_expr);
void write_make_seq(ostream &out, Object *obj, const std::string &ClassName, void write_make_seq(ostream &out, Object *obj, const std::string &ClassName,
MakeSeq *make_seq); const std::string &cClassName, MakeSeq *make_seq);
void write_class_prototypes(ostream &out) ; void write_class_prototypes(ostream &out) ;
void write_class_declarations(ostream &out, ostream *out_h, Object *obj); void write_class_declarations(ostream &out, ostream *out_h, Object *obj);
@ -190,7 +199,8 @@ public:
int NeedsAReprFunction(const InterrogateType &itype_class); int NeedsAReprFunction(const InterrogateType &itype_class);
bool NeedsARichCompareFunction(const InterrogateType &itype_class); bool NeedsARichCompareFunction(const InterrogateType &itype_class);
void output_quoted(ostream &out, int indent_level, const std::string &str); void output_quoted(ostream &out, int indent_level, const std::string &str,
bool first_line=true);
// stash the forward declarations for this compile pass.. // stash the forward declarations for this compile pass..
std::set<CPPType *> _external_imports; std::set<CPPType *> _external_imports;

View File

@ -43,7 +43,14 @@ ParameterRemapConcreteToPointer(CPPType *orig_type) :
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
void ParameterRemapConcreteToPointer:: void ParameterRemapConcreteToPointer::
pass_parameter(ostream &out, const string &variable_name) { pass_parameter(ostream &out, const string &variable_name) {
out << "*" << variable_name; if (variable_name.size() > 1 && variable_name[0] == '&') {
// Prevent generating something like *&param
// Also, if this is really some local type, we can presumably
// just move it?
out << "MOVE(" << variable_name.substr(1) << ")";
} else {
out << "*" << variable_name;
}
} }
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////

View File

@ -42,7 +42,16 @@ ParameterRemapReferenceToPointer(CPPType *orig_type) :
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
void ParameterRemapReferenceToPointer:: void ParameterRemapReferenceToPointer::
pass_parameter(ostream &out, const string &variable_name) { pass_parameter(ostream &out, const string &variable_name) {
out << "*" << variable_name; if (variable_name.size() > 1 && variable_name[0] == '&') {
// Prevent generating something like *&param
// Also, if this is really some local type, we can presumably just
// move it? This is only relevant if this parameter is an rvalue
// reference, but CPPParser can't know that, and it might have an overload
// that takes an rvalue reference. It shouldn't hurt either way.
out << "MOVE(" << variable_name.substr(1) << ")";
} else {
out << "*" << variable_name;
}
} }
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////

View File

@ -1115,7 +1115,7 @@ is_unsigned_integer(CPPType *type) {
// Function: TypeManager::is_size // Function: TypeManager::is_size
// Access: Public, Static // Access: Public, Static
// Description: Returns true if the indicated type is the "size_t" // Description: Returns true if the indicated type is the "size_t"
// type. // type, or a const size_t, or a typedef to either.
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
bool TypeManager:: bool TypeManager::
is_size(CPPType *type) { is_size(CPPType *type) {
@ -1124,8 +1124,38 @@ is_size(CPPType *type) {
return is_size(type->as_const_type()->_wrapped_around); return is_size(type->as_const_type()->_wrapped_around);
case CPPDeclaration::ST_typedef: case CPPDeclaration::ST_typedef:
return is_integer(type->as_typedef_type()->_type) && if (type->get_simple_name() == "size_t") {
type->get_simple_name() == "size_t"; return is_integer(type->as_typedef_type()->_type);
} else {
return is_size(type->as_typedef_type()->_type);
}
default:
break;
}
return false;
}
////////////////////////////////////////////////////////////////////
// Function: TypeManager::is_ssize
// Access: Public, Static
// Description: Returns true if the indicated type is the "ssize_t"
// type, or a const ssize_t, or a typedef to either.
////////////////////////////////////////////////////////////////////
bool TypeManager::
is_ssize(CPPType *type) {
switch (type->get_subtype()) {
case CPPDeclaration::ST_const:
return is_ssize(type->as_const_type()->_wrapped_around);
case CPPDeclaration::ST_typedef:
if (type->get_simple_name() == "Py_ssize_t" ||
type->get_simple_name() == "ssize_t") {
return is_integer(type->as_typedef_type()->_type);
} else {
return is_ssize(type->as_typedef_type()->_type);
}
default: default:
break; break;

View File

@ -88,6 +88,7 @@ public:
static bool is_integer(CPPType *type); static bool is_integer(CPPType *type);
static bool is_unsigned_integer(CPPType *type); static bool is_unsigned_integer(CPPType *type);
static bool is_size(CPPType *type); static bool is_size(CPPType *type);
static bool is_ssize(CPPType *type);
static bool is_short(CPPType *type); static bool is_short(CPPType *type);
static bool is_unsigned_short(CPPType *type); static bool is_unsigned_short(CPPType *type);
static bool is_longlong(CPPType *type); static bool is_longlong(CPPType *type);

View File

@ -15,7 +15,7 @@
#include "py_panda.h" #include "py_panda.h"
#ifdef HAVE_PYTHON #ifdef HAVE_PYTHON
class EmptyClass { class EmptyClass {
}; };
Define_Module_Class_Private(dtoolconfig, DTOOL_SUPER_BASE, EmptyClass, DTOOL_SUPER_BASE111); Define_Module_Class_Private(dtoolconfig, DTOOL_SUPER_BASE, EmptyClass, DTOOL_SUPER_BASE111);
@ -30,7 +30,7 @@ PyMethodDef Dtool_Methods_DTOOL_SUPER_BASE[] = {
{ NULL, NULL } { NULL, NULL }
}; };
static Py_hash_t DTool_HashKey_Methods_DTOOL_SUPER_BASE(PyObject *self) { static Py_hash_t Dtool_HashKey_DTOOL_SUPER_BASE(PyObject *self) {
void *local_this = DTOOL_Call_GetPointerThis(self); void *local_this = DTOOL_Call_GetPointerThis(self);
if (local_this == NULL) { if (local_this == NULL) {
return -1; return -1;
@ -46,15 +46,6 @@ EXPCL_DTOOLCONFIG void Dtool_PyModuleClassInit_DTOOL_SUPER_BASE(PyObject *module
Dtool_DTOOL_SUPER_BASE.As_PyTypeObject().tp_dict = PyDict_New(); Dtool_DTOOL_SUPER_BASE.As_PyTypeObject().tp_dict = PyDict_New();
PyDict_SetItemString(Dtool_DTOOL_SUPER_BASE.As_PyTypeObject().tp_dict, "DtoolClassDict", Dtool_DTOOL_SUPER_BASE.As_PyTypeObject().tp_dict); PyDict_SetItemString(Dtool_DTOOL_SUPER_BASE.As_PyTypeObject().tp_dict, "DtoolClassDict", Dtool_DTOOL_SUPER_BASE.As_PyTypeObject().tp_dict);
// __hash__
Dtool_DTOOL_SUPER_BASE.As_PyTypeObject().tp_hash = &DTool_HashKey_Methods_DTOOL_SUPER_BASE;
#if PY_MAJOR_VERSION >= 3
// Python 3 removed the regular tp_compare function - there is only tp_richcompare.
Dtool_DTOOL_SUPER_BASE.As_PyTypeObject().tp_richcompare = &DTOOL_PyObject_RichCompare;
#else
Dtool_DTOOL_SUPER_BASE.As_PyTypeObject().tp_compare = &DTOOL_PyObject_Compare;
#endif
if (PyType_Ready(&Dtool_DTOOL_SUPER_BASE.As_PyTypeObject()) < 0) { if (PyType_Ready(&Dtool_DTOOL_SUPER_BASE.As_PyTypeObject()) < 0) {
PyErr_SetString(PyExc_TypeError, "PyType_Ready(Dtool_DTOOL_SUPER_BASE)"); PyErr_SetString(PyExc_TypeError, "PyType_Ready(Dtool_DTOOL_SUPER_BASE)");
return; return;
@ -83,4 +74,66 @@ int Dtool_Init_DTOOL_SUPER_BASE(PyObject *self, PyObject *args, PyObject *kwds)
return -1; return -1;
} }
EXPORT_THIS Dtool_PyTypedObject Dtool_DTOOL_SUPER_BASE = {
{
PyVarObject_HEAD_INIT(NULL, 0)
"dtoolconfig.DTOOL_SUPER_BASE",
sizeof(Dtool_PyInstDef),
0,
&Dtool_FreeInstance_DTOOL_SUPER_BASE,
0,
0,
0,
#if PY_MAJOR_VERSION >= 3
0,
#else
&DTOOL_PyObject_Compare,
#endif
0,
0,
0,
0,
&Dtool_HashKey_DTOOL_SUPER_BASE,
0,
0,
PyObject_GenericGetAttr,
PyObject_GenericSetAttr,
0,
(Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_CHECKTYPES),
0,
0,
0,
#if PY_MAJOR_VERSION >= 3
&DTOOL_PyObject_RichCompare,
#else
0,
#endif
0,
0,
0,
Dtool_Methods_DTOOL_SUPER_BASE,
standard_type_members,
0,
0,
0,
0,
0,
0,
Dtool_Init_DTOOL_SUPER_BASE,
PyType_GenericAlloc,
Dtool_new_DTOOL_SUPER_BASE,
PyObject_Del,
0,
0,
0,
0,
0,
0,
0,
},
Dtool_UpcastInterface_DTOOL_SUPER_BASE,
Dtool_DowncastInterface_DTOOL_SUPER_BASE,
TypeHandle::none(),
};
#endif // HAVE_PYTHON #endif // HAVE_PYTHON

View File

@ -70,13 +70,13 @@ void DTOOL_Call_ExtractThisPointerForType(PyObject *self, Dtool_PyTypedObject *c
// wrong type, raises an AttributeError. // wrong type, raises an AttributeError.
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
bool Dtool_Call_ExtractThisPointer(PyObject *self, Dtool_PyTypedObject &classdef, void **answer) { bool Dtool_Call_ExtractThisPointer(PyObject *self, Dtool_PyTypedObject &classdef, void **answer) {
if (self != NULL && DtoolCanThisBeAPandaInstance(self)) { if (self == NULL || !DtoolCanThisBeAPandaInstance(self)) {
*answer = ((Dtool_PyInstDef *)self)->_My_Type->_Dtool_UpcastInterface(self, &classdef); Dtool_Raise_TypeError("C++ object is not yet constructed, or already destructed.");
return true; return false;
} }
PyErr_SetString(PyExc_AttributeError, "C++ object is not yet constructed, or already destructed."); *answer = ((Dtool_PyInstDef *)self)->_My_Type->_Dtool_UpcastInterface(self, &classdef);
return false; return true;
} }
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
@ -93,9 +93,9 @@ bool Dtool_Call_ExtractThisPointer(PyObject *self, Dtool_PyTypedObject &classdef
bool Dtool_Call_ExtractThisPointer_NonConst(PyObject *self, Dtool_PyTypedObject &classdef, bool Dtool_Call_ExtractThisPointer_NonConst(PyObject *self, Dtool_PyTypedObject &classdef,
void **answer, const char *method_name) { void **answer, const char *method_name) {
if (self != NULL && DtoolCanThisBeAPandaInstance(self)) { if (self == NULL || !DtoolCanThisBeAPandaInstance(self)) {
*answer = ((Dtool_PyInstDef *)self)->_My_Type->_Dtool_UpcastInterface(self, &classdef); Dtool_Raise_TypeError("C++ object is not yet constructed, or already destructed.");
return true; return false;
} }
if (((Dtool_PyInstDef *)self)->_is_const) { if (((Dtool_PyInstDef *)self)->_is_const) {
@ -106,6 +106,7 @@ bool Dtool_Call_ExtractThisPointer_NonConst(PyObject *self, Dtool_PyTypedObject
return false; return false;
} }
*answer = ((Dtool_PyInstDef *)self)->_My_Type->_Dtool_UpcastInterface(self, &classdef);
return true; return true;
} }
@ -145,7 +146,7 @@ DTOOL_Call_GetPointerThisClass(PyObject *self, Dtool_PyTypedObject *classdef,
//} //}
if (self == NULL) { if (self == NULL) {
if (report_errors) { if (report_errors) {
PyErr_SetString(PyExc_TypeError, "self is NULL"); return Dtool_Raise_TypeError("self is NULL");
} }
return NULL; return NULL;
} }
@ -159,18 +160,16 @@ DTOOL_Call_GetPointerThisClass(PyObject *self, Dtool_PyTypedObject *classdef,
} }
if (report_errors) { if (report_errors) {
PyErr_Format(PyExc_TypeError, return PyErr_Format(PyExc_TypeError,
"%s() argument %d may not be const", "%s() argument %d may not be const",
function_name.c_str(), param); function_name.c_str(), param);
} }
return NULL; return NULL;
} }
} }
if (report_errors) { if (report_errors) {
Dtool_Raise_ArgTypeError(self, param, function_name.c_str(), classdef->_PyType.tp_name); return Dtool_Raise_ArgTypeError(self, param, function_name.c_str(), classdef->_PyType.tp_name);
return NULL;
} }
return NULL; return NULL;
@ -183,7 +182,6 @@ void *DTOOL_Call_GetPointerThis(PyObject *self) {
return pyself->_ptr_to_object; return pyself->_ptr_to_object;
} }
} }
return NULL; return NULL;
} }
@ -206,27 +204,130 @@ bool Dtool_CheckErrorOccurred() {
if (_PyErr_OCCURRED()) { if (_PyErr_OCCURRED()) {
return true; return true;
} }
Notify *notify = Notify::ptr(); if (Notify::ptr()->has_assert_failed()) {
if (notify->has_assert_failed()) { Dtool_Raise_AssertionError();
PyErr_SetString(PyExc_AssertionError, notify->get_assert_error_message().c_str());
notify->clear_assert_failed();
return true; return true;
} }
return false; return false;
} }
#endif // NDEBUG #endif // NDEBUG
////////////////////////////////////////////////////////////////////
// Function: Dtool_Raise_AssertionError
// Description: Raises an AssertionError containing the last thrown
// assert message, and clears the assertion flag.
// Returns NULL.
////////////////////////////////////////////////////////////////////
PyObject *Dtool_Raise_AssertionError() {
Notify *notify = Notify::ptr();
#if PY_MAJOR_VERSION >= 3
PyObject *message = PyUnicode_FromString(notify->get_assert_error_message().c_str());
#else
PyObject *message = PyString_FromString(notify->get_assert_error_message().c_str());
#endif
Py_INCREF(PyExc_AssertionError);
PyErr_Restore(PyExc_AssertionError, message, (PyObject *)NULL);
notify->clear_assert_failed();
return NULL;
}
////////////////////////////////////////////////////////////////////
// Function: Dtool_Raise_TypeError
// Description: Raises a TypeError with the given message, and
// returns NULL.
////////////////////////////////////////////////////////////////////
PyObject *Dtool_Raise_TypeError(const char *message) {
// PyErr_Restore is what PyErr_SetString would have ended up calling
// eventually anyway, so we might as well just get to the point.
Py_INCREF(PyExc_TypeError);
#if PY_MAJOR_VERSION >= 3
PyErr_Restore(PyExc_TypeError, PyUnicode_FromString(message), (PyObject *)NULL);
#else
PyErr_Restore(PyExc_TypeError, PyString_FromString(message), (PyObject *)NULL);
#endif
return NULL;
}
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
// Function: Dtool_Raise_ArgTypeError // Function: Dtool_Raise_ArgTypeError
// Description: Raises a TypeError of the form: // Description: Raises a TypeError of the form:
// function_name() argument n must be type, not type // function_name() argument n must be type, not type
// for a given object passed to a function. // for a given object passed to a function.
//
// Always returns NULL so that it can be conveniently
// used as a return expression for wrapper functions
// that return a PyObject pointer.
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
void Dtool_Raise_ArgTypeError(PyObject *obj, int param, const char *function_name, const char *type_name) { PyObject *Dtool_Raise_ArgTypeError(PyObject *obj, int param, const char *function_name, const char *type_name) {
PyErr_Format(PyExc_TypeError, #if PY_MAJOR_VERSION >= 3
"%s() argument %d must be %s, not %s", PyObject *message = PyUnicode_FromFormat(
function_name, param, type_name, #else
Py_TYPE(obj)->tp_name); PyObject *message = PyString_FromFormat(
#endif
"%s() argument %d must be %s, not %s",
function_name, param, type_name,
Py_TYPE(obj)->tp_name);
Py_INCREF(PyExc_TypeError);
PyErr_Restore(PyExc_TypeError, message, (PyObject *)NULL);
return NULL;
}
////////////////////////////////////////////////////////////////////
// Function: Dtool_Raise_BadArgumentsError
// Description: Raises a TypeError of the form:
// Arguments must match:
// <list of overloads>
//
// However, in release builds, this instead is defined
// to a function that just prints out a generic
// message, to help reduce the amount of strings in
// the compiled library.
//
// Always returns NULL so that it can be conveniently
// used as a return expression for wrapper functions
// that return a PyObject pointer.
////////////////////////////////////////////////////////////////////
PyObject *_Dtool_Raise_BadArgumentsError() {
return Dtool_Raise_TypeError("arguments do not match any function overload");
}
////////////////////////////////////////////////////////////////////
// Function: Dtool_Return_None
// Description: Convenience method that checks for exceptions, and
// if one occurred, returns NULL, otherwise Py_None.
////////////////////////////////////////////////////////////////////
PyObject *_Dtool_Return_None() {
if (_PyErr_OCCURRED()) {
return NULL;
}
#ifndef NDEBUG
if (Notify::ptr()->has_assert_failed()) {
return Dtool_Raise_AssertionError();
}
#endif
Py_INCREF(Py_None);
return Py_None;
}
////////////////////////////////////////////////////////////////////
// Function: Dtool_Return_Bool
// Description: Convenience method that checks for exceptions, and
// if one occurred, returns NULL, otherwise the given
// boolean value as a PyObject *.
////////////////////////////////////////////////////////////////////
PyObject *Dtool_Return_Bool(bool value) {
if (_PyErr_OCCURRED()) {
return NULL;
}
#ifndef NDEBUG
if (Notify::ptr()->has_assert_failed()) {
return Dtool_Raise_AssertionError();
}
#endif
PyObject *result = (value ? Py_True : Py_False);
Py_INCREF(result);
return result;
} }
//////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////
@ -236,11 +337,11 @@ void Dtool_Raise_ArgTypeError(PyObject *obj, int param, const char *function_nam
// //
//////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////
PyObject *DTool_CreatePyInstanceTyped(void *local_this_in, Dtool_PyTypedObject &known_class_type, bool memory_rules, bool is_const, int type_index) { PyObject *DTool_CreatePyInstanceTyped(void *local_this_in, Dtool_PyTypedObject &known_class_type, bool memory_rules, bool is_const, int type_index) {
if (local_this_in == NULL) { // We can't do the NULL check here like in DTool_CreatePyInstance, since
// Let's not be stupid.. // the caller will have to get the type index to pass to this function
PyErr_SetString(PyExc_TypeError, "C Function Return Null 'this'"); // to begin with. That code probably would have crashed by now if it was
return NULL; // really NULL for whatever reason.
} nassertr(local_this_in != NULL, NULL);
///////////////////////////////////////////////////// /////////////////////////////////////////////////////
// IF the class is possibly a run time typed object // IF the class is possibly a run time typed object
@ -293,8 +394,10 @@ PyObject *DTool_CreatePyInstanceTyped(void *local_this_in, Dtool_PyTypedObject &
//////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////
PyObject *DTool_CreatePyInstance(void *local_this, Dtool_PyTypedObject &in_classdef, bool memory_rules, bool is_const) { PyObject *DTool_CreatePyInstance(void *local_this, Dtool_PyTypedObject &in_classdef, bool memory_rules, bool is_const) {
if (local_this == NULL) { if (local_this == NULL) {
PyErr_SetString(PyExc_TypeError, "C Function Return Null 'this'"); // This is actually a very common case, so let's allow this, but return
return NULL; // Py_None consistently. This eliminates code in the wrappers.
Py_INCREF(Py_None);
return Py_None;
} }
Dtool_PyTypedObject *classdef = &in_classdef; Dtool_PyTypedObject *classdef = &in_classdef;
@ -417,11 +520,10 @@ PyObject *Dtool_PyModuleInitHelper(LibraryDef *defs[], const char *modulename) {
if (module == NULL) { if (module == NULL) {
#if PY_MAJOR_VERSION >= 3 #if PY_MAJOR_VERSION >= 3
PyErr_SetString(PyExc_TypeError, "PyModule_Create returned NULL"); return Dtool_Raise_TypeError("PyModule_Create returned NULL");
#else #else
PyErr_SetString(PyExc_TypeError, "Py_InitModule returned NULL"); return Dtool_Raise_TypeError("Py_InitModule returned NULL");
#endif #endif
return NULL;
} }
// the constant inits... enums, classes ... // the constant inits... enums, classes ...
@ -430,7 +532,6 @@ PyObject *Dtool_PyModuleInitHelper(LibraryDef *defs[], const char *modulename) {
} }
PyModule_AddIntConstant(module, "Dtool_PyNativeInterface", 1); PyModule_AddIntConstant(module, "Dtool_PyNativeInterface", 1);
return module; return module;
} }
@ -461,10 +562,10 @@ PyObject *Dtool_BorrowThisReference(PyObject *self, PyObject *args) {
return Py_None; return Py_None;
} }
PyErr_Format(PyExc_TypeError, "types %s and %s do not match", return PyErr_Format(PyExc_TypeError, "types %s and %s do not match",
Py_TYPE(from)->tp_name, Py_TYPE(to)->tp_name); Py_TYPE(from)->tp_name, Py_TYPE(to)->tp_name);
} else { } else {
PyErr_SetString(PyExc_TypeError, "One of these does not appear to be DTOOL Instance ??"); return Dtool_Raise_TypeError("One of these does not appear to be DTOOL Instance ??");
} }
} }
return (PyObject *) NULL; return (PyObject *) NULL;
@ -479,16 +580,17 @@ PyObject *Dtool_AddToDictionary(PyObject *self1, PyObject *args) {
PyObject *key; PyObject *key;
if (PyArg_ParseTuple(args, "OSO", &self, &key, &subject)) { if (PyArg_ParseTuple(args, "OSO", &self, &key, &subject)) {
PyObject *dict = ((PyTypeObject *)self)->tp_dict; PyObject *dict = ((PyTypeObject *)self)->tp_dict;
if (dict == NULL && !PyDict_Check(dict)) { if (dict == NULL || !PyDict_Check(dict)) {
PyErr_SetString(PyExc_TypeError, "No dictionary On Object"); return Dtool_Raise_TypeError("No dictionary On Object");
} else { } else {
PyDict_SetItem(dict,key,subject); PyDict_SetItem(dict, key, subject);
} }
} }
if (PyErr_Occurred()) { if (PyErr_Occurred()) {
return (PyObject *)NULL; return (PyObject *)NULL;
} }
return Py_BuildValue(""); Py_INCREF(Py_None);
return Py_None;
} }
/////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////
@ -653,7 +755,7 @@ PyObject *make_list_for_item(PyObject *self, const char *num_name,
Py_DECREF(list); Py_DECREF(list);
return NULL; return NULL;
} }
PyList_SetItem(list, i, element); PyList_SET_ITEM(list, i, element);
} }
return list; return list;
} }

View File

@ -115,7 +115,7 @@ inline PyObject* doPy_RETURN_FALSE()
#define PyLongOrInt_FromLong PyLong_FromLong #define PyLongOrInt_FromLong PyLong_FromLong
#define PyLongOrInt_FromUnsignedLong PyLong_FromUnsignedLong #define PyLongOrInt_FromUnsignedLong PyLong_FromUnsignedLong
#define PyInt_Check PyLong_Check #define PyInt_Check PyLong_Check
#define PyInt_AsLong PyLong_Aslong #define PyInt_AsLong PyLong_AsLong
#define PyInt_AS_LONG PyLong_AS_LONG #define PyInt_AS_LONG PyLong_AS_LONG
#else #else
#define PyLongOrInt_Check(x) (PyInt_Check(x) || PyLong_Check(x)) #define PyLongOrInt_Check(x) (PyInt_Check(x) || PyLong_Check(x))
@ -165,14 +165,14 @@ typedef void *(*DowncastFunction)(void *, Dtool_PyTypedObject *);
struct Dtool_PyInstDef { struct Dtool_PyInstDef {
PyObject_HEAD PyObject_HEAD
// Pointer to the underlying C++ object.
void *_ptr_to_object;
// This is a pointer to the Dtool_PyTypedObject type. It's tempting // This is a pointer to the Dtool_PyTypedObject type. It's tempting
// not to store this and to instead use PY_TYPE(self) and upcast that, // not to store this and to instead use PY_TYPE(self) and upcast that,
// but that breaks when someone inherits from our class in Python. // but that breaks when someone inherits from our class in Python.
struct Dtool_PyTypedObject *_My_Type; struct Dtool_PyTypedObject *_My_Type;
// Pointer to the underlying C++ object.
void *_ptr_to_object;
// This is always set to PY_PANDA_SIGNATURE, so that we can quickly // This is always set to PY_PANDA_SIGNATURE, so that we can quickly
// detect whether an object is a Panda object. // detect whether an object is a Panda object.
unsigned short _signature; unsigned short _signature;
@ -208,64 +208,10 @@ struct Dtool_PyTypedObject {
inline PyObject &As_PyObject() { return (PyObject &)_PyType; }; inline PyObject &As_PyObject() { return (PyObject &)_PyType; };
}; };
//////////////////////////////////////////////////////////////////////// // This is now simply a forward declaration. The actual definition is created
// Macros from Hell.. May want to just add this to the code generator.. // by the code generator.
//////////////////////////////////////////////////////////////////////// #define Define_Dtool_Class(MODULE_NAME, CLASS_NAME, PUBLIC_NAME) \
#define Define_Dtool_PyTypedObject(MODULE_NAME, CLASS_NAME, PUBLIC_NAME) \ extern Dtool_PyTypedObject Dtool_##CLASS_NAME;
EXPORT_THIS Dtool_PyTypedObject Dtool_##CLASS_NAME = \
{ \
{ \
PyVarObject_HEAD_INIT(NULL, 0) \
#MODULE_NAME "." #PUBLIC_NAME, /*type name with module */ \
sizeof(Dtool_PyInstDef), /* tp_basicsize */ \
0, /* tp_itemsize */ \
&Dtool_FreeInstance_##CLASS_NAME, /* tp_dealloc */ \
0, /* tp_print */ \
0, /* tp_getattr */ \
0, /* tp_setattr */ \
0, /* tp_compare */ \
0, /* tp_repr */ \
&Dtool_PyNumberMethods_##CLASS_NAME, /* tp_as_number */ \
&Dtool_PySequenceMethods_##CLASS_NAME, /* tp_as_sequence */ \
&Dtool_PyMappingMethods_##CLASS_NAME, /* tp_as_mapping */ \
0, /* tp_hash */ \
0, /* tp_call */ \
0, /* tp_str */ \
PyObject_GenericGetAttr, /* tp_getattro */ \
PyObject_GenericSetAttr, /* tp_setattro */ \
&Dtool_PyBufferProcs_##CLASS_NAME, /* tp_as_buffer */ \
(Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_CHECKTYPES), /* tp_flags */ \
0, /* tp_doc */ \
0, /* tp_traverse */ \
0, /* tp_clear */ \
0, /* tp_richcompare */ \
0, /* tp_weaklistoffset */ \
0, /* tp_iter */ \
0, /* tp_iternext */ \
Dtool_Methods_##CLASS_NAME, /* tp_methods */ \
standard_type_members, /* tp_members */ \
0, /* tp_getset */ \
0, /* tp_base */ \
0, /* tp_dict */ \
0, /* tp_descr_get */ \
0, /* tp_descr_set */ \
0, /* tp_dictoffset */ \
Dtool_Init_##CLASS_NAME, /* tp_init */ \
PyType_GenericAlloc, /* tp_alloc */ \
Dtool_new_##CLASS_NAME, /* tp_new */ \
PyObject_Del, /* tp_free */ \
}, \
Dtool_UpcastInterface_##CLASS_NAME, \
Dtool_DowncastInterface_##CLASS_NAME, \
TypeHandle::none(), \
};
#define Define_Dtool_Class(MODULE_NAME, CLASS_NAME, PUBLIC_NAME) \
static PyNumberMethods Dtool_PyNumberMethods_##CLASS_NAME = {0}; \
static PySequenceMethods Dtool_PySequenceMethods_##CLASS_NAME = {0}; \
static PyMappingMethods Dtool_PyMappingMethods_##CLASS_NAME = {0}; \
static PyBufferProcs Dtool_PyBufferProcs_##CLASS_NAME = {0}; \
Define_Dtool_PyTypedObject(MODULE_NAME, CLASS_NAME, PUBLIC_NAME)
//////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////
// More Macro(s) to Implement class functions.. Usually used if C++ needs type information // More Macro(s) to Implement class functions.. Usually used if C++ needs type information
@ -326,6 +272,12 @@ static void Dtool_FreeInstance_##CLASS_NAME(PyObject *self) {\
Py_TYPE(self)->tp_free(self);\ Py_TYPE(self)->tp_free(self);\
} }
#define Define_Dtool_Simple_FreeInstance(CLASS_NAME, CNAME)\
static void Dtool_FreeInstance_##CLASS_NAME(PyObject *self) {\
((Dtool_InstDef_##CLASS_NAME *)self)->_value.~##CLASS_NAME();\
Py_TYPE(self)->tp_free(self);\
}
//////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////
/// Simple Recognition Functions.. /// Simple Recognition Functions..
//////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////
@ -385,7 +337,27 @@ template<class T> INLINE bool DTOOL_Call_ExtractThisPointer(PyObject *self, T *&
EXPCL_DTOOLCONFIG bool Dtool_CheckErrorOccurred(); EXPCL_DTOOLCONFIG bool Dtool_CheckErrorOccurred();
#endif #endif
EXPCL_DTOOLCONFIG void Dtool_Raise_ArgTypeError(PyObject *obj, int param, const char *function_name, const char *type_name); EXPCL_DTOOLCONFIG PyObject *Dtool_Raise_AssertionError();
EXPCL_DTOOLCONFIG PyObject *Dtool_Raise_TypeError(const char *message);
EXPCL_DTOOLCONFIG PyObject *Dtool_Raise_ArgTypeError(PyObject *obj, int param, const char *function_name, const char *type_name);
EXPCL_DTOOLCONFIG PyObject *_Dtool_Raise_BadArgumentsError();
#ifdef NDEBUG
// Define it to a function that just prints a generic message.
#define Dtool_Raise_BadArgumentsError(x) _Dtool_Raise_BadArgumentsError()
#else
// Expand this to a TypeError listing all of the overloads.
#define Dtool_Raise_BadArgumentsError(x) Dtool_Raise_TypeError("Arguments must match:\n" x)
#endif
EXPCL_DTOOLCONFIG PyObject *_Dtool_Return_None();
EXPCL_DTOOLCONFIG PyObject *Dtool_Return_Bool(bool value);
#ifdef NDEBUG
#define Dtool_Return_None() (_PyErr_OCCURRED() != NULL ? NULL : (Py_INCREF(Py_None), Py_None))
#else
#define Dtool_Return_None() _Dtool_Return_None()
#endif
//////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////
// Function : DTool_CreatePyInstanceTyped // Function : DTool_CreatePyInstanceTyped
@ -436,7 +408,6 @@ template<class T> INLINE PyObject *DTool_CreatePyInstanceTyped(T *obj, bool memo
#define Define_Module_Class_Internal(MODULE_NAME,CLASS_NAME,CNAME)\ #define Define_Module_Class_Internal(MODULE_NAME,CLASS_NAME,CNAME)\
extern EXPORT_THIS Dtool_PyTypedObject Dtool_##CLASS_NAME;\ 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_Init_##CLASS_NAME(PyObject *self, PyObject *args, PyObject *kwds);\
PyObject * Dtool_new_##CLASS_NAME(PyTypeObject *type, PyObject *args, PyObject *kwds);\ PyObject * Dtool_new_##CLASS_NAME(PyTypeObject *type, PyObject *args, PyObject *kwds);\
void * Dtool_UpcastInterface_##CLASS_NAME(PyObject *self, Dtool_PyTypedObject *requested_type);\ void * Dtool_UpcastInterface_##CLASS_NAME(PyObject *self, Dtool_PyTypedObject *requested_type);\
@ -470,7 +441,6 @@ Define_Dtool_new(CLASS_NAME,CNAME)\
Define_Dtool_FreeInstanceRef(CLASS_NAME,CNAME)\ Define_Dtool_FreeInstanceRef(CLASS_NAME,CNAME)\
Define_Dtool_Class(MODULE_NAME,CLASS_NAME,PUBLIC_NAME) Define_Dtool_Class(MODULE_NAME,CLASS_NAME,PUBLIC_NAME)
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
/// Th Finalizer for simple instances.. /// Th Finalizer for simple instances..
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////

View File

@ -26,7 +26,7 @@ typedef long DWORD;
typedef long LONG; typedef long LONG;
typedef long UINT; typedef long UINT;
typedef unsigned long ULONG; typedef unsigned long ULONG;
typedef signed __int64 LONGLONG; typedef signed long long LONGLONG;
typedef long HRESULT; typedef long HRESULT;
typedef int CRITICAL_SECTION; typedef int CRITICAL_SECTION;
typedef int HANDLE; typedef int HANDLE;
@ -45,12 +45,12 @@ typedef struct _STICKYKEYS STICKYKEYS;
typedef struct _TOGGLEKEYS TOGGLEKEYS; typedef struct _TOGGLEKEYS TOGGLEKEYS;
typedef struct _FILTERKEYS FILTERKEYS; typedef struct _FILTERKEYS FILTERKEYS;
#define CALLBACK #define CALLBACK
#define WINAPI #define WINAPI
union LARGE_INTEGER { union LARGE_INTEGER {
__int64 QuadPart; long long QuadPart;
}; };
class IGraphBuilder; class IGraphBuilder;

View File

@ -2,16 +2,8 @@
#define _WINSOCK2API_ #define _WINSOCK2API_
#define _WINSOCKAPI_ /* Prevent inclusion of winsock.h in windows.h */ #define _WINSOCKAPI_ /* Prevent inclusion of winsock.h in windows.h */
typedef int SOCKET ; typedef int SOCKET;
struct sockaddr_in struct sockaddr_in;
{
};
typedef struct fd_set {
unsigned int fd_count; /* how many are SET? */
SOCKET fd_array[10]; /* an array of SOCKETs */
} fd_set;
#endif #endif

View File

@ -123,6 +123,7 @@ extern "C" {
EXPCL_PYSTUB int PySequence_Tuple(...); EXPCL_PYSTUB int PySequence_Tuple(...);
EXPCL_PYSTUB int PyString_AsString(...); EXPCL_PYSTUB int PyString_AsString(...);
EXPCL_PYSTUB int PyString_AsStringAndSize(...); EXPCL_PYSTUB int PyString_AsStringAndSize(...);
EXPCL_PYSTUB int PyString_FromFormat(...);
EXPCL_PYSTUB int PyString_FromString(...); EXPCL_PYSTUB int PyString_FromString(...);
EXPCL_PYSTUB int PyString_FromStringAndSize(...); EXPCL_PYSTUB int PyString_FromStringAndSize(...);
EXPCL_PYSTUB int PyString_InternFromString(...); EXPCL_PYSTUB int PyString_InternFromString(...);
@ -155,6 +156,7 @@ extern "C" {
EXPCL_PYSTUB int PyUnicode_AsUTF8AndSize(...); EXPCL_PYSTUB int PyUnicode_AsUTF8AndSize(...);
EXPCL_PYSTUB int PyUnicode_AsWideChar(...); EXPCL_PYSTUB int PyUnicode_AsWideChar(...);
EXPCL_PYSTUB int PyUnicode_AsWideCharString(...); EXPCL_PYSTUB int PyUnicode_AsWideCharString(...);
EXPCL_PYSTUB int PyUnicode_FromFormat(...);
EXPCL_PYSTUB int PyUnicode_FromString(...); EXPCL_PYSTUB int PyUnicode_FromString(...);
EXPCL_PYSTUB int PyUnicode_FromStringAndSize(...); EXPCL_PYSTUB int PyUnicode_FromStringAndSize(...);
EXPCL_PYSTUB int PyUnicode_FromWideChar(...); EXPCL_PYSTUB int PyUnicode_FromWideChar(...);
@ -311,6 +313,7 @@ int PySequence_Size(...) { return 0; }
int PySequence_Tuple(...) { return 0; } int PySequence_Tuple(...) { return 0; }
int PyString_AsString(...) { return 0; } int PyString_AsString(...) { return 0; }
int PyString_AsStringAndSize(...) { return 0; } int PyString_AsStringAndSize(...) { return 0; }
int PyString_FromFormat(...) { return 0; }
int PyString_FromString(...) { return 0; } int PyString_FromString(...) { return 0; }
int PyString_FromStringAndSize(...) { return 0; } int PyString_FromStringAndSize(...) { return 0; }
int PyString_InternFromString(...) { return 0; } int PyString_InternFromString(...) { return 0; }
@ -343,6 +346,7 @@ int PyUnicode_AsUTF8(...) { return 0; }
int PyUnicode_AsUTF8AndSize(...) { return 0; } int PyUnicode_AsUTF8AndSize(...) { return 0; }
int PyUnicode_AsWideChar(...) { return 0; } int PyUnicode_AsWideChar(...) { return 0; }
int PyUnicode_AsWideCharString(...) { return 0; } int PyUnicode_AsWideCharString(...) { return 0; }
int PyUnicode_FromFormat(...) { return 0; }
int PyUnicode_FromString(...) { return 0; } int PyUnicode_FromString(...) { return 0; }
int PyUnicode_FromStringAndSize(...) { return 0; } int PyUnicode_FromStringAndSize(...) { return 0; }
int PyUnicode_FromWideChar(...) { return 0; } int PyUnicode_FromWideChar(...) { return 0; }