diff options
author | Mark Shannon <mark@hotpy.org> | 2021-05-07 14:19:19 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-05-07 14:19:19 (GMT) |
commit | adcd2205565f91c6719f4141ab4e1da6d7086126 (patch) | |
tree | 0953b285944eccde57b05b8f3c7e30fb501a3d64 /Objects/codeobject.c | |
parent | b32c8e97951db46484ba3b646b988bcdc4062199 (diff) | |
download | cpython-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.c | 35 |
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 * |