mirror of
https://github.com/python/cpython.git
synced 2025-07-08 03:45:36 +00:00
gh-132775: Add _PyFunction_GetXIData() (gh-133481)
This commit is contained in:
parent
121ed71f4e
commit
8cf4947b0f
5 changed files with 103 additions and 0 deletions
|
@ -10,6 +10,7 @@
|
|||
#include "pycore_initconfig.h" // _PyStatus_OK()
|
||||
#include "pycore_namespace.h" // _PyNamespace_New()
|
||||
#include "pycore_pythonrun.h" // _Py_SourceAsString()
|
||||
#include "pycore_setobject.h" // _PySet_NextEntry()
|
||||
#include "pycore_typeobject.h" // _PyStaticType_InitBuiltin()
|
||||
|
||||
|
||||
|
|
|
@ -677,6 +677,60 @@ _PyCode_GetXIData(PyThreadState *tstate, PyObject *obj, _PyXIData_t *xidata)
|
|||
return 0;
|
||||
}
|
||||
|
||||
// function
|
||||
|
||||
PyObject *
|
||||
_PyFunction_FromXIData(_PyXIData_t *xidata)
|
||||
{
|
||||
// For now "stateless" functions are the only ones we must accommodate.
|
||||
|
||||
PyObject *code = _PyMarshal_ReadObjectFromXIData(xidata);
|
||||
if (code == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
// Create a new function.
|
||||
assert(PyCode_Check(code));
|
||||
PyObject *globals = PyDict_New();
|
||||
if (globals == NULL) {
|
||||
Py_DECREF(code);
|
||||
return NULL;
|
||||
}
|
||||
PyObject *func = PyFunction_New(code, globals);
|
||||
Py_DECREF(code);
|
||||
Py_DECREF(globals);
|
||||
return func;
|
||||
}
|
||||
|
||||
int
|
||||
_PyFunction_GetXIData(PyThreadState *tstate, PyObject *func,
|
||||
_PyXIData_t *xidata)
|
||||
{
|
||||
if (!PyFunction_Check(func)) {
|
||||
const char *msg = "expected a function, got %R";
|
||||
format_notshareableerror(tstate, NULL, 0, msg, func);
|
||||
return -1;
|
||||
}
|
||||
if (_PyFunction_VerifyStateless(tstate, func) < 0) {
|
||||
PyObject *cause = _PyErr_GetRaisedException(tstate);
|
||||
assert(cause != NULL);
|
||||
const char *msg = "only stateless functions are shareable";
|
||||
set_notshareableerror(tstate, cause, 0, msg);
|
||||
Py_DECREF(cause);
|
||||
return -1;
|
||||
}
|
||||
PyObject *code = PyFunction_GET_CODE(func);
|
||||
|
||||
// Ideally code objects would be immortal and directly shareable.
|
||||
// In the meantime, we use marshal.
|
||||
if (_PyMarshal_GetXIData(tstate, code, xidata) < 0) {
|
||||
return -1;
|
||||
}
|
||||
// Replace _PyMarshal_ReadObjectFromXIData.
|
||||
// (_PyFunction_FromXIData() will call it.)
|
||||
_PyXIData_SET_NEW_OBJECT(xidata, _PyFunction_FromXIData);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
// registration
|
||||
|
||||
|
@ -717,4 +771,6 @@ _register_builtins_for_crossinterpreter_data(dlregistry_t *xidregistry)
|
|||
if (_xidregistry_add_type(xidregistry, &PyTuple_Type, _tuple_shared) != 0) {
|
||||
Py_FatalError("could not register tuple for cross-interpreter sharing");
|
||||
}
|
||||
|
||||
// For now, we do not register PyCode_Type or PyFunction_Type.
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue