Browse Source

Move Python support code from libp3interrogatedb to generated module

This prevents libp3interrogatedb from having a dependency on the Python library.

See #387
rdb 7 years ago
parent
commit
49b72fb198

+ 2 - 1
dtool/src/dtoolbase/typeHandle_ext.cxx

@@ -22,7 +22,8 @@
  */
 TypeHandle Extension<TypeHandle>::
 make(PyTypeObject *tp) {
-  if (!PyType_IsSubtype(tp, &Dtool_DTOOL_SUPER_BASE._PyType)) {
+  Dtool_PyTypedObject *super_base = Dtool_GetSuperBase();
+  if (!PyType_IsSubtype(tp, (PyTypeObject *)super_base)) {
     PyErr_SetString(PyExc_TypeError, "a Panda type is required");
     return TypeHandle::none();
   }

+ 1 - 1
dtool/src/interrogate/interfaceMakerPythonNative.cxx

@@ -3097,7 +3097,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_DTOOL_SUPER_BASE;\n";
+    out << "    Dtool_" << ClassName << "._PyType.tp_base = (PyTypeObject *)Dtool_GetSuperBase();\n";
   }
 
   int num_nested = obj->_itype.number_of_nested_types();

+ 6 - 1
dtool/src/interrogate/interrogate_module.cxx

@@ -30,6 +30,9 @@
 using std::cerr;
 using std::string;
 
+// This contains a big source string determined at compile time.
+extern const char interrogate_preamble_python_native[];
+
 Filename output_code_filename;
 string module_name;
 string library_name;
@@ -635,8 +638,10 @@ int main(int argc, char *argv[]) {
 
       if (build_python_native_wrappers) {
         write_python_table_native(output_code);
-      }
 
+        // Output the support code.
+        output_code << interrogate_preamble_python_native << "\n";
+      }
     }
   }
 

+ 103 - 91
dtool/src/interrogatedb/dtool_super_base.cxx

@@ -15,120 +15,132 @@
 
 #ifdef HAVE_PYTHON
 
-class EmptyClass {
-};
-Define_Module_Class_Private(dtoolconfig, DTOOL_SUPER_BASE, EmptyClass, DTOOL_SUPER_BASE111);
-
 static PyObject *GetSuperBase(PyObject *self) {
-  Py_INCREF((PyTypeObject *)&Dtool_DTOOL_SUPER_BASE); // order is important .. this is used for static functions
-  return (PyObject *) &Dtool_DTOOL_SUPER_BASE;
-};
-
-PyMethodDef Dtool_Methods_DTOOL_SUPER_BASE[] = {
-  { "DtoolGetSuperBase", (PyCFunction) &GetSuperBase, METH_NOARGS, "Will Return SUPERbase Class"},
-  { nullptr, nullptr, 0, nullptr }
+  Dtool_PyTypedObject *super_base = Dtool_GetSuperBase();
+  Py_XINCREF((PyTypeObject *)super_base); // order is important .. this is used for static functions
+  return (PyObject *)super_base;
 };
 
-EXPCL_INTERROGATEDB void Dtool_PyModuleClassInit_DTOOL_SUPER_BASE(PyObject *module) {
-  static bool initdone = false;
-  if (!initdone) {
-
-    initdone = true;
-    Dtool_DTOOL_SUPER_BASE._PyType.tp_dict = PyDict_New();
-    PyDict_SetItemString(Dtool_DTOOL_SUPER_BASE._PyType.tp_dict, "DtoolClassDict", Dtool_DTOOL_SUPER_BASE._PyType.tp_dict);
-
-    if (PyType_Ready((PyTypeObject *)&Dtool_DTOOL_SUPER_BASE) < 0) {
-      PyErr_SetString(PyExc_TypeError, "PyType_Ready(Dtool_DTOOL_SUPER_BASE)");
-      return;
-    }
-    Py_INCREF((PyTypeObject *)&Dtool_DTOOL_SUPER_BASE);
-
-    PyDict_SetItemString(Dtool_DTOOL_SUPER_BASE._PyType.tp_dict, "DtoolGetSuperBase", PyCFunction_New(&Dtool_Methods_DTOOL_SUPER_BASE[0], (PyObject *)&Dtool_DTOOL_SUPER_BASE));
-  }
-
+static void Dtool_PyModuleClassInit_DTOOL_SUPER_BASE(PyObject *module) {
   if (module != nullptr) {
-    Py_INCREF((PyTypeObject *)&Dtool_DTOOL_SUPER_BASE);
-    PyModule_AddObject(module, "DTOOL_SUPER_BASE", (PyObject *)&Dtool_DTOOL_SUPER_BASE);
+    Dtool_PyTypedObject *super_base = Dtool_GetSuperBase();
+    Py_INCREF((PyTypeObject *)&super_base);
+    PyModule_AddObject(module, "DTOOL_SUPER_BASE", (PyObject *)&super_base);
   }
 }
 
-inline void *Dtool_DowncastInterface_DTOOL_SUPER_BASE(void *from_this, Dtool_PyTypedObject *from_type) {
+static void *Dtool_DowncastInterface_DTOOL_SUPER_BASE(void *from_this, Dtool_PyTypedObject *from_type) {
   return nullptr;
 }
 
-inline void *Dtool_UpcastInterface_DTOOL_SUPER_BASE(PyObject *self, Dtool_PyTypedObject *requested_type) {
+static void *Dtool_UpcastInterface_DTOOL_SUPER_BASE(PyObject *self, Dtool_PyTypedObject *requested_type) {
   return nullptr;
 }
 
-int Dtool_Init_DTOOL_SUPER_BASE(PyObject *self, PyObject *args, PyObject *kwds) {
+static int Dtool_Init_DTOOL_SUPER_BASE(PyObject *self, PyObject *args, PyObject *kwds) {
   assert(self != nullptr);
   PyErr_Format(PyExc_TypeError, "cannot init constant class %s", Py_TYPE(self)->tp_name);
   return -1;
 }
 
-EXPORT_THIS Dtool_PyTypedObject Dtool_DTOOL_SUPER_BASE = {
-  {
-    PyVarObject_HEAD_INIT(nullptr, 0)
-    "dtoolconfig.DTOOL_SUPER_BASE",
-    sizeof(Dtool_PyInstDef),
-    0, // tp_itemsize
-    &Dtool_FreeInstance_DTOOL_SUPER_BASE,
-    nullptr, // tp_print
-    nullptr, // tp_getattr
-    nullptr, // tp_setattr
+static void Dtool_FreeInstance_DTOOL_SUPER_BASE(PyObject *self) {
+  Py_TYPE(self)->tp_free(self);
+}
+
+/**
+ * Returns a pointer to the DTOOL_SUPER_BASE class that is the base class of
+ * all Panda types.  This pointer is shared by all modules.
+ */
+Dtool_PyTypedObject *Dtool_GetSuperBase() {
+  Dtool_TypeMap *type_map = Dtool_GetGlobalTypeMap();
+  auto it = type_map->find("DTOOL_SUPER_BASE");
+  if (it != type_map->end()) {
+    return it->second;
+  }
+
+  static PyMethodDef methods[] = {
+    { "DtoolGetSuperBase", (PyCFunction)&GetSuperBase, METH_NOARGS, "Will Return SUPERbase Class"},
+    { nullptr, nullptr, 0, nullptr }
+  };
+
+  static Dtool_PyTypedObject super_base_type = {
+    {
+      PyVarObject_HEAD_INIT(nullptr, 0)
+      "dtoolconfig.DTOOL_SUPER_BASE",
+      sizeof(Dtool_PyInstDef),
+      0, // tp_itemsize
+      &Dtool_FreeInstance_DTOOL_SUPER_BASE,
+      nullptr, // tp_print
+      nullptr, // tp_getattr
+      nullptr, // tp_setattr
 #if PY_MAJOR_VERSION >= 3
-    nullptr, // tp_compare
+      nullptr, // tp_compare
 #else
-    &DtoolInstance_ComparePointers,
+      &DtoolInstance_ComparePointers,
 #endif
-    nullptr, // tp_repr
-    nullptr, // tp_as_number
-    nullptr, // tp_as_sequence
-    nullptr, // tp_as_mapping
-    &DtoolInstance_HashPointer,
-    nullptr, // tp_call
-    nullptr, // tp_str
-    PyObject_GenericGetAttr,
-    PyObject_GenericSetAttr,
-    nullptr, // tp_as_buffer
-    (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_CHECKTYPES),
-    nullptr, // tp_doc
-    nullptr, // tp_traverse
-    nullptr, // tp_clear
+      nullptr, // tp_repr
+      nullptr, // tp_as_number
+      nullptr, // tp_as_sequence
+      nullptr, // tp_as_mapping
+      &DtoolInstance_HashPointer,
+      nullptr, // tp_call
+      nullptr, // tp_str
+      PyObject_GenericGetAttr,
+      PyObject_GenericSetAttr,
+      nullptr, // tp_as_buffer
+      (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_CHECKTYPES),
+      nullptr, // tp_doc
+      nullptr, // tp_traverse
+      nullptr, // tp_clear
 #if PY_MAJOR_VERSION >= 3
-    &DtoolInstance_RichComparePointers,
+      &DtoolInstance_RichComparePointers,
 #else
-    nullptr, // tp_richcompare
+      nullptr, // tp_richcompare
 #endif
-    0, // tp_weaklistoffset
-    nullptr, // tp_iter
-    nullptr, // tp_iternext
-    Dtool_Methods_DTOOL_SUPER_BASE,
-    standard_type_members,
-    nullptr, // tp_getset
-    nullptr, // tp_base
-    nullptr, // tp_dict
-    nullptr, // tp_descr_get
-    nullptr, // tp_descr_set
-    0, // tp_dictoffset
-    Dtool_Init_DTOOL_SUPER_BASE,
-    PyType_GenericAlloc,
-    Dtool_new_DTOOL_SUPER_BASE,
-    PyObject_Del,
-    nullptr, // tp_is_gc
-    nullptr, // tp_bases
-    nullptr, // tp_mro
-    nullptr, // tp_cache
-    nullptr, // tp_subclasses
-    nullptr, // tp_weaklist
-    nullptr, // tp_del
-  },
-  TypeHandle::none(),
-  Dtool_PyModuleClassInit_DTOOL_SUPER_BASE,
-  Dtool_UpcastInterface_DTOOL_SUPER_BASE,
-  Dtool_DowncastInterface_DTOOL_SUPER_BASE,
-  nullptr,
-  nullptr,
-};
+      0, // tp_weaklistoffset
+      nullptr, // tp_iter
+      nullptr, // tp_iternext
+      methods,
+      standard_type_members,
+      nullptr, // tp_getset
+      nullptr, // tp_base
+      nullptr, // tp_dict
+      nullptr, // tp_descr_get
+      nullptr, // tp_descr_set
+      0, // tp_dictoffset
+      Dtool_Init_DTOOL_SUPER_BASE,
+      PyType_GenericAlloc,
+      nullptr, // tp_new
+      PyObject_Del,
+      nullptr, // tp_is_gc
+      nullptr, // tp_bases
+      nullptr, // tp_mro
+      nullptr, // tp_cache
+      nullptr, // tp_subclasses
+      nullptr, // tp_weaklist
+      nullptr, // tp_del
+    },
+    TypeHandle::none(),
+    Dtool_PyModuleClassInit_DTOOL_SUPER_BASE,
+    Dtool_UpcastInterface_DTOOL_SUPER_BASE,
+    Dtool_DowncastInterface_DTOOL_SUPER_BASE,
+    nullptr,
+    nullptr,
+  };
+
+  super_base_type._PyType.tp_dict = PyDict_New();
+  PyDict_SetItemString(super_base_type._PyType.tp_dict, "DtoolClassDict", super_base_type._PyType.tp_dict);
+
+  if (PyType_Ready((PyTypeObject *)&super_base_type) < 0) {
+    PyErr_SetString(PyExc_TypeError, "PyType_Ready(Dtool_DTOOL_SUPER_BASE)");
+    return nullptr;
+  }
+  Py_INCREF((PyTypeObject *)&super_base_type);
+
+  PyDict_SetItemString(super_base_type._PyType.tp_dict, "DtoolGetSuperBase", PyCFunction_New(&methods[0], (PyObject *)&super_base_type));
+
+  (*type_map)["DTOOL_SUPER_BASE"] = &super_base_type;
+  return &super_base_type;
+}
 
 #endif  // HAVE_PYTHON

+ 0 - 1
dtool/src/interrogatedb/p3interrogatedb_composite1.cxx

@@ -1,5 +1,4 @@
 #include "config_interrogatedb.cxx"
-#include "dtool_super_base.cxx"
 #include "indexRemapper.cxx"
 #include "interrogateComponent.cxx"
 #include "interrogateDatabase.cxx"

+ 0 - 3
dtool/src/interrogatedb/p3interrogatedb_composite2.cxx

@@ -4,6 +4,3 @@
 #include "interrogate_datafile.cxx"
 #include "interrogate_interface.cxx"
 #include "interrogate_request.cxx"
-#include "py_panda.cxx"
-#include "py_compat.cxx"
-#include "py_wrappers.cxx"

+ 0 - 7
dtool/src/interrogatedb/py_compat.cxx

@@ -1,11 +1,4 @@
 /**
- * PANDA 3D SOFTWARE
- * Copyright (c) Carnegie Mellon University.  All rights reserved.
- *
- * All use of this software is subject to the terms of the revised BSD
- * license.  You should have received a copy of this license along
- * with this source code in a file named "LICENSE."
- *
  * @file py_compat.cxx
  * @author rdb
  * @date 2017-12-03

+ 1 - 8
dtool/src/interrogatedb/py_compat.h

@@ -1,11 +1,4 @@
 /**
- * PANDA 3D SOFTWARE
- * Copyright (c) Carnegie Mellon University.  All rights reserved.
- *
- * All use of this software is subject to the terms of the revised BSD
- * license.  You should have received a copy of this license along
- * with this source code in a file named "LICENSE."
- *
  * @file py_compat.h
  * @author rdb
  * @date 2017-12-02
@@ -106,7 +99,7 @@ typedef int Py_ssize_t;
 // PyInt_FromSize_t automatically picks the right type.
 #  define PyLongOrInt_AS_LONG PyInt_AsLong
 
-EXPCL_INTERROGATEDB size_t PyLongOrInt_AsSize_t(PyObject *);
+size_t PyLongOrInt_AsSize_t(PyObject *);
 #endif
 
 // Which character to use in PyArg_ParseTuple et al for a byte string.

+ 12 - 7
dtool/src/interrogatedb/py_panda.I

@@ -1,11 +1,4 @@
 /**
- * PANDA 3D SOFTWARE
- * Copyright (c) Carnegie Mellon University.  All rights reserved.
- *
- * All use of this software is subject to the terms of the revised BSD
- * license.  You should have received a copy of this license along
- * with this source code in a file named "LICENSE."
- *
  * @file py_panda.I
  * @author rdb
  * @date 2016-06-06
@@ -142,6 +135,18 @@ DTool_CreatePyInstanceTyped(T *obj, bool memory_rules) {
   return DTool_CreatePyInstanceTyped((void*) obj, *known_class, memory_rules, false, obj->get_type().get_index());
 }
 
+/**
+ * Finishes initializing the Dtool_PyInstDef.
+ */
+INLINE int
+DTool_PyInit_Finalize(PyObject *self, void *local_this, Dtool_PyTypedObject *type, bool memory_rules, bool is_const) {
+  ((Dtool_PyInstDef *)self)->_My_Type = type;
+  ((Dtool_PyInstDef *)self)->_ptr_to_object = local_this;
+  ((Dtool_PyInstDef *)self)->_memory_rules = memory_rules;
+  ((Dtool_PyInstDef *)self)->_is_const = is_const;
+  return 0;
+}
+
 /**
  * Checks that the tuple is empty.
  */

+ 10 - 83
dtool/src/interrogatedb/py_panda.cxx

@@ -1,11 +1,4 @@
 /**
- * PANDA 3D SOFTWARE
- * Copyright (c) Carnegie Mellon University.  All rights reserved.
- *
- * All use of this software is subject to the terms of the revised BSD
- * license.  You should have received a copy of this license along
- * with this source code in a file named "LICENSE."
- *
  * @file py_panda.cxx
  * @author drose
  * @date 2005-07-04
@@ -480,49 +473,22 @@ PyObject *DTool_CreatePyInstance(void *local_this, Dtool_PyTypedObject &in_class
   return (PyObject *)self;
 }
 
-// Th Finalizer for simple instances..
-int DTool_PyInit_Finalize(PyObject *self, void *local_this, Dtool_PyTypedObject *type, bool memory_rules, bool is_const) {
-  // lets put some code in here that checks to see the memory is properly
-  // configured.. prior to my call ..
-
-  ((Dtool_PyInstDef *)self)->_My_Type = type;
-  ((Dtool_PyInstDef *)self)->_ptr_to_object = local_this;
-  ((Dtool_PyInstDef *)self)->_memory_rules = memory_rules;
-  ((Dtool_PyInstDef *)self)->_is_const = is_const;
-  return 0;
-}
-
-// A helper function to glue method definition together .. that can not be
-// done at code generation time because of multiple generation passes in
-// interrogate..
-void Dtool_Accum_MethDefs(PyMethodDef in[], MethodDefmap &themap) {
-  for (; in->ml_name != nullptr; in++) {
-    if (themap.find(in->ml_name) == themap.end()) {
-      themap[in->ml_name] = in;
-    }
-  }
-}
-
 /**
  * Returns a borrowed reference to the global type dictionary.
  */
 Dtool_TypeMap *Dtool_GetGlobalTypeMap() {
-  PyObject *capsule = PySys_GetObject("_interrogate_types");
+  PyObject *capsule = PySys_GetObject((char *)"_interrogate_types");
   if (capsule != nullptr) {
     return (Dtool_TypeMap *)PyCapsule_GetPointer(capsule, nullptr);
   } else {
     Dtool_TypeMap *type_map = new Dtool_TypeMap;
     capsule = PyCapsule_New((void *)type_map, nullptr, nullptr);
-    PySys_SetObject("_interrogate_types", capsule);
+    PySys_SetObject((char *)"_interrogate_types", capsule);
     Py_DECREF(capsule);
     return type_map;
   }
 }
 
-Dtool_PyTypedObject *Dtool_RuntimeTypeDtoolType(int type) {
-  return (Dtool_PyTypedObject *)TypeHandle::from_index(type).get_python_type();
-}
-
 #if PY_MAJOR_VERSION >= 3
 PyObject *Dtool_PyModuleInitHelper(const LibraryDef *defs[], PyModuleDef *module_def) {
 #else
@@ -544,58 +510,19 @@ PyObject *Dtool_PyModuleInitHelper(const LibraryDef *defs[], const char *modulen
     return nullptr;
   }
 
-  // Initialize the types we define in py_panda.
-  static bool dtool_inited = false;
-  if (!dtool_inited) {
-    dtool_inited = true;
-
-    if (PyType_Ready(&Dtool_SequenceWrapper_Type) < 0) {
-      return Dtool_Raise_TypeError("PyType_Ready(Dtool_SequenceWrapper)");
-    }
-
-    if (PyType_Ready(&Dtool_MutableSequenceWrapper_Type) < 0) {
-      return Dtool_Raise_TypeError("PyType_Ready(Dtool_MutableSequenceWrapper)");
-    }
-
-    if (PyType_Ready(&Dtool_MappingWrapper_Type) < 0) {
-      return Dtool_Raise_TypeError("PyType_Ready(Dtool_MappingWrapper)");
-    }
-
-    if (PyType_Ready(&Dtool_MutableMappingWrapper_Type) < 0) {
-      return Dtool_Raise_TypeError("PyType_Ready(Dtool_MutableMappingWrapper)");
-    }
-
-    if (PyType_Ready(&Dtool_MappingWrapper_Keys_Type) < 0) {
-      return Dtool_Raise_TypeError("PyType_Ready(Dtool_MappingWrapper_Keys)");
-    }
-
-    if (PyType_Ready(&Dtool_MappingWrapper_Values_Type) < 0) {
-      return Dtool_Raise_TypeError("PyType_Ready(Dtool_MappingWrapper_Values)");
-    }
-
-    if (PyType_Ready(&Dtool_MappingWrapper_Items_Type) < 0) {
-      return Dtool_Raise_TypeError("PyType_Ready(Dtool_MappingWrapper_Items)");
-    }
-
-    if (PyType_Ready(&Dtool_GeneratorWrapper_Type) < 0) {
-      return Dtool_Raise_TypeError("PyType_Ready(Dtool_GeneratorWrapper)");
-    }
-
-    if (PyType_Ready(&Dtool_StaticProperty_Type) < 0) {
-      return Dtool_Raise_TypeError("PyType_Ready(Dtool_StaticProperty_Type)");
-    }
-
-    // Initialize the base class of everything.
-    Dtool_PyModuleClassInit_DTOOL_SUPER_BASE(nullptr);
-  }
-
   Dtool_TypeMap *type_map = Dtool_GetGlobalTypeMap();
 
   // the module level function inits....
   MethodDefmap functions;
   for (size_t i = 0; defs[i] != nullptr; i++) {
     const LibraryDef &def = *defs[i];
-    Dtool_Accum_MethDefs(def._methods, functions);
+
+    // Accumulate method definitions.
+    for (PyMethodDef *meth = def._methods; meth->ml_name != nullptr; meth++) {
+      if (functions.find(meth->ml_name) == functions.end()) {
+        functions[meth->ml_name] = meth;
+      }
+    }
 
     // Define exported types.
     const Dtool_TypeDef *types = def._types;
@@ -746,7 +673,7 @@ PyObject *Dtool_BorrowThisReference(PyObject *self, PyObject *args) {
 
 // We do expose a dictionay for dtool classes .. this should be removed at
 // some point..
-EXPCL_INTERROGATEDB PyObject *Dtool_AddToDictionary(PyObject *self1, PyObject *args) {
+PyObject *Dtool_AddToDictionary(PyObject *self1, PyObject *args) {
   PyObject *self;
   PyObject *subject;
   PyObject *key;

+ 32 - 49
dtool/src/interrogatedb/py_panda.h

@@ -1,11 +1,4 @@
 /**
- * PANDA 3D SOFTWARE
- * Copyright (c) Carnegie Mellon University.  All rights reserved.
- *
- * All use of this software is subject to the terms of the revised BSD
- * license.  You should have received a copy of this license along
- * with this source code in a file named "LICENSE."
- *
  * @file py_panda.h
  */
 
@@ -43,9 +36,6 @@ using namespace std;
 #endif
 
 struct Dtool_PyTypedObject;
-typedef std::map<int, Dtool_PyTypedObject *> RuntimeTypeMap;
-typedef std::set<int> RuntimeTypeSet;
-typedef std::map<std::string, Dtool_PyTypedObject *> NamedTypeMap;
 
 // used to stamp dtool instance..
 #define PY_PANDA_SIGNATURE 0xbeaf
@@ -78,7 +68,7 @@ struct Dtool_PyInstDef {
 };
 
 // A Offset Dictionary Defining How to read the Above Object..
-extern EXPCL_INTERROGATEDB PyMemberDef standard_type_members[];
+extern PyMemberDef standard_type_members[];
 
 // The Class Definition Structor For a Dtool python type.
 struct Dtool_PyTypedObject {
@@ -192,21 +182,19 @@ static void Dtool_FreeInstance_##CLASS_NAME(PyObject *self) {\
 
 typedef std::map<std::string, Dtool_PyTypedObject *> Dtool_TypeMap;
 
-EXPCL_INTERROGATEDB Dtool_TypeMap *Dtool_GetGlobalTypeMap();
-
-EXPCL_INTERROGATEDB Dtool_PyTypedObject *Dtool_RuntimeTypeDtoolType(int type);
+Dtool_TypeMap *Dtool_GetGlobalTypeMap();
 
 /**
 
  */
-EXPCL_INTERROGATEDB void DTOOL_Call_ExtractThisPointerForType(PyObject *self, Dtool_PyTypedObject *classdef, void **answer);
+void DTOOL_Call_ExtractThisPointerForType(PyObject *self, Dtool_PyTypedObject *classdef, void **answer);
 
-EXPCL_INTERROGATEDB void *DTOOL_Call_GetPointerThisClass(PyObject *self, Dtool_PyTypedObject *classdef, int param, const std::string &function_name, bool const_ok, bool report_errors);
+void *DTOOL_Call_GetPointerThisClass(PyObject *self, Dtool_PyTypedObject *classdef, int param, const std::string &function_name, bool const_ok, bool report_errors);
 
-EXPCL_INTERROGATEDB bool Dtool_Call_ExtractThisPointer(PyObject *self, Dtool_PyTypedObject &classdef, void **answer);
+bool Dtool_Call_ExtractThisPointer(PyObject *self, Dtool_PyTypedObject &classdef, void **answer);
 
-EXPCL_INTERROGATEDB bool Dtool_Call_ExtractThisPointer_NonConst(PyObject *self, Dtool_PyTypedObject &classdef,
-                                                              void **answer, const char *method_name);
+bool Dtool_Call_ExtractThisPointer_NonConst(PyObject *self, Dtool_PyTypedObject &classdef,
+                                            void **answer, const char *method_name);
 
 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);
@@ -216,7 +204,7 @@ INLINE int DtoolInstance_ComparePointers(PyObject *v1, PyObject *v2);
 INLINE PyObject *DtoolInstance_RichComparePointers(PyObject *v1, PyObject *v2, int op);
 
 // Functions related to error reporting.
-EXPCL_INTERROGATEDB bool _Dtool_CheckErrorOccurred();
+bool _Dtool_CheckErrorOccurred();
 
 #ifdef NDEBUG
 #define Dtool_CheckErrorOccurred() (UNLIKELY(_PyErr_OCCURRED() != nullptr))
@@ -224,12 +212,12 @@ EXPCL_INTERROGATEDB bool _Dtool_CheckErrorOccurred();
 #define Dtool_CheckErrorOccurred() (UNLIKELY(_Dtool_CheckErrorOccurred()))
 #endif
 
-EXPCL_INTERROGATEDB PyObject *Dtool_Raise_AssertionError();
-EXPCL_INTERROGATEDB PyObject *Dtool_Raise_TypeError(const char *message);
-EXPCL_INTERROGATEDB PyObject *Dtool_Raise_ArgTypeError(PyObject *obj, int param, const char *function_name, const char *type_name);
-EXPCL_INTERROGATEDB PyObject *Dtool_Raise_AttributeError(PyObject *obj, const char *attribute);
+PyObject *Dtool_Raise_AssertionError();
+PyObject *Dtool_Raise_TypeError(const char *message);
+PyObject *Dtool_Raise_ArgTypeError(PyObject *obj, int param, const char *function_name, const char *type_name);
+PyObject *Dtool_Raise_AttributeError(PyObject *obj, const char *attribute);
 
-EXPCL_INTERROGATEDB PyObject *_Dtool_Raise_BadArgumentsError();
+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()
@@ -241,9 +229,9 @@ EXPCL_INTERROGATEDB PyObject *_Dtool_Raise_BadArgumentsError();
 // These functions are similar to Dtool_WrapValue, except that they also
 // contain code for checking assertions and exceptions when compiling with
 // NDEBUG mode on.
-EXPCL_INTERROGATEDB PyObject *_Dtool_Return_None();
-EXPCL_INTERROGATEDB PyObject *Dtool_Return_Bool(bool value);
-EXPCL_INTERROGATEDB PyObject *_Dtool_Return(PyObject *value);
+PyObject *_Dtool_Return_None();
+PyObject *Dtool_Return_Bool(bool value);
+PyObject *_Dtool_Return(PyObject *value);
 
 #ifdef NDEBUG
 #define Dtool_Return_None() (LIKELY(_PyErr_OCCURRED() == nullptr) ? (Py_INCREF(Py_None), Py_None) : nullptr)
@@ -256,19 +244,19 @@ EXPCL_INTERROGATEDB PyObject *_Dtool_Return(PyObject *value);
 /**
  * Wrapper around Python 3.4's enum library, which does not have a C API.
  */
-EXPCL_INTERROGATEDB PyTypeObject *Dtool_EnumType_Create(const char *name, PyObject *names,
+PyTypeObject *Dtool_EnumType_Create(const char *name, PyObject *names,
                                                         const char *module = nullptr);
-EXPCL_INTERROGATEDB INLINE long Dtool_EnumValue_AsLong(PyObject *value);
+INLINE long Dtool_EnumValue_AsLong(PyObject *value);
 
 
 /**
 
  */
-EXPCL_INTERROGATEDB PyObject *DTool_CreatePyInstanceTyped(void *local_this_in, Dtool_PyTypedObject &known_class_type, bool memory_rules, bool is_const, int RunTimeType);
+PyObject *DTool_CreatePyInstanceTyped(void *local_this_in, Dtool_PyTypedObject &known_class_type, bool memory_rules, bool is_const, int RunTimeType);
 
 // DTool_CreatePyInstance .. wrapper function to finalize the existance of a
 // general dtool py instance..
-EXPCL_INTERROGATEDB 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);
 
 // These template methods allow use when the Dtool_PyTypedObject is not known.
 // They require a get_class_type() to be defined for the class.
@@ -312,15 +300,13 @@ Define_Dtool_FreeInstanceRef(CLASS_NAME,CNAME)\
 Define_Dtool_Class(MODULE_NAME,CLASS_NAME,PUBLIC_NAME)
 
 // The finalizer for simple instances.
-EXPCL_INTERROGATEDB int DTool_PyInit_Finalize(PyObject *self, void *This, Dtool_PyTypedObject *type, bool memory_rules, bool is_const);
+INLINE int DTool_PyInit_Finalize(PyObject *self, void *This, Dtool_PyTypedObject *type, bool memory_rules, bool is_const);
 
 // A heler function to glu methed definition together .. that can not be done
 // at code generation time becouse of multiple generation passes in
 // interigate..
 typedef std::map<std::string, PyMethodDef *> MethodDefmap;
 
-EXPCL_INTERROGATEDB void Dtool_Accum_MethDefs(PyMethodDef in[], MethodDefmap &themap);
-
 // We need a way to runtime merge compile units into a python "Module" .. this
 // is done with the fallowing structors and code.. along with the support of
 // interigate_module
@@ -337,26 +323,26 @@ struct LibraryDef {
 };
 
 #if PY_MAJOR_VERSION >= 3
-EXPCL_INTERROGATEDB PyObject *Dtool_PyModuleInitHelper(const LibraryDef *defs[], PyModuleDef *module_def);
+PyObject *Dtool_PyModuleInitHelper(const LibraryDef *defs[], PyModuleDef *module_def);
 #else
-EXPCL_INTERROGATEDB PyObject *Dtool_PyModuleInitHelper(const LibraryDef *defs[], const char *modulename);
+PyObject *Dtool_PyModuleInitHelper(const LibraryDef *defs[], const char *modulename);
 #endif
 
 // HACK.... Be carefull Dtool_BorrowThisReference This function can be used to
 // grab the "THIS" pointer from an object and use it Required to support fom
 // historical inharatence in the for of "is this instance of"..
-EXPCL_INTERROGATEDB PyObject *Dtool_BorrowThisReference(PyObject *self, PyObject *args);
+PyObject *Dtool_BorrowThisReference(PyObject *self, PyObject *args);
 
 #define DTOOL_PyObject_HashPointer DtoolInstance_HashPointer
 #define DTOOL_PyObject_ComparePointers DtoolInstance_ComparePointers
 
-EXPCL_INTERROGATEDB PyObject *
+PyObject *
 copy_from_make_copy(PyObject *self, PyObject *noargs);
 
-EXPCL_INTERROGATEDB PyObject *
+PyObject *
 copy_from_copy_constructor(PyObject *self, PyObject *noargs);
 
-EXPCL_INTERROGATEDB PyObject *
+PyObject *
 map_deepcopy_to_copy(PyObject *self, PyObject *args);
 
 /**
@@ -365,13 +351,13 @@ map_deepcopy_to_copy(PyObject *self, PyObject *args);
  */
 ALWAYS_INLINE bool Dtool_CheckNoArgs(PyObject *args);
 ALWAYS_INLINE bool Dtool_CheckNoArgs(PyObject *args, PyObject *kwds);
-EXPCL_INTERROGATEDB bool Dtool_ExtractArg(PyObject **result, PyObject *args,
+bool Dtool_ExtractArg(PyObject **result, PyObject *args,
                                           PyObject *kwds, const char *keyword);
-EXPCL_INTERROGATEDB bool Dtool_ExtractArg(PyObject **result, PyObject *args,
+bool Dtool_ExtractArg(PyObject **result, PyObject *args,
                                           PyObject *kwds);
-EXPCL_INTERROGATEDB bool Dtool_ExtractOptionalArg(PyObject **result, PyObject *args,
+bool Dtool_ExtractOptionalArg(PyObject **result, PyObject *args,
                                                   PyObject *kwds, const char *keyword);
-EXPCL_INTERROGATEDB bool Dtool_ExtractOptionalArg(PyObject **result, PyObject *args,
+bool Dtool_ExtractOptionalArg(PyObject **result, PyObject *args,
                                                   PyObject *kwds);
 
 /**
@@ -407,10 +393,7 @@ ALWAYS_INLINE PyObject *Dtool_WrapValue(Py_buffer *value);
 template<class T1, class T2>
 ALWAYS_INLINE PyObject *Dtool_WrapValue(const std::pair<T1, T2> &value);
 
-EXPCL_INTERROGATEDB extern struct Dtool_PyTypedObject Dtool_DTOOL_SUPER_BASE;
-EXPCL_INTERROGATEDB extern void Dtool_PyModuleClassInit_DTOOL_SUPER_BASE(PyObject *module);
-
-#define Dtool_Ptr_DTOOL_SUPER_BASE (&Dtool_DTOOL_SUPER_BASE)
+Dtool_PyTypedObject *Dtool_GetSuperBase();
 
 #include "py_panda.I"
 

File diff suppressed because it is too large
+ 299 - 674
dtool/src/interrogatedb/py_wrappers.cxx


+ 6 - 23
dtool/src/interrogatedb/py_wrappers.h

@@ -1,11 +1,4 @@
 /**
- * PANDA 3D SOFTWARE
- * Copyright (c) Carnegie Mellon University.  All rights reserved.
- *
- * All use of this software is subject to the terms of the revised BSD
- * license.  You should have received a copy of this license along
- * with this source code in a file named "LICENSE."
- *
  * @file py_wrappers.h
  * @author rdb
  * @date 2017-11-26
@@ -56,22 +49,12 @@ struct Dtool_GeneratorWrapper {
   iternextfunc _iternext_func;
 };
 
-EXPCL_INTERROGATEDB extern PyTypeObject Dtool_SequenceWrapper_Type;
-EXPCL_INTERROGATEDB extern PyTypeObject Dtool_MutableSequenceWrapper_Type;
-EXPCL_INTERROGATEDB extern PyTypeObject Dtool_MappingWrapper_Type;
-EXPCL_INTERROGATEDB extern PyTypeObject Dtool_MutableMappingWrapper_Type;
-EXPCL_INTERROGATEDB extern PyTypeObject Dtool_MappingWrapper_Items_Type;
-EXPCL_INTERROGATEDB extern PyTypeObject Dtool_MappingWrapper_Keys_Type;
-EXPCL_INTERROGATEDB extern PyTypeObject Dtool_MappingWrapper_Values_Type;
-EXPCL_INTERROGATEDB extern PyTypeObject Dtool_GeneratorWrapper_Type;
-EXPCL_INTERROGATEDB extern PyTypeObject Dtool_StaticProperty_Type;
-
-EXPCL_INTERROGATEDB Dtool_SequenceWrapper *Dtool_NewSequenceWrapper(PyObject *self, const char *name);
-EXPCL_INTERROGATEDB Dtool_MutableSequenceWrapper *Dtool_NewMutableSequenceWrapper(PyObject *self, const char *name);
-EXPCL_INTERROGATEDB Dtool_MappingWrapper *Dtool_NewMappingWrapper(PyObject *self, const char *name);
-EXPCL_INTERROGATEDB Dtool_MappingWrapper *Dtool_NewMutableMappingWrapper(PyObject *self, const char *name);
-EXPCL_INTERROGATEDB PyObject *Dtool_NewGenerator(PyObject *self, const char *name, iternextfunc func);
-EXPCL_INTERROGATEDB PyObject *Dtool_NewStaticProperty(PyTypeObject *obj, const PyGetSetDef *getset);
+Dtool_SequenceWrapper *Dtool_NewSequenceWrapper(PyObject *self, const char *name);
+Dtool_MutableSequenceWrapper *Dtool_NewMutableSequenceWrapper(PyObject *self, const char *name);
+Dtool_MappingWrapper *Dtool_NewMappingWrapper(PyObject *self, const char *name);
+Dtool_MappingWrapper *Dtool_NewMutableMappingWrapper(PyObject *self, const char *name);
+PyObject *Dtool_NewGenerator(PyObject *self, iternextfunc func);
+PyObject *Dtool_NewStaticProperty(PyTypeObject *obj, const PyGetSetDef *getset);
 
 #endif  // HAVE_PYTHON
 

+ 9 - 2
makepanda/makepanda.py

@@ -3442,14 +3442,13 @@ TargetAdd('libp3dtoolconfig.dll', opts=['ADVAPI', 'OPENSSL', 'WINGDI', 'WINUSER'
 # DIRECTORY: dtool/src/interrogatedb/
 #
 
-OPTS=['DIR:dtool/src/interrogatedb', 'BUILDING:INTERROGATEDB', 'PYTHON']
+OPTS=['DIR:dtool/src/interrogatedb', 'BUILDING:INTERROGATEDB']
 TargetAdd('p3interrogatedb_composite1.obj', opts=OPTS, input='p3interrogatedb_composite1.cxx')
 TargetAdd('p3interrogatedb_composite2.obj', opts=OPTS, input='p3interrogatedb_composite2.cxx')
 TargetAdd('libp3interrogatedb.dll', input='p3interrogatedb_composite1.obj')
 TargetAdd('libp3interrogatedb.dll', input='p3interrogatedb_composite2.obj')
 TargetAdd('libp3interrogatedb.dll', input='libp3dtool.dll')
 TargetAdd('libp3interrogatedb.dll', input='libp3dtoolconfig.dll')
-TargetAdd('libp3interrogatedb.dll', opts=['PYTHON'])
 
 if not PkgSkip("PYTHON"):
   # This used to be called dtoolconfig.pyd, but it just contains the interrogatedb
@@ -3489,8 +3488,16 @@ if (not RUNTIME):
   TargetAdd('interrogate.exe', input='libp3pystub.lib')
   TargetAdd('interrogate.exe', opts=['ADVAPI',  'OPENSSL', 'WINSHELL', 'WINGDI', 'WINUSER'])
 
+  preamble = WriteEmbeddedStringFile('interrogate_preamble_python_native', inputs=[
+    'dtool/src/interrogatedb/py_panda.cxx',
+    'dtool/src/interrogatedb/py_compat.cxx',
+    'dtool/src/interrogatedb/py_wrappers.cxx',
+    'dtool/src/interrogatedb/dtool_super_base.cxx',
+  ])
+  TargetAdd('interrogate_module_preamble_python_native.obj', opts=OPTS, input=preamble)
   TargetAdd('interrogate_module_interrogate_module.obj', opts=OPTS, input='interrogate_module.cxx')
   TargetAdd('interrogate_module.exe', input='interrogate_module_interrogate_module.obj')
+  TargetAdd('interrogate_module.exe', input='interrogate_module_preamble_python_native.obj')
   TargetAdd('interrogate_module.exe', input='libp3cppParser.ilb')
   TargetAdd('interrogate_module.exe', input=COMMON_DTOOL_LIBS)
   TargetAdd('interrogate_module.exe', input='libp3interrogatedb.dll')

+ 42 - 0
makepanda/makepandacore.py

@@ -3190,6 +3190,48 @@ def WriteResourceFile(basename, **kwargs):
     ConditionalWriteFile(basename, GenerateResourceFile(**kwargs))
     return basename
 
+
+def WriteEmbeddedStringFile(basename, inputs, string_name=None):
+    if os.path.splitext(basename)[1] not in SUFFIX_INC:
+        basename += '.cxx'
+    target = GetOutputDir() + "/tmp/" + basename
+
+    if string_name is None:
+        string_name = os.path.basename(os.path.splitext(target)[0])
+        string_name = string_name.replace('-', '_')
+
+    data = bytearray()
+    for input in inputs:
+        fp = open(input, 'rb')
+
+        # Insert a #line so that we get meaningful compile/assert errors when
+        # the result is inserted by interrogate_module into generated code.
+        if os.path.splitext(input)[1] in SUFFIX_INC:
+            line = '#line 1 "%s"\n' % (input)
+            data += bytearray(line.encode('ascii', 'replace'))
+
+        data += bytearray(fp.read())
+        fp.close()
+
+    data.append(0)
+
+    output = 'extern const char %s[] = {\n' % (string_name)
+
+    i = 0
+    for byte in data:
+        if i == 0:
+            output += ' '
+
+        output += ' 0x%02x,' % (byte)
+        i += 1
+        if i >= 12:
+            output += '\n'
+            i = 0
+
+    output += '\n};\n'
+    ConditionalWriteFile(target, output)
+    return target
+
 ########################################################################
 ##
 ## FindLocation

+ 1 - 8
panda/src/event/asyncFuture_ext.cxx

@@ -168,14 +168,7 @@ static PyObject *gen_next(PyObject *self) {
  */
 PyObject *Extension<AsyncFuture>::
 __await__(PyObject *self) {
-  Dtool_GeneratorWrapper *gen;
-  gen = (Dtool_GeneratorWrapper *)PyType_GenericAlloc(&Dtool_GeneratorWrapper_Type, 0);
-  if (gen != nullptr) {
-    Py_INCREF(self);
-    gen->_base._self = self;
-    gen->_iternext_func = &gen_next;
-  }
-  return (PyObject *)gen;
+  return Dtool_NewGenerator(self, &gen_next);
 }
 
 /**

Some files were not shown because too many files changed in this diff