Changeset 86333 in vbox for trunk/src/libs/xpcom18a4/python
- Timestamp:
- Sep 28, 2020 8:01:18 PM (4 years ago)
- Location:
- trunk/src/libs/xpcom18a4/python
- Files:
-
- 10 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/libs/xpcom18a4/python/Makefile.kmk
r86245 r86333 279 279 endif 280 280 281 ifndef VBOX_WITH_ONLY_PYTHON_LIMITED_API 282 281 283 ifdef VBOX_PYTHON33_INC 282 284 # … … 582 584 endif 583 585 endif 586 587 endif # !VBOX_WITH_ONLY_PYTHON_LIMITED_API 588 589 ifndef VBOX_WITHOUT_PYTHON_LIMITED_API 590 # 591 # If there is python 3.3 or later present, we can build a generic 592 # 3.x extension. Since 3.3 and 3.4 are rather old, we will pick 593 # those headers last. 594 # 595 # Note! No library dependencies are needed here (at least that's 596 # how the xxlimited.so demo extension is done on linux and darwin). 597 # Note! The 'm' ABI suffix was discontinued in 3.8. 598 # TODO: ASSUMING that we don't need a different headers for pymalloc 599 # ('m' builds < 3.8) and CRT malloc. 600 # 601 VBOX_PYTHON_LIMITED_API_VER := $(firstword $(foreach ver, 35 36 38 39 310 34 33 \ 602 ,$(if-expr defined(VBOX_PYTHON$(ver)_INC),$(ver),)$(if-expr defined(VBOX_PYTHON$(ver)m_INC),$(ver)m,))) 603 ifneq ($(VBOX_PYTHON_LIMITED_API_VER),) 604 DLLS += VBoxPython3 605 VBoxPython3_EXTENDS = VBoxPythonBase 606 VBoxPython3_DEFS = $(filter-out VBOX_PYXPCOM_VERSIONED,$(VBoxPythonBase_DEFS)) Py_LIMITED_API=0x03030000 607 VBoxPython3_INCS = $(VBoxPythonBase_INCS) $(VBOX_PYTHON$(VBOX_PYTHON_LIMITED_API_VER)_INC) 608 609 DLLS += VBoxPython3m 610 VBoxPython3m_EXTENDS = VBoxPythonBase_m 611 VBoxPython3m_DEFS = $(filter-out VBOX_PYXPCOM_VERSIONED,$(VBoxPythonBase_m_DEFS)) Py_LIMITED_API=0x03030000 612 VBoxPython3m_INCS = $(VBoxPythonBase_m_INCS) $(VBOX_PYTHON$(VBOX_PYTHON_LIMITED_API_VER)_INC) 613 endif 614 endif # VBOX_WITH_PYTHON_LIMITED_API 584 615 585 616 endif # VBOX_ONLY_SDK -
trunk/src/libs/xpcom18a4/python/src/PyGBase.cpp
r65842 r86333 154 154 155 155 #ifdef DEBUG_FULL 156 LogF("PyGatewayBase: created %s", m_pPyObject ? m_pPyObject->ob_type->tp_name: "<NULL>");156 LogF("PyGatewayBase: created %s", m_pPyObject ? PyXPCOM_ObTypeName(m_pPyObject) : "<NULL>"); 157 157 #endif 158 158 } … … 400 400 // reporting the fact that QI failed - this error 401 401 // may provide clues! 402 PyXPCOM_LogError("The _QueryInterface_ method returned an object of type '%s', but an interface was expected\n", result->ob_type->tp_name);402 PyXPCOM_LogError("The _QueryInterface_ method returned an object of type '%s', but an interface was expected\n", PyXPCOM_ObTypeName(result)); 403 403 // supports remains false 404 404 } … … 512 512 // The exception handler succeeded, but returned other than 513 513 // int or None. 514 PyXPCOM_LogError("The _CallMethodException_ handler returned object of type '%s' - None or an integer expected\n", err_result->ob_type->tp_name);514 PyXPCOM_LogError("The _CallMethodException_ handler returned object of type '%s' - None or an integer expected\n", PyXPCOM_ObTypeName(err_result)); 515 515 } 516 516 Py_XDECREF(err_result); -
trunk/src/libs/xpcom18a4/python/src/PyGInputStream.cpp
r11746 r86333 104 104 nsresult nr = InvokeNativeViaPolicy(methodName, &ret, "i", count); 105 105 if (NS_SUCCEEDED(nr)) { 106 #ifndef VBOX /* unsafe cast on 64-bit hosts. */ 106 #if 0 /* VBox: new buffer protocol (though I could use it for Py_LIMITED_API and ditch the warning, but cpython specific) */ 107 Py_buffer py_view; 108 if (PyObject_GetBuffer(ret, &py_view, PyBUF_SIMPLE) == 0) { 109 if (py_view.len <= count) { 110 count = py_view.len; 111 } else { 112 PyXPCOM_LogWarning("nsIInputStream::read() was asked for %d bytes, but the string returned is %d bytes - truncating!\n", count, py_size); 113 } 114 memcpy(buf, py_view.py_buf, count); 115 PyBuffer_Release(&py_view); 116 *_retval = count; 117 } else { 118 PyErr_Format(PyExc_TypeError, "nsIInputStream::read() method must return a buffer object - not a '%s' object", PyXPCOM_ObTypeName(ret)); 119 nr = HandleNativeGatewayError(methodName); 120 } 121 #else /* Old protocol: */ 122 # ifndef VBOX /* unsafe cast on 64-bit hosts. */ 107 123 PRUint32 py_size; 108 124 const void *py_buf; 109 125 if (PyObject_AsReadBuffer(ret, &py_buf, (Py_ssize_t*)&py_size)!=0) { 110 # else /* VBOX */126 # else /* VBOX */ 111 127 const void *py_buf; 112 # if PY_VERSION_HEX >= 0x02050000 || defined(PY_SSIZE_T_MIN)128 # if PY_VERSION_HEX >= 0x02050000 || defined(PY_SSIZE_T_MIN) 113 129 Py_ssize_t py_size; 114 # else130 # else 115 131 int py_size; 132 # endif 133 if (PyObject_AsReadBuffer(ret, &py_buf, &py_size)!=0) { 116 134 # endif /* VBOX */ 117 if (PyObject_AsReadBuffer(ret, &py_buf, &py_size)!=0) { 118 #endif /* VBOX */ 119 PyErr_Format(PyExc_TypeError, "nsIInputStream::read() method must return a buffer object - not a '%s' object", ret->ob_type->tp_name); 135 PyErr_Format(PyExc_TypeError, "nsIInputStream::read() method must return a buffer object - not a '%s' object", PyXPCOM_ObTypeName(ret)); 120 136 nr = HandleNativeGatewayError(methodName); 121 137 } else { … … 127 143 *_retval = py_size; 128 144 } 145 #endif 129 146 } 130 147 return nr; -
trunk/src/libs/xpcom18a4/python/src/PyGStub.cpp
r21178 r86333 160 160 // The exception handler succeeded, but returned other than 161 161 // int or None. 162 PyXPCOM_LogError("The _CallMethodException_ handler returned object of type '%s' - None or an integer expected\n", err_result->ob_type->tp_name);162 PyXPCOM_LogError("The _CallMethodException_ handler returned object of type '%s' - None or an integer expected\n", PyXPCOM_ObTypeName(err_result)); 163 163 } 164 164 Py_XDECREF(err_result); -
trunk/src/libs/xpcom18a4/python/src/PyIID.cpp
r86312 r86333 68 68 #else 69 69 if (PyObject_CheckBuffer(obBuf)) { 70 # ifndef Py_LIMITED_API 70 71 Py_buffer view; 71 72 if (PyObject_GetBuffer(obBuf, &view, PyBUF_CONTIG_RO) != 0) { … … 75 76 Py_ssize_t size = view.len; 76 77 const void *buf = view.buf; 78 # else /* Py_LIMITED_API - the buffer API is non-existant, from what I can tell */ 79 const void *buf = NULL; 80 Py_ssize_t size = 0; 81 if (PyObject_AsReadBuffer(obBuf, &buf, &size) != 0) { 82 PyErr_Format(PyExc_ValueError, "Could not get read-only buffer from object"); 83 return NULL; 84 } 85 # endif /* Py_LIMITED_API */ 77 86 #endif 78 87 if (size != sizeof(nsIID) || buf==NULL) { 79 #if PY_MAJOR_VERSION >= 3 88 #if PY_MAJOR_VERSION >= 3 && !defined(Py_LIMITED_API) 80 89 PyBuffer_Release(&view); 81 90 #endif … … 99 108 ptr += sizeof(PRUint8); 100 109 } 101 #if PY_MAJOR_VERSION >= 3 110 #if PY_MAJOR_VERSION >= 3 && !defined(Py_LIMITED_API) 102 111 PyBuffer_Release(&view); 103 112 #endif … … 135 144 return PR_FALSE; 136 145 } 146 #ifndef Py_LIMITED_API 137 147 } else if (ob->ob_type == &type) { 148 #else 149 } else if (ob->ob_type == Py_nsIID::GetTypeObject()) { 150 #endif 138 151 iid = ((Py_nsIID *)ob)->m_iid; 139 152 } else if (PyObject_HasAttrString(ob, "__class__")) { … … 144 157 return PR_FALSE; 145 158 } 159 #ifndef Py_LIMITED_API 146 160 if (use_ob->ob_type != &type) { 161 #else 162 if (use_ob->ob_type != Py_nsIID::GetTypeObject()) { 163 #endif 147 164 Py_DECREF(use_ob); 148 165 PyErr_SetString(PyExc_TypeError, "instance _iidobj_ attributes must be raw IID object"); … … 152 169 Py_DECREF(use_ob); 153 170 } else { 154 PyErr_Format(PyExc_TypeError, "Objects of type '%s' can not be converted to an IID", ob->ob_type->tp_name);171 PyErr_Format(PyExc_TypeError, "Objects of type '%s' can not be converted to an IID", PyXPCOM_ObTypeName(ob)); 155 172 ok = PR_FALSE; 156 173 } … … 164 181 // objects. However, in almost all cases, functions that expect a CLSID/IID 165 182 // as a param will accept either a string object, or a native Py_nsIID object. 183 #ifndef Py_LIMITED_API 166 184 PyTypeObject Py_nsIID::type = 167 185 { … … 202 220 0, /* tp_base */ 203 221 }; 222 #else /* Py_LIMITED_API */ 223 NS_EXPORT_STATIC_MEMBER_(PyTypeObject *) Py_nsIID::s_pType = NULL; 224 225 PyTypeObject *Py_nsIID::GetTypeObject(void) 226 { 227 PyTypeObject *pTypeObj = Py_nsIID::s_pType; 228 if (pTypeObj) 229 return pTypeObj; 230 231 PyType_Slot aTypeSlots[] = { 232 { Py_tp_base, &PyType_Type }, 233 { Py_tp_dealloc, (void *)(uintptr_t)&Py_nsIID::PyTypeMethod_dealloc }, 234 { Py_tp_getattr, (void *)(uintptr_t)&Py_nsIID::PyTypeMethod_getattr }, 235 { Py_tp_repr, (void *)(uintptr_t)&Py_nsIID::PyTypeMethod_repr }, 236 { Py_tp_hash, (void *)(uintptr_t)&Py_nsIID::PyTypeMethod_hash }, 237 { Py_tp_str, (void *)(uintptr_t)&Py_nsIID::PyTypeMethod_str }, 238 { Py_tp_richcompare, (void *)(uintptr_t)&Py_nsIID::PyTypeMethod_richcompare }, 239 { 0, NULL } /* terminator */ 240 }; 241 PyType_Spec TypeSpec = { 242 /* .name: */ "IID", 243 /* .basicsize: */ sizeof(Py_nsIID), 244 /* .itemsize: */ 0, 245 /* .flags: */ 0, 246 /* .slots: */ aTypeSlots, 247 }; 248 249 PyObject *exc_typ = NULL, *exc_val = NULL, *exc_tb = NULL; 250 PyErr_Fetch(&exc_typ, &exc_val, &exc_tb); /* goes south in PyType_Ready if we don't clear exceptions first. */ 251 252 pTypeObj = (PyTypeObject *)PyType_FromSpec(&TypeSpec); 253 assert(pTypeObj); 254 255 PyErr_Restore(exc_typ, exc_val, exc_tb); 256 Py_nsIID::s_pType = pTypeObj; 257 return pTypeObj; 258 } 259 #endif /* Py_LIMITED_API */ 204 260 205 261 Py_nsIID::Py_nsIID(const nsIID &riid) 206 262 { 263 #ifndef Py_LIMITED_API 207 264 ob_type = &type; 265 #else 266 ob_type = GetTypeObject(); 267 #endif 208 268 _Py_NewReference(this); 209 269 m_iid = riid; -
trunk/src/libs/xpcom18a4/python/src/PyISupports.cpp
r86310 r86333 129 129 } 130 130 131 #ifndef Py_LIMITED_API 131 132 Py_nsISupports::Py_nsISupports(nsISupports *punk, const nsIID &iid, PyTypeObject *this_type) 132 { 133 #else 134 Py_nsISupports::Py_nsISupports(nsISupports *punk, const nsIID &iid, PyXPCOM_TypeObject *this_type) 135 #endif 136 { 137 #ifndef Py_LIMITED_API 133 138 ob_type = this_type; 139 #else 140 ob_type = this_type->m_pTypeObj; 141 m_pMyTypeObj = this_type; 142 #endif 134 143 m_obj = punk; 135 144 m_iid = iid; … … 217 226 return ret; 218 227 } 228 #ifndef Py_LIMITED_API 219 229 PyXPCOM_TypeObject *this_type = (PyXPCOM_TypeObject *)ob_type; 230 #else 231 PyXPCOM_TypeObject *this_type = m_pMyTypeObj; 232 #endif 220 233 #if PY_MAJOR_VERSION <= 2 221 234 return Py_FindMethodInChain(&this_type->chain, this, (char *)name); … … 223 236 PyMethodChain *chain = &this_type->chain; 224 237 if (name[0] == '_' && name[1] == '_') { 238 # ifndef Py_LIMITED_API /** @todo ? */ 225 239 if (!strcmp(name, "__doc__")) { 226 240 const char *doc = ob_type->tp_doc; … … 228 242 return PyUnicode_FromString(doc); 229 243 } 244 # endif 230 245 } 231 246 while (chain) { … … 247 262 char buf[128]; 248 263 #ifdef VBOX 249 snprintf(buf, sizeof(buf), "%s has read-only attributes", ob_type->tp_name);250 #else 251 sprintf(buf, "%s has read-only attributes", ob_type->tp_name);264 snprintf(buf, sizeof(buf), "%s has read-only attributes", PyXPCOM_ObTypeName(this) ); 265 #else 266 sprintf(buf, "%s has read-only attributes", PyXPCOM_ObTypeName(this) ); 252 267 #endif 253 268 PyErr_SetString(PyExc_TypeError, buf); … … 272 287 if ( !Check(ob) ) 273 288 { 274 PyErr_Format(PyExc_TypeError, "Objects of type '%s' can not be used as COM objects", ob->ob_type->tp_name);289 PyErr_Format(PyExc_TypeError, "Objects of type '%s' can not be used as COM objects", PyXPCOM_ObTypeName(ob)); 275 290 goto done; 276 291 } … … 390 405 // Interface conversions 391 406 /*static*/void 407 #ifndef Py_LIMITED_API 392 408 Py_nsISupports::RegisterInterface( const nsIID &iid, PyTypeObject *t) 409 #else 410 Py_nsISupports::RegisterInterface( const nsIID &iid, PyXPCOM_TypeObject *t) 411 #endif 393 412 { 394 413 if (mapIIDToType==NULL) … … 426 445 } 427 446 447 #ifndef Py_LIMITED_API 428 448 PyTypeObject *createType = NULL; 449 #else 450 PyXPCOM_TypeObject *createType = NULL; 451 #endif 429 452 // If the IID is for nsISupports, dont bother with 430 453 // a map lookup as we know the type! … … 435 458 436 459 if (mapIIDToType != NULL) 460 #ifndef Py_LIMITED_API 437 461 createType = (PyTypeObject *)PyDict_GetItem(mapIIDToType, obiid); 462 #else 463 createType = (PyXPCOM_TypeObject *)PyDict_GetItem(mapIIDToType, obiid); 464 #endif 438 465 Py_DECREF(obiid); 439 466 } 440 467 if (createType==NULL) 441 468 createType = Py_nsISupports::type; 469 #ifndef Py_LIMITED_API 442 470 // Check it is indeed one of our types. 443 471 if (!PyXPCOM_TypeObject::IsType(createType)) { … … 447 475 // we can now safely cast the thing to a PyComTypeObject and use it 448 476 PyXPCOM_TypeObject *myCreateType = (PyXPCOM_TypeObject *)createType; 477 #else /* Since the mapIIDToType is only updated by us, there should be no need for the above. */ 478 PyXPCOM_TypeObject * const myCreateType = createType; 479 #endif 449 480 if (myCreateType->ctor==NULL) { 450 481 PyErr_SetString(PyExc_TypeError, "The type does not declare a PyCom constructor"); -
trunk/src/libs/xpcom18a4/python/src/PyXPCOM.h
r64330 r86333 166 166 class Py_nsISupports; 167 167 168 169 /** @name VBox limited API hacks: 170 * @{ */ 171 #ifndef Py_LIMITED_API 172 173 # define PyXPCOM_ObTypeName(obj) (Py_TYPE(obj)->tp_name) 174 175 #else /* Py_LIMITED_API */ 176 177 const char *PyXPCOMGetObTypeName(PyTypeObject *pTypeObj); 178 # define PyXPCOM_ObTypeName(obj) PyXPCOMGetObTypeName(Py_TYPE(obj)) 179 180 /** @todo shouldn't be using PyUnicode_AsUTF8 from cpython/unicodeobject.h! */ 181 # undef PyUnicode_AsUTF8 182 extern "C" PyAPI_FUNC(const char *) PyUnicode_AsUTF8(PyObject *); 183 184 /** @todo shouldn't be using PyUnicode_AsUTF8AndSize from cpython/unicodeobject.h! */ 185 # undef PyUnicode_AsUTF8AndSize 186 extern "C" PyAPI_FUNC(const char *) PyUnicode_AsUTF8AndSize(PyObject *, Py_ssize_t *); 187 188 DECLINLINE(int) PyRun_SimpleString(const char *pszCode) 189 { 190 /* Get the main mode dictionary: */ 191 PyObject *pMainMod = PyImport_AddModule("__main__"); 192 if (pMainMod) { 193 PyObject *pMainModDict = PyModule_GetDict(pMainMod); 194 195 /* Compile and run the code. */ 196 PyObject *pCodeObject = Py_CompileString(pszCode, "PyXPCOM", Py_file_input); 197 if (pCodeObject) { 198 PyObject *pResult = PyEval_EvalCode(pCodeObject, pMainModDict, pMainModDict); 199 Py_DECREF(pCodeObject); 200 if (pResult) { 201 Py_DECREF(pResult); 202 return 0; 203 } 204 PyErr_Print(); 205 } 206 } 207 return -1; 208 } 209 210 DECLINLINE(PyObject *) PyTuple_GET_ITEM(PyObject *pTuple, Py_ssize_t idx) 211 { 212 return PyTuple_GetItem(pTuple, idx); 213 } 214 215 DECLINLINE(int) PyTuple_SET_ITEM(PyObject *pTuple, Py_ssize_t idx, PyObject *pItem) 216 { 217 int rc = PyTuple_SetItem(pTuple, idx, pItem); /* Steals pItem ref, just like PyTuple_SET_ITEM. */ 218 Assert(rc == 0); 219 return rc; 220 } 221 222 DECLINLINE(int) PyList_SET_ITEM(PyObject *pList, Py_ssize_t idx, PyObject *pItem) 223 { 224 int rc = PyList_SetItem(pList, idx, pItem); /* Steals pItem ref, just like PyList_SET_ITEM. */ 225 Assert(rc == 0); 226 return rc; 227 } 228 229 DECLINLINE(Py_ssize_t) PyBytes_GET_SIZE(PyObject *pBytes) 230 { 231 return PyBytes_Size(pBytes); 232 } 233 234 DECLINLINE(const char *) PyBytes_AS_STRING(PyObject *pBytes) 235 { 236 return PyBytes_AsString(pBytes); 237 } 238 239 DECLINLINE(Py_ssize_t) PyUnicode_GET_SIZE(PyObject *pUnicode) 240 { 241 /* Note! Currently only used for testing for zero or 1 codepoints, so we don't 242 really need to deal with the different way these two treats surrogate pairs. */ 243 # if Py_LIMITED_API >= 0x03030000 244 return PyUnicode_GetLength(pUnicode); 245 # else 246 return PyUnicode_GetSize(pUnicode); 247 # endif 248 } 249 250 # define PyObject_CheckBuffer(pAllegedBuffer) PyObject_CheckReadBuffer(pAllegedBuffer) 251 252 # include <iprt/asm.h> 253 DECLINLINE(Py_hash_t) _Py_HashPointer(void *p) 254 { 255 Py_hash_t uHash = (Py_hash_t)RT_CONCAT(ASMRotateRightU,ARCH_BITS)((uintptr_t)p, 4); 256 return uHash != -1 ? uHash : -2; 257 } 258 259 #endif /* Py_LIMITED_API */ 260 /** @} */ 261 262 168 263 /************************************************************************* 169 264 ************************************************************************** … … 264 359 // Base class for (most of) the type objects. 265 360 361 #ifndef Py_LIMITED_API 266 362 class PYXPCOM_EXPORT PyXPCOM_TypeObject : public PyTypeObject { 363 #else 364 class PYXPCOM_EXPORT PyXPCOM_TypeObject : public PyObject { 365 #endif 267 366 public: 268 367 PyXPCOM_TypeObject( … … 291 390 #else 292 391 static long Py_hash(PyObject *self); 392 #endif 393 #ifdef Py_LIMITED_API 394 PyTypeObject *m_pTypeObj; /**< The python type object we wrap. */ 293 395 #endif 294 396 }; … … 321 423 nsCOMPtr<nsISupports> m_obj; 322 424 nsIID m_iid; 425 #ifdef Py_LIMITED_API 426 /** Because PyXPCOM_TypeObject cannot inherit from PyTypeObject in 427 * Py_LIMITED_API mode, we cannot use ob_type to get to the method list. 428 * Instead of we store it here. */ 429 PyXPCOM_TypeObject *m_pMyTypeObj; 430 #endif 323 431 324 432 // Given an nsISupports and an Interface ID, create and return an object … … 370 478 static PyObject *mapIIDToType; 371 479 static void SafeRelease(Py_nsISupports *ob); 480 #ifndef Py_LIMITED_API 372 481 static void RegisterInterface( const nsIID &iid, PyTypeObject *t); 482 #else 483 static void RegisterInterface( const nsIID &iid, PyXPCOM_TypeObject *t); 484 #endif 373 485 static void InitType(); 374 486 #ifdef VBOX_DEBUG_LIFETIMES … … 393 505 Py_nsISupports(nsISupports *p, 394 506 const nsIID &iid, 507 #ifndef Py_LIMITED_API 395 508 PyTypeObject *type); 509 #else 510 PyXPCOM_TypeObject *type); 511 #endif 396 512 397 513 // Make a default wrapper for an ISupports (which is an … … 425 541 IsEqual(PyObject *ob) { 426 542 return ob && 543 #ifndef Py_LIMITED_API 427 544 ob->ob_type== &type && 545 #else 546 ob->ob_type == s_pType && 547 #endif 428 548 m_iid.Equals(((Py_nsIID *)ob)->m_iid); 429 549 } … … 454 574 static PyObject *PyTypeMethod_str(PyObject *self); 455 575 static void PyTypeMethod_dealloc(PyObject *self); 576 #ifndef Py_LIMITED_API 456 577 static NS_EXPORT_STATIC_MEMBER_(PyTypeObject) type; 578 #else 579 static NS_EXPORT_STATIC_MEMBER_(PyTypeObject *) s_pType; 580 static PyTypeObject *GetTypeObject(void); 581 #endif 457 582 static NS_EXPORT_STATIC_MEMBER_(PyMethodDef) methods[]; 458 583 }; … … 757 882 // See "pending calls" comment below. We reach into the Python 758 883 // implementation to see if we are the first call on the stack. 884 # ifndef Py_LIMITED_API 759 885 if (PyThreadState_Get()->gilstate_counter==1) { 886 # else 887 if (state == PyGILState_UNLOCKED) { 888 # endif 760 889 PyXPCOM_MakePendingCalls(); 761 890 } -
trunk/src/libs/xpcom18a4/python/src/TypeObject.cpp
r64330 r86333 52 52 53 53 54 #ifndef Py_LIMITED_API 54 55 static PyTypeObject PyInterfaceType_Type = { 55 56 PyVarObject_HEAD_INIT(&PyType_Type, 0) … … 76 77 }; 77 78 79 #else /* Py_LIMITED_API */ 80 81 /** The offset of PyTypeObject::ob_name. */ 82 static size_t g_offObTypeNameMember = sizeof(PyVarObject); 83 84 /** 85 * Base type object for XPCOM interfaces. Created dynamicially. 86 */ 87 static PyTypeObject *g_pPyInterfaceTypeObj = NULL; 88 89 /** 90 * Gets the base XPCOM interface type object, creating it if needed. 91 */ 92 static PyTypeObject *PyXPCOM_GetInterfaceType(void) 93 { 94 PyTypeObject *pTypeObj = g_pPyInterfaceTypeObj; 95 if (pTypeObj) 96 return pTypeObj; 97 98 static char g_szTypeDoc[] = "Define the behavior of a PythonCOM Interface type."; /* need non-const */ 99 PyType_Slot aTypeSlots[] = { 100 { Py_tp_doc, g_szTypeDoc }, 101 { 0, NULL } /* terminator */ 102 }; 103 PyType_Spec TypeSpec = { 104 /* .name: */ "interface-type", 105 /* .basicsize: */ 0, 106 /* .itemsize: */ 0, 107 /* .flags: */ Py_TPFLAGS_BASETYPE, 108 /* .slots: */ aTypeSlots, 109 }; 110 111 PyObject *exc_typ = NULL, *exc_val = NULL, *exc_tb = NULL; 112 PyErr_Fetch(&exc_typ, &exc_val, &exc_tb); /* goes south in PyType_Ready if we don't clear exceptions first. */ 113 114 pTypeObj = (PyTypeObject *)PyType_FromSpec(&TypeSpec); 115 assert(pTypeObj); 116 117 PyErr_Restore(exc_typ, exc_val, exc_tb); 118 g_pPyInterfaceTypeObj = pTypeObj; 119 120 /* 121 * Verify/correct g_offObTypeNameMember. 122 */ 123 /** @todo (could use pipe+read to safely probe memory) */ 124 125 return pTypeObj; 126 } 127 128 /** 129 * Get the PyTypeObject::ob_name value. 130 * 131 * @todo This is _horrible_, but there appears to be no simple tp_name getters 132 * till https://bugs.python.org/issue31497 (2017). 133 */ 134 const char *PyXPCOMGetObTypeName(PyTypeObject *pTypeObj) 135 { 136 return *(const char **)((uintptr_t)(pTypeObj) + g_offObTypeNameMember); 137 } 138 139 #endif /* Py_LIMITED_API */ 140 78 141 /*static*/ PRBool 79 142 PyXPCOM_TypeObject::IsType(PyTypeObject *t) … … 81 144 #if PY_MAJOR_VERSION <= 2 82 145 return t->ob_type == &PyInterfaceType_Type; 83 #el se146 #elif !defined(Py_LIMITED_API) 84 147 return Py_TYPE(t) == &PyInterfaceType_Type; 148 #else 149 return Py_TYPE(t) == g_pPyInterfaceTypeObj /* Typically not the case as t->ob_type is &PyType_Type */ 150 || PyType_IsSubtype(t, g_pPyInterfaceTypeObj); /* rather than g_pPyInterfaceTypeObj because of PyType_FromSpec(). */ 85 151 #endif 86 152 } … … 241 307 PyXPCOM_TypeObject::PyXPCOM_TypeObject( const char *name, PyXPCOM_TypeObject *pBase, int typeSize, struct PyMethodDef* methodList, PyXPCOM_I_CTOR thector) 242 308 { 309 #ifndef Py_LIMITED_API 243 310 static const PyTypeObject type_template = { 244 311 PyVarObject_HEAD_INIT(&PyInterfaceType_Type, 0) … … 280 347 281 348 *((PyTypeObject *)this) = type_template; 349 #else /* Py_LIMITED_API */ 350 /* Create the type specs: */ 351 PyType_Slot aTypeSlots[] = { 352 { Py_tp_base, PyXPCOM_GetInterfaceType() }, 353 { Py_tp_dealloc, (void *)(uintptr_t)&PyXPCOM_TypeObject::Py_dealloc }, 354 { Py_tp_getattr, (void *)(uintptr_t)&PyXPCOM_TypeObject::Py_getattr }, 355 { Py_tp_setattr, (void *)(uintptr_t)&PyXPCOM_TypeObject::Py_setattr }, 356 { Py_tp_repr, (void *)(uintptr_t)&PyXPCOM_TypeObject::Py_repr }, 357 { Py_tp_hash, (void *)(uintptr_t)&PyXPCOM_TypeObject::Py_hash }, 358 { Py_tp_str, (void *)(uintptr_t)&PyXPCOM_TypeObject::Py_str }, 359 { Py_tp_richcompare, (void *)(uintptr_t)&PyXPCOM_TypeObject::Py_richcmp }, 360 { 0, NULL } /* terminator */ 361 }; 362 PyType_Spec TypeSpec = { 363 /* .name: */ name, 364 /* .basicsize: */ typeSize, 365 /* .itemsize: */ 0, 366 /* .flags: */ Py_TPFLAGS_BASETYPE /*?*/, 367 /* .slots: */ aTypeSlots, 368 }; 369 370 PyObject *exc_typ = NULL, *exc_val = NULL, *exc_tb = NULL; 371 PyErr_Fetch(&exc_typ, &exc_val, &exc_tb); /* goes south in PyType_Ready if we don't clear exceptions first. */ 372 373 m_pTypeObj = (PyTypeObject *)PyType_FromSpec(&TypeSpec); 374 assert(m_pTypeObj); 375 376 PyErr_Restore(exc_typ, exc_val, exc_tb); 377 378 /* Initialize the PyObject part - needed so we can keep instance in a PyDict: */ 379 ob_type = PyXPCOM_GetInterfaceType(); 380 _Py_NewReference(this); 381 382 #endif /* Py_LIMITED_API */ 282 383 283 384 chain.methods = methodList; … … 287 388 ctor = thector; 288 389 390 #ifndef Py_LIMITED_API 289 391 // cast away const, as Python doesnt use it. 290 392 tp_name = (char *)name; 291 393 tp_basicsize = typeSize; 394 #endif 292 395 } 293 396 … … 295 398 { 296 399 } 400 -
trunk/src/libs/xpcom18a4/python/src/VariantUtils.cpp
r86309 r86333 498 498 NS_ABORT_IF_FALSE(PyUnicode_Check(val_use), "PyUnicode_FromObject didnt return a Unicode object!"); 499 499 // Lossy! 500 #ifndef Py_LIMITED_API 500 501 FILL_SIMPLE_POINTER( PRUnichar, *PyUnicode_AS_UNICODE(val_use) ); 502 #else 503 FILL_SIMPLE_POINTER( PRUnichar, PyUnicode_ReadChar(val_use, 0) ); 504 #endif 501 505 break; 502 506 … … 833 837 #endif 834 838 nr = v->SetAsWStringWithSize(0, (PRUnichar*)NULL); 835 } else { 839 } 840 else { 836 841 PRUint32 nch; 837 842 PRUnichar *p; 838 843 if (PyUnicode_AsPRUnichar(ob, &p, &nch) < 0) { 839 PyXPCOM_LogWarning("Failed to convert object to unicode", ob->ob_type->tp_name);844 PyXPCOM_LogWarning("Failed to convert object to unicode", PyXPCOM_ObTypeName(ob)); 840 845 nr = NS_ERROR_UNEXPECTED; 841 846 break; … … 894 899 break; 895 900 case (PRUint16)-1: 896 PyXPCOM_LogWarning("Objects of type '%s' can not be converted to an nsIVariant", ob->ob_type->tp_name);901 PyXPCOM_LogWarning("Objects of type '%s' can not be converted to an nsIVariant", PyXPCOM_ObTypeName(ob)); 897 902 nr = NS_ERROR_UNEXPECTED; 898 903 default: 899 904 NS_ABORT_IF_FALSE(0, "BestVariantTypeForPyObject() returned a variant type not handled here!"); 900 PyXPCOM_LogWarning("Objects of type '%s' can not be converted to an nsIVariant", ob->ob_type->tp_name);905 PyXPCOM_LogWarning("Objects of type '%s' can not be converted to an nsIVariant", PyXPCOM_ObTypeName(ob)); 901 906 nr = NS_ERROR_UNEXPECTED; 902 907 } … … 1424 1429 } 1425 1430 1431 # ifndef Py_LIMITED_API 1426 1432 ns_v.val.c = *PyUnicode_AS_UNICODE(val_use); 1433 # else 1434 ns_v.val.c = PyUnicode_ReadChar(val_use, 0); 1435 # endif 1427 1436 #endif 1428 1437 break; … … 1450 1459 } 1451 1460 // Lossy! 1461 #ifndef Py_LIMITED_API 1452 1462 ns_v.val.wc = *PyUnicode_AS_UNICODE(val_use); 1463 #else 1464 ns_v.val.wc = PyUnicode_ReadChar(val_use, 0); 1465 #endif 1453 1466 break; 1454 1467 } … … 2568 2581 BREAK_FALSE; 2569 2582 } 2583 # ifndef Py_LIMITED_API 2570 2584 FILL_SIMPLE_POINTER( char, *PyUnicode_AS_UNICODE(val) ); 2585 # else 2586 FILL_SIMPLE_POINTER( char, PyUnicode_ReadChar(val, 0) ); 2587 # endif 2571 2588 #endif 2572 2589 break; … … 2588 2605 NS_ABORT_IF_FALSE(PyUnicode_Check(val_use), "PyUnicode_FromObject didnt return a Unicode object!"); 2589 2606 // Lossy! 2607 #ifndef Py_LIMITED_API 2590 2608 FILL_SIMPLE_POINTER( PRUnichar, *PyUnicode_AS_UNICODE(val_use) ); 2609 #else 2610 FILL_SIMPLE_POINTER( PRUnichar, PyUnicode_ReadChar(val_use, 0) ); 2611 #endif 2591 2612 break; 2592 2613 … … 2931 2952 if (val != Py_None) { 2932 2953 if (!PySequence_Check(val)) { 2933 PyErr_Format(PyExc_TypeError, "Object for xpcom array must be a sequence, not type '%s'", val->ob_type->tp_name);2954 PyErr_Format(PyExc_TypeError, "Object for xpcom array must be a sequence, not type '%s'", PyXPCOM_ObTypeName(val)); 2934 2955 BREAK_FALSE; 2935 2956 } -
trunk/src/libs/xpcom18a4/python/src/module/_xpcom.cpp
r69588 r86333 132 132 # endif 133 133 # else 134 # define MODULE_NAME MANGLE_MODULE_NAME("VBoxPython")135 134 # if PY_MAJOR_VERSION <= 2 136 # define initVBoxPython MANGLE_MODULE_INIT(initVBoxPython) 135 # define MODULE_NAME MANGLE_MODULE_NAME("VBoxPython") 136 # define initVBoxPython MANGLE_MODULE_INIT(initVBoxPython) 137 # elif defined(Py_LIMITED_API) 138 # define MODULE_NAME MANGLE_MODULE_NAME("VBoxPython3") 139 # define initVBoxPython MANGLE_MODULE_INIT(PyInit_VBoxPython3) 137 140 # else 138 # define initVBoxPython MANGLE_MODULE_INIT(PyInit_VBoxPython) 141 # define MODULE_NAME MANGLE_MODULE_NAME("VBoxPython") 142 # define initVBoxPython MANGLE_MODULE_INIT(PyInit_VBoxPython) 139 143 # endif 140 144 # endif … … 271 275 return PyErr_Format(PyExc_TypeError, 272 276 "First param must be a native nsISupports wrapper (got %s)", 273 obIS->ob_type->tp_name);277 PyXPCOM_ObTypeName(obIS)); 274 278 } 275 279 // Ack! We must ask for the "native" interface supported by … … 497 501 return PyErr_Format(PyExc_ValueError, 498 502 "Object is not an nsIVariant (got %s)", 499 ob->ob_type->tp_name);503 PyXPCOM_ObTypeName(ob)); 500 504 501 505 Py_nsISupports *parent = nsnull; … … 809 813 #endif 810 814 } 815 #ifndef Py_LIMITED_API 811 816 PyDict_SetItemString(dict, "IIDType", (PyObject *)&Py_nsIID::type); 817 #else 818 PyDict_SetItemString(dict, "IIDType", (PyObject *)Py_nsIID::GetTypeObject()); 819 #endif 812 820 813 821 REGISTER_IID(nsISupports);
Note:
See TracChangeset
for help on using the changeset viewer.