aboutsummaryrefslogtreecommitdiffstats
path: root/sources/shiboken2/libshiboken/signature.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'sources/shiboken2/libshiboken/signature.cpp')
-rw-r--r--sources/shiboken2/libshiboken/signature.cpp212
1 files changed, 120 insertions, 92 deletions
diff --git a/sources/shiboken2/libshiboken/signature.cpp b/sources/shiboken2/libshiboken/signature.cpp
index a99927c15..dea4c9b09 100644
--- a/sources/shiboken2/libshiboken/signature.cpp
+++ b/sources/shiboken2/libshiboken/signature.cpp
@@ -418,75 +418,101 @@ GetSignature_Cached(PyObject *props, const char *sig_kind, const char *modifier)
return Py_INCREF(value), value;
}
-// const char *PySide_SignatureModule[] = {
-// #include "embed/signature.inc"
-// };
-
-static const char PySide_PythonCode[] =
- "from __future__ import print_function, absolute_import\n" R"~(if True:
-
- # This is becoming the 'signature_loader' module.
-
- import sys, os, traceback
- # We avoid imports in phase 1 that could fail. "import shiboken" of the
- # binary would even crash in FinishSignatureInitialization.
-
- def bootstrap():
- global __file__
- try:
- import shiboken2 as root
- except ImportError:
- # uninstalled case without ctest, try only this one which has __init__:
- import shibokenmodule as root
- rp = os.path.realpath(os.path.dirname(root.__file__))
- # This can be the shiboken2 directory or the binary module, so search.
- while len(rp) > 3 and not os.path.exists(os.path.join(rp, 'files.dir')):
- rp = os.path.abspath(os.path.join(rp, '..'))
- __file__ = os.path.join(rp, 'files.dir', 'shibokensupport', 'signature', 'loader.py')
- try:
- with open(__file__) as _f:
- exec(compile(_f.read(), __file__, 'exec'))
- except Exception as e:
- print('Exception:', e)
- traceback.print_exc(file=sys.stdout)
- globals().update(locals())
-
- )~";
+static const char *PySide_CompressedSignaturePackage[] = {
+#include "embed/signature.inc"
+ };
+
+static const unsigned char PySide_SignatureLoader[] = {
+#include "embed/signature_bootstrap.inc"
+ };
static safe_globals_struc *
init_phase_1(void)
{
- PyObject *d, *v;
- safe_globals_struc *p = (safe_globals_struc *)
- malloc(sizeof(safe_globals_struc));
- if (p == NULL)
- goto error;
- p->helper_module = PyImport_AddModule((char *) "signature_loader");
- if (p->helper_module == NULL)
- goto error;
-
- // Initialize the module
- d = PyModule_GetDict(p->helper_module);
- if (PyDict_SetItemString(d, "__builtins__", PyEval_GetBuiltins()) < 0)
- goto error;
- v = PyRun_String(PySide_PythonCode, Py_file_input, d, d);
- if (v == NULL)
- goto error;
- Py_DECREF(v);
-
- // build a dict for diverse mappings
- p->map_dict = PyDict_New();
- if (p->map_dict == NULL)
- goto error;
-
- // build a dict for the prepared arguments
- p->arg_dict = PyDict_New();
- if (p->arg_dict == NULL
- || PyObject_SetAttrString(p->helper_module, "pyside_arg_dict", p->arg_dict) < 0)
- goto error;
- return p;
+ {
+ safe_globals_struc *p = (safe_globals_struc *)
+ malloc(sizeof(safe_globals_struc));
+ if (p == NULL)
+ goto error;
+ /*
+ * Initializing module signature_bootstrap.
+ * Since we now have an embedding script, we can do this without any
+ * Python strings in the C code.
+ */
+#ifdef Py_LIMITED_API
+ // We must work for multiple versions, so use source code.
+#else
+ Shiboken::AutoDecRef marshal_str(Py_BuildValue("s", "marshal"));
+ if (marshal_str.isNull())
+ goto error;
+ Shiboken::AutoDecRef marshal_module(PyImport_Import(marshal_str));
+ if (marshal_module.isNull())
+ goto error;
+ Shiboken::AutoDecRef loads(PyObject_GetAttrString(marshal_module, "loads"));
+ if (loads.isNull())
+ goto error;
+#endif
+ char *bytes_cast = reinterpret_cast<char *>(
+ const_cast<unsigned char *>(PySide_SignatureLoader));
+ Shiboken::AutoDecRef bytes(PyBytes_FromStringAndSize(bytes_cast,
+ sizeof(PySide_SignatureLoader)));
+ if (bytes.isNull())
+ goto error;
+#ifdef Py_LIMITED_API
+ PyObject *builtins = PyEval_GetBuiltins();
+ PyObject *compile = PyDict_GetItemString(builtins, "compile");
+ if (compile == nullptr)
+ goto error;
+ Shiboken::AutoDecRef code_obj(PyObject_CallFunction(compile, "Oss",
+ bytes.object(), "(builtin)", "exec"));
+#else
+ Shiboken::AutoDecRef code_obj(PyObject_CallFunctionObjArgs(
+ loads, bytes.object(), nullptr));
+#endif
+ if (code_obj.isNull())
+ goto error;
+ p->helper_module = PyImport_ExecCodeModule(const_cast<char *>
+ ("signature_bootstrap"), code_obj);
+ if (p->helper_module == nullptr)
+ goto error;
+ // Initialize the module
+ PyObject *mdict = PyModule_GetDict(p->helper_module);
+ if (PyDict_SetItemString(mdict, "__builtins__", PyEval_GetBuiltins()) < 0)
+ goto error;
+ /*
+ * Unpack an embedded ZIP file with more signature modules.
+ * They will be loaded later with the zipimporter.
+ * Due to MSVC's limitation to 64k strings, we need to assemble pieces.
+ */
+ const char **block_ptr = (const char **)PySide_CompressedSignaturePackage;
+ int npieces = 0;
+ PyObject *piece, *zipped_string_sequence = PyList_New(0);
+ for (; **block_ptr != 0; ++block_ptr) {
+ npieces++;
+ // we avoid the string/unicode dilemma by not using PyString_XXX:
+ piece = Py_BuildValue("s", *block_ptr);
+ if (piece == NULL || PyList_Append(zipped_string_sequence, piece) < 0)
+ goto error;
+ }
+ if (PyDict_SetItemString(mdict, "zipstring_sequence", zipped_string_sequence) < 0)
+ goto error;
+ Py_DECREF(zipped_string_sequence);
+
+ // build a dict for diverse mappings
+ p->map_dict = PyDict_New();
+ if (p->map_dict == NULL)
+ goto error;
+
+ // build a dict for the prepared arguments
+ p->arg_dict = PyDict_New();
+ if (p->arg_dict == NULL
+ || PyObject_SetAttrString(p->helper_module, "pyside_arg_dict", p->arg_dict) < 0)
+ goto error;
+ return p;
+ }
error:
+ PyErr_Print();
PyErr_SetString(PyExc_SystemError, "could not initialize part 1");
return NULL;
}
@@ -494,38 +520,40 @@ error:
static int
init_phase_2(safe_globals_struc *p, PyMethodDef *methods)
{
- PyObject *bootstrap_func, *v = nullptr;
- PyMethodDef *ml;
-
- // The single function to be called, but maybe more to come.
- for (ml = methods; ml->ml_name != NULL; ml++) {
- v = PyCFunction_NewEx(ml, nullptr, nullptr);
- if (v == nullptr
- || PyObject_SetAttrString(p->helper_module, ml->ml_name, v) != 0)
+ {
+ PyMethodDef *ml;
+
+ // The single function to be called, but maybe more to come.
+ for (ml = methods; ml->ml_name != NULL; ml++) {
+ PyObject *v = PyCFunction_NewEx(ml, nullptr, nullptr);
+ if (v == nullptr
+ || PyObject_SetAttrString(p->helper_module, ml->ml_name, v) != 0)
+ goto error;
+ Py_DECREF(v);
+ }
+ PyObject *bootstrap_func = PyObject_GetAttrString(p->helper_module, "bootstrap");
+ if (bootstrap_func == NULL)
+ goto error;
+ // The return value of the bootstrap function is the loader module.
+ PyObject *loader = PyObject_CallFunction(bootstrap_func, (char *)"()");
+ if (loader == nullptr)
goto error;
- Py_DECREF(v);
+ // now the loader should be initialized
+ p->sigparse_func = PyObject_GetAttrString(loader, "pyside_type_init");
+ if (p->sigparse_func == NULL)
+ goto error;
+ p->createsig_func = PyObject_GetAttrString(loader, "create_signature");
+ if (p->createsig_func == NULL)
+ goto error;
+ p->seterror_argument_func = PyObject_GetAttrString(loader, "seterror_argument");
+ if (p->seterror_argument_func == NULL)
+ goto error;
+ p->make_helptext_func = PyObject_GetAttrString(loader, "make_helptext");
+ if (p->make_helptext_func == NULL)
+ goto error;
+ return 0;
}
- bootstrap_func = PyObject_GetAttrString(p->helper_module, "bootstrap");
- if (bootstrap_func == NULL
- || PyObject_CallFunction(bootstrap_func, (char *)"()") == NULL)
- goto error;
- // now the loader should be initialized
- p->sigparse_func = PyObject_GetAttrString(p->helper_module, "pyside_type_init");
- if (p->sigparse_func == NULL)
- goto error;
- p->createsig_func = PyObject_GetAttrString(p->helper_module, "create_signature");
- if (p->createsig_func == NULL)
- goto error;
- p->seterror_argument_func = PyObject_GetAttrString(p->helper_module, "seterror_argument");
- if (p->seterror_argument_func == NULL)
- goto error;
- p->make_helptext_func = PyObject_GetAttrString(p->helper_module, "make_helptext");
- if (p->make_helptext_func == NULL)
- goto error;
- return 0;
-
error:
- Py_XDECREF(v);
PyErr_Print();
PyErr_SetString(PyExc_SystemError, "could not initialize part 2");
return -1;