summaryrefslogtreecommitdiff
path: root/Objects/codeobject.c
diff options
context:
space:
mode:
authorMark Shannon <mark@hotpy.org>2022-11-10 04:34:57 -0800
committerGitHub <noreply@github.com>2022-11-10 12:34:57 +0000
commit1e197e63e21f77b102ff2601a549dda4b6439455 (patch)
tree5d8524091404607c838bb9a0ea168c8d9c28fd6a /Objects/codeobject.c
parentdbf2faf579b4094387d65ee41f049456ca67c446 (diff)
downloadcpython-git-1e197e63e21f77b102ff2601a549dda4b6439455.tar.gz
GH-96421: Insert shim frame on entry to interpreter (GH-96319)
* Adds EXIT_INTERPRETER instruction to exit PyEval_EvalDefault() * Simplifies RETURN_VALUE, YIELD_VALUE and RETURN_GENERATOR instructions as they no longer need to check for entry frames.
Diffstat (limited to 'Objects/codeobject.c')
-rw-r--r--Objects/codeobject.c75
1 files changed, 75 insertions, 0 deletions
diff --git a/Objects/codeobject.c b/Objects/codeobject.c
index 854611ff85..3824fc0f5a 100644
--- a/Objects/codeobject.c
+++ b/Objects/codeobject.c
@@ -2264,3 +2264,78 @@ _PyStaticCode_Init(PyCodeObject *co)
_PyCode_Quicken(co);
return 0;
}
+
+#define MAX_CODE_UNITS_PER_LOC_ENTRY 8
+
+PyCodeObject *
+_Py_MakeShimCode(const _PyShimCodeDef *codedef)
+{
+ PyObject *name = NULL;
+ PyObject *co_code = NULL;
+ PyObject *lines = NULL;
+ PyCodeObject *codeobj = NULL;
+ uint8_t *loc_table = NULL;
+
+ name = _PyUnicode_FromASCII(codedef->cname, strlen(codedef->cname));
+ if (name == NULL) {
+ goto cleanup;
+ }
+ co_code = PyBytes_FromStringAndSize(
+ (const char *)codedef->code, codedef->codelen);
+ if (co_code == NULL) {
+ goto cleanup;
+ }
+ int code_units = codedef->codelen / sizeof(_Py_CODEUNIT);
+ int loc_entries = (code_units + MAX_CODE_UNITS_PER_LOC_ENTRY - 1) /
+ MAX_CODE_UNITS_PER_LOC_ENTRY;
+ loc_table = PyMem_Malloc(loc_entries);
+ if (loc_table == NULL) {
+ PyErr_NoMemory();
+ goto cleanup;
+ }
+ for (int i = 0; i < loc_entries-1; i++) {
+ loc_table[i] = 0x80 | (PY_CODE_LOCATION_INFO_NONE << 3) | 7;
+ code_units -= MAX_CODE_UNITS_PER_LOC_ENTRY;
+ }
+ assert(loc_entries > 0);
+ assert(code_units > 0 && code_units <= MAX_CODE_UNITS_PER_LOC_ENTRY);
+ loc_table[loc_entries-1] = 0x80 |
+ (PY_CODE_LOCATION_INFO_NONE << 3) | (code_units-1);
+ lines = PyBytes_FromStringAndSize((const char *)loc_table, loc_entries);
+ PyMem_Free(loc_table);
+ if (lines == NULL) {
+ goto cleanup;
+ }
+ _Py_DECLARE_STR(shim_name, "<shim>");
+ struct _PyCodeConstructor con = {
+ .filename = &_Py_STR(shim_name),
+ .name = name,
+ .qualname = name,
+ .flags = CO_NEWLOCALS | CO_OPTIMIZED,
+
+ .code = co_code,
+ .firstlineno = 1,
+ .linetable = lines,
+
+ .consts = (PyObject *)&_Py_SINGLETON(tuple_empty),
+ .names = (PyObject *)&_Py_SINGLETON(tuple_empty),
+
+ .localsplusnames = (PyObject *)&_Py_SINGLETON(tuple_empty),
+ .localspluskinds = (PyObject *)&_Py_SINGLETON(bytes_empty),
+
+ .argcount = 0,
+ .posonlyargcount = 0,
+ .kwonlyargcount = 0,
+
+ .stacksize = codedef->stacksize,
+
+ .exceptiontable = (PyObject *)&_Py_SINGLETON(bytes_empty),
+ };
+
+ codeobj = _PyCode_New(&con);
+cleanup:
+ Py_XDECREF(name);
+ Py_XDECREF(co_code);
+ Py_XDECREF(lines);
+ return codeobj;
+}