summaryrefslogtreecommitdiffstats
path: root/Objects/codeobject.c
diff options
context:
space:
mode:
authorMark Shannon <mark@hotpy.org>2021-05-07 14:19:19 (GMT)
committerGitHub <noreply@github.com>2021-05-07 14:19:19 (GMT)
commitadcd2205565f91c6719f4141ab4e1da6d7086126 (patch)
tree0953b285944eccde57b05b8f3c7e30fb501a3d64 /Objects/codeobject.c
parentb32c8e97951db46484ba3b646b988bcdc4062199 (diff)
downloadcpython-adcd2205565f91c6719f4141ab4e1da6d7086126.zip
cpython-adcd2205565f91c6719f4141ab4e1da6d7086126.tar.gz
cpython-adcd2205565f91c6719f4141ab4e1da6d7086126.tar.bz2
bpo-40222: "Zero cost" exception handling (GH-25729)
"Zero cost" exception handling. * Uses a lookup table to determine how to handle exceptions. * Removes SETUP_FINALLY and POP_TOP block instructions, eliminating (most of) the runtime overhead of try statements. * Reduces the size of the frame object by about 60%.
Diffstat (limited to 'Objects/codeobject.c')
-rw-r--r--Objects/codeobject.c35
1 files changed, 23 insertions, 12 deletions
diff --git a/Objects/codeobject.c b/Objects/codeobject.c
index c76ac90..e981e39 100644
--- a/Objects/codeobject.c
+++ b/Objects/codeobject.c
@@ -119,7 +119,7 @@ PyCode_NewWithPosOnlyArgs(int argcount, int posonlyargcount, int kwonlyargcount,
PyObject *code, PyObject *consts, PyObject *names,
PyObject *varnames, PyObject *freevars, PyObject *cellvars,
PyObject *filename, PyObject *name, int firstlineno,
- PyObject *linetable)
+ PyObject *linetable, PyObject *exceptiontable)
{
PyCodeObject *co;
Py_ssize_t *cell2arg = NULL;
@@ -137,7 +137,8 @@ PyCode_NewWithPosOnlyArgs(int argcount, int posonlyargcount, int kwonlyargcount,
cellvars == NULL || !PyTuple_Check(cellvars) ||
name == NULL || !PyUnicode_Check(name) ||
filename == NULL || !PyUnicode_Check(filename) ||
- linetable == NULL || !PyBytes_Check(linetable)) {
+ linetable == NULL || !PyBytes_Check(linetable) ||
+ exceptiontable == NULL || !PyBytes_Check(exceptiontable)) {
PyErr_BadInternalCall();
return NULL;
}
@@ -260,6 +261,8 @@ PyCode_NewWithPosOnlyArgs(int argcount, int posonlyargcount, int kwonlyargcount,
co->co_firstlineno = firstlineno;
Py_INCREF(linetable);
co->co_linetable = linetable;
+ Py_INCREF(exceptiontable);
+ co->co_exceptiontable = exceptiontable;
co->co_zombieframe = NULL;
co->co_weakreflist = NULL;
co->co_extra = NULL;
@@ -277,12 +280,12 @@ PyCode_New(int argcount, int kwonlyargcount,
PyObject *code, PyObject *consts, PyObject *names,
PyObject *varnames, PyObject *freevars, PyObject *cellvars,
PyObject *filename, PyObject *name, int firstlineno,
- PyObject *linetable)
+ PyObject *linetable, PyObject *exceptiontable)
{
return PyCode_NewWithPosOnlyArgs(argcount, 0, kwonlyargcount, nlocals,
stacksize, flags, code, consts, names,
varnames, freevars, cellvars, filename,
- name, firstlineno, linetable);
+ name, firstlineno, linetable, exceptiontable);
}
int
@@ -369,7 +372,8 @@ PyCode_NewEmpty(const char *filename, const char *funcname, int firstlineno)
filename_ob, /* filename */
funcname_ob, /* name */
firstlineno, /* firstlineno */
- emptystring /* linetable */
+ emptystring, /* linetable */
+ emptystring /* exception table */
);
failed:
@@ -397,6 +401,7 @@ static PyMemberDef code_memberlist[] = {
{"co_name", T_OBJECT, OFF(co_name), READONLY},
{"co_firstlineno", T_INT, OFF(co_firstlineno), READONLY},
{"co_linetable", T_OBJECT, OFF(co_linetable), READONLY},
+ {"co_exceptiontable", T_OBJECT, OFF(co_exceptiontable), READONLY},
{NULL} /* Sentinel */
};
@@ -538,6 +543,7 @@ code.__new__ as code_new
name: unicode
firstlineno: int
linetable: object(subclass_of="&PyBytes_Type")
+ exceptiontable: object(subclass_of="&PyBytes_Type")
freevars: object(subclass_of="&PyTuple_Type", c_default="NULL") = ()
cellvars: object(subclass_of="&PyTuple_Type", c_default="NULL") = ()
/
@@ -550,9 +556,9 @@ code_new_impl(PyTypeObject *type, int argcount, int posonlyargcount,
int kwonlyargcount, int nlocals, int stacksize, int flags,
PyObject *code, PyObject *consts, PyObject *names,
PyObject *varnames, PyObject *filename, PyObject *name,
- int firstlineno, PyObject *linetable, PyObject *freevars,
- PyObject *cellvars)
-/*[clinic end generated code: output=42c1839b082ba293 input=0ec80da632b99f57]*/
+ int firstlineno, PyObject *linetable, PyObject *exceptiontable,
+ PyObject *freevars, PyObject *cellvars)
+/*[clinic end generated code: output=a3899259c3b4cace input=f823c686da4b3a03]*/
{
PyObject *co = NULL;
PyObject *ournames = NULL;
@@ -618,7 +624,9 @@ code_new_impl(PyTypeObject *type, int argcount, int posonlyargcount,
code, consts, ournames,
ourvarnames, ourfreevars,
ourcellvars, filename,
- name, firstlineno, linetable);
+ name, firstlineno, linetable,
+ exceptiontable
+ );
cleanup:
Py_XDECREF(ournames);
Py_XDECREF(ourvarnames);
@@ -663,6 +671,7 @@ code_dealloc(PyCodeObject *co)
Py_XDECREF(co->co_filename);
Py_XDECREF(co->co_name);
Py_XDECREF(co->co_linetable);
+ Py_XDECREF(co->co_exceptiontable);
if (co->co_cell2arg != NULL)
PyMem_Free(co->co_cell2arg);
if (co->co_zombieframe != NULL)
@@ -715,6 +724,7 @@ code.replace
co_filename: unicode(c_default="self->co_filename") = None
co_name: unicode(c_default="self->co_name") = None
co_linetable: PyBytesObject(c_default="(PyBytesObject *)self->co_linetable") = None
+ co_exceptiontable: PyBytesObject(c_default="(PyBytesObject *)self->co_exceptiontable") = None
Return a copy of the code object with new values for the specified fields.
[clinic start generated code]*/
@@ -727,8 +737,9 @@ code_replace_impl(PyCodeObject *self, int co_argcount,
PyObject *co_consts, PyObject *co_names,
PyObject *co_varnames, PyObject *co_freevars,
PyObject *co_cellvars, PyObject *co_filename,
- PyObject *co_name, PyBytesObject *co_linetable)
-/*[clinic end generated code: output=50d77e668d3b449b input=a5f997b173d7f636]*/
+ PyObject *co_name, PyBytesObject *co_linetable,
+ PyBytesObject *co_exceptiontable)
+/*[clinic end generated code: output=80957472b7f78ed6 input=38376b1193efbbae]*/
{
#define CHECK_INT_ARG(ARG) \
if (ARG < 0) { \
@@ -758,7 +769,7 @@ code_replace_impl(PyCodeObject *self, int co_argcount,
co_argcount, co_posonlyargcount, co_kwonlyargcount, co_nlocals,
co_stacksize, co_flags, (PyObject*)co_code, co_consts, co_names,
co_varnames, co_freevars, co_cellvars, co_filename, co_name,
- co_firstlineno, (PyObject*)co_linetable);
+ co_firstlineno, (PyObject*)co_linetable, (PyObject*)co_exceptiontable);
}
static PyObject *