diff options
author | Brandt Bucher <brandtbucher@microsoft.com> | 2022-11-10 16:46:56 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-11-10 16:46:56 (GMT) |
commit | 00ee6d506ec399d30687c6cb420c8b3e22664577 (patch) | |
tree | ef81acccc46d710c8661e1cb876507580845a942 /Python/bytecodes.c | |
parent | c41b13d39ccc2d6e239782de99ba8e3cdd061e5a (diff) | |
download | cpython-00ee6d506ec399d30687c6cb420c8b3e22664577.zip cpython-00ee6d506ec399d30687c6cb420c8b3e22664577.tar.gz cpython-00ee6d506ec399d30687c6cb420c8b3e22664577.tar.bz2 |
GH-99298: Don't perform jumps before error handling (GH-99299)
Diffstat (limited to 'Python/bytecodes.c')
-rw-r--r-- | Python/bytecodes.c | 34 |
1 files changed, 19 insertions, 15 deletions
diff --git a/Python/bytecodes.c b/Python/bytecodes.c index ed12b94..80f9b1e 100644 --- a/Python/bytecodes.c +++ b/Python/bytecodes.c @@ -1146,6 +1146,8 @@ dummy_func( PyObject *name = GETITEM(names, oparg); next_instr--; if (_Py_Specialize_StoreAttr(owner, next_instr, name)) { + // "undo" the rewind so end up in the correct handler: + next_instr++; goto error; } DISPATCH_SAME_OPARG(); @@ -1725,6 +1727,8 @@ dummy_func( PyObject *name = GETITEM(names, oparg>>1); next_instr--; if (_Py_Specialize_LoadAttr(owner, next_instr, name)) { + // "undo" the rewind so end up in the correct handler: + next_instr++; goto error; } DISPATCH_SAME_OPARG(); @@ -3113,7 +3117,6 @@ dummy_func( PyObject *callable = PEEK(2); DEOPT_IF(callable != (PyObject *)&PyUnicode_Type, CALL); STAT_INC(CALL, hit); - JUMPBY(INLINE_CACHE_ENTRIES_CALL); PyObject *arg = TOP(); PyObject *res = PyObject_Str(arg); Py_DECREF(arg); @@ -3123,6 +3126,7 @@ dummy_func( if (res == NULL) { goto error; } + JUMPBY(INLINE_CACHE_ENTRIES_CALL); CHECK_EVAL_BREAKER(); } @@ -3134,7 +3138,6 @@ dummy_func( PyObject *callable = PEEK(2); DEOPT_IF(callable != (PyObject *)&PyTuple_Type, CALL); STAT_INC(CALL, hit); - JUMPBY(INLINE_CACHE_ENTRIES_CALL); PyObject *arg = TOP(); PyObject *res = PySequence_Tuple(arg); Py_DECREF(arg); @@ -3144,6 +3147,7 @@ dummy_func( if (res == NULL) { goto error; } + JUMPBY(INLINE_CACHE_ENTRIES_CALL); CHECK_EVAL_BREAKER(); } @@ -3157,7 +3161,6 @@ dummy_func( PyTypeObject *tp = (PyTypeObject *)callable; DEOPT_IF(tp->tp_vectorcall == NULL, CALL); STAT_INC(CALL, hit); - JUMPBY(INLINE_CACHE_ENTRIES_CALL); STACK_SHRINK(total_args); PyObject *res = tp->tp_vectorcall((PyObject *)tp, stack_pointer, total_args-kwnames_len, kwnames); @@ -3172,6 +3175,7 @@ dummy_func( if (res == NULL) { goto error; } + JUMPBY(INLINE_CACHE_ENTRIES_CALL); CHECK_EVAL_BREAKER(); } @@ -3187,7 +3191,6 @@ dummy_func( DEOPT_IF(!PyCFunction_CheckExact(callable), CALL); DEOPT_IF(PyCFunction_GET_FLAGS(callable) != METH_O, CALL); STAT_INC(CALL, hit); - JUMPBY(INLINE_CACHE_ENTRIES_CALL); PyCFunction cfunc = PyCFunction_GET_FUNCTION(callable); // This is slower but CPython promises to check all non-vectorcall // function calls. @@ -3206,6 +3209,7 @@ dummy_func( if (res == NULL) { goto error; } + JUMPBY(INLINE_CACHE_ENTRIES_CALL); CHECK_EVAL_BREAKER(); } @@ -3221,7 +3225,6 @@ dummy_func( DEOPT_IF(PyCFunction_GET_FLAGS(callable) != METH_FASTCALL, CALL); STAT_INC(CALL, hit); - JUMPBY(INLINE_CACHE_ENTRIES_CALL); PyCFunction cfunc = PyCFunction_GET_FUNCTION(callable); STACK_SHRINK(total_args); /* res = func(self, args, nargs) */ @@ -3246,6 +3249,7 @@ dummy_func( */ goto error; } + JUMPBY(INLINE_CACHE_ENTRIES_CALL); CHECK_EVAL_BREAKER(); } @@ -3260,7 +3264,6 @@ dummy_func( DEOPT_IF(PyCFunction_GET_FLAGS(callable) != (METH_FASTCALL | METH_KEYWORDS), CALL); STAT_INC(CALL, hit); - JUMPBY(INLINE_CACHE_ENTRIES_CALL); STACK_SHRINK(total_args); /* res = func(self, args, nargs, kwnames) */ _PyCFunctionFastWithKeywords cfunc = @@ -3285,6 +3288,7 @@ dummy_func( if (res == NULL) { goto error; } + JUMPBY(INLINE_CACHE_ENTRIES_CALL); CHECK_EVAL_BREAKER(); } @@ -3300,7 +3304,6 @@ dummy_func( PyInterpreterState *interp = _PyInterpreterState_GET(); DEOPT_IF(callable != interp->callable_cache.len, CALL); STAT_INC(CALL, hit); - JUMPBY(INLINE_CACHE_ENTRIES_CALL); PyObject *arg = TOP(); Py_ssize_t len_i = PyObject_Length(arg); if (len_i < 0) { @@ -3316,6 +3319,7 @@ dummy_func( if (res == NULL) { goto error; } + JUMPBY(INLINE_CACHE_ENTRIES_CALL); } // stack effect: (__0, __array[oparg] -- ) @@ -3330,7 +3334,6 @@ dummy_func( PyInterpreterState *interp = _PyInterpreterState_GET(); DEOPT_IF(callable != interp->callable_cache.isinstance, CALL); STAT_INC(CALL, hit); - JUMPBY(INLINE_CACHE_ENTRIES_CALL); PyObject *cls = POP(); PyObject *inst = TOP(); int retval = PyObject_IsInstance(inst, cls); @@ -3349,6 +3352,7 @@ dummy_func( if (res == NULL) { goto error; } + JUMPBY(INLINE_CACHE_ENTRIES_CALL); } // stack effect: (__0, __array[oparg] -- ) @@ -3362,9 +3366,6 @@ dummy_func( PyObject *list = SECOND(); DEOPT_IF(!PyList_Check(list), CALL); STAT_INC(CALL, hit); - // CALL + POP_TOP - JUMPBY(INLINE_CACHE_ENTRIES_CALL + 1); - assert(_Py_OPCODE(next_instr[-1]) == POP_TOP); PyObject *arg = POP(); if (_PyList_AppendTakeRef((PyListObject *)list, arg) < 0) { goto error; @@ -3372,6 +3373,9 @@ dummy_func( STACK_SHRINK(2); Py_DECREF(list); Py_DECREF(callable); + // CALL + POP_TOP + JUMPBY(INLINE_CACHE_ENTRIES_CALL + 1); + assert(_Py_OPCODE(next_instr[-1]) == POP_TOP); } // stack effect: (__0, __array[oparg] -- ) @@ -3389,7 +3393,6 @@ dummy_func( PyObject *self = SECOND(); DEOPT_IF(!Py_IS_TYPE(self, callable->d_common.d_type), CALL); STAT_INC(CALL, hit); - JUMPBY(INLINE_CACHE_ENTRIES_CALL); PyCFunction cfunc = meth->ml_meth; // This is slower but CPython promises to check all non-vectorcall // function calls. @@ -3407,6 +3410,7 @@ dummy_func( if (res == NULL) { goto error; } + JUMPBY(INLINE_CACHE_ENTRIES_CALL); CHECK_EVAL_BREAKER(); } @@ -3423,7 +3427,6 @@ dummy_func( PyObject *self = PEEK(total_args); DEOPT_IF(!Py_IS_TYPE(self, d_type), CALL); STAT_INC(CALL, hit); - JUMPBY(INLINE_CACHE_ENTRIES_CALL); int nargs = total_args-1; STACK_SHRINK(nargs); _PyCFunctionFastWithKeywords cfunc = @@ -3444,6 +3447,7 @@ dummy_func( if (res == NULL) { goto error; } + JUMPBY(INLINE_CACHE_ENTRIES_CALL); CHECK_EVAL_BREAKER(); } @@ -3461,7 +3465,6 @@ dummy_func( DEOPT_IF(!Py_IS_TYPE(self, callable->d_common.d_type), CALL); DEOPT_IF(meth->ml_flags != METH_NOARGS, CALL); STAT_INC(CALL, hit); - JUMPBY(INLINE_CACHE_ENTRIES_CALL); PyCFunction cfunc = meth->ml_meth; // This is slower but CPython promises to check all non-vectorcall // function calls. @@ -3478,6 +3481,7 @@ dummy_func( if (res == NULL) { goto error; } + JUMPBY(INLINE_CACHE_ENTRIES_CALL); CHECK_EVAL_BREAKER(); } @@ -3495,7 +3499,6 @@ dummy_func( PyObject *self = PEEK(total_args); DEOPT_IF(!Py_IS_TYPE(self, callable->d_common.d_type), CALL); STAT_INC(CALL, hit); - JUMPBY(INLINE_CACHE_ENTRIES_CALL); _PyCFunctionFast cfunc = (_PyCFunctionFast)(void(*)(void))meth->ml_meth; int nargs = total_args-1; @@ -3513,6 +3516,7 @@ dummy_func( if (res == NULL) { goto error; } + JUMPBY(INLINE_CACHE_ENTRIES_CALL); CHECK_EVAL_BREAKER(); } |