From 90c363d46f0eb30bcb9041c262c9b7985ffc5a65 Mon Sep 17 00:00:00 2001 From: Irit Katriel Date: Wed, 1 Feb 2023 22:56:17 +0000 Subject: [PATCH 1/2] RERAISE --- Python/bytecodes.c | 16 ++++++++-------- Python/generated_cases.c.h | 16 ++++++++++------ Python/opcode_metadata.h | 4 ++-- 3 files changed, 20 insertions(+), 16 deletions(-) diff --git a/Python/bytecodes.c b/Python/bytecodes.c index 105bd95be0fdc3..382f524c54537d 100644 --- a/Python/bytecodes.c +++ b/Python/bytecodes.c @@ -739,10 +739,10 @@ dummy_func( Py_XSETREF(exc_info->exc_value, exc_value); } - // stack effect: (__0 -- ) - inst(RERAISE) { + inst(RERAISE, (values[oparg], exc -- values[oparg])) { + assert(oparg >= 0 && oparg <= 2); if (oparg) { - PyObject *lasti = PEEK(oparg + 1); + PyObject *lasti = values[0]; if (PyLong_Check(lasti)) { frame->prev_instr = _PyCode_CODE(frame->f_code) + PyLong_AsLong(lasti); assert(!_PyErr_Occurred(tstate)); @@ -753,11 +753,11 @@ dummy_func( goto error; } } - PyObject *val = POP(); - assert(val && PyExceptionInstance_Check(val)); - PyObject *exc = Py_NewRef(PyExceptionInstance_Class(val)); - PyObject *tb = PyException_GetTraceback(val); - _PyErr_Restore(tstate, exc, val, tb); + assert(exc && PyExceptionInstance_Check(exc)); + Py_INCREF(exc); + PyObject *typ = Py_NewRef(PyExceptionInstance_Class(exc)); + PyObject *tb = PyException_GetTraceback(exc); + _PyErr_Restore(tstate, typ, exc, tb); goto exception_unwind; } diff --git a/Python/generated_cases.c.h b/Python/generated_cases.c.h index a02d8d79c60d37..7271e22cfe7682 100644 --- a/Python/generated_cases.c.h +++ b/Python/generated_cases.c.h @@ -945,8 +945,11 @@ } TARGET(RERAISE) { + PyObject *exc = PEEK(1); + PyObject **values = &PEEK(1 + oparg); + assert(oparg >= 0 && oparg <= 2); if (oparg) { - PyObject *lasti = PEEK(oparg + 1); + PyObject *lasti = values[0]; if (PyLong_Check(lasti)) { frame->prev_instr = _PyCode_CODE(frame->f_code) + PyLong_AsLong(lasti); assert(!_PyErr_Occurred(tstate)); @@ -957,11 +960,12 @@ goto error; } } - PyObject *val = POP(); - assert(val && PyExceptionInstance_Check(val)); - PyObject *exc = Py_NewRef(PyExceptionInstance_Class(val)); - PyObject *tb = PyException_GetTraceback(val); - _PyErr_Restore(tstate, exc, val, tb); + // PyObject *exc = Py_NewRef(values[oparg]); + assert(exc && PyExceptionInstance_Check(exc)); + Py_INCREF(exc); + PyObject *typ = Py_NewRef(PyExceptionInstance_Class(exc)); + PyObject *tb = PyException_GetTraceback(exc); + _PyErr_Restore(tstate, typ, exc, tb); goto exception_unwind; } diff --git a/Python/opcode_metadata.h b/Python/opcode_metadata.h index c9f9759e16b316..0af9fdd7ed4fda 100644 --- a/Python/opcode_metadata.h +++ b/Python/opcode_metadata.h @@ -105,7 +105,7 @@ _PyOpcode_num_popped(int opcode, int oparg, bool jump) { case POP_EXCEPT: return 1; case RERAISE: - return -1; + return oparg + 1; case PREP_RERAISE_STAR: return 2; case END_ASYNC_FOR: @@ -451,7 +451,7 @@ _PyOpcode_num_pushed(int opcode, int oparg, bool jump) { case POP_EXCEPT: return 0; case RERAISE: - return -1; + return oparg; case PREP_RERAISE_STAR: return 1; case END_ASYNC_FOR: From c861af52e1e26dffd3d7b227e2cb1d047a35e918 Mon Sep 17 00:00:00 2001 From: Irit Katriel Date: Wed, 1 Feb 2023 23:14:11 +0000 Subject: [PATCH 2/2] CLEANUP_THROW --- Python/bytecodes.c | 12 +++--------- Python/generated_cases.c.h | 18 ++++++++++-------- Python/opcode_metadata.h | 4 ++-- 3 files changed, 15 insertions(+), 19 deletions(-) diff --git a/Python/bytecodes.c b/Python/bytecodes.c index 382f524c54537d..6ebb5e945ce0e8 100644 --- a/Python/bytecodes.c +++ b/Python/bytecodes.c @@ -784,18 +784,12 @@ dummy_func( } } - // stack effect: (__0, __1 -- ) - inst(CLEANUP_THROW) { + inst(CLEANUP_THROW, (sub_iter, last_sent_val, exc_value -- value)) { assert(throwflag); - PyObject *exc_value = TOP(); assert(exc_value && PyExceptionInstance_Check(exc_value)); if (PyErr_GivenExceptionMatches(exc_value, PyExc_StopIteration)) { - PyObject *value = ((PyStopIterationObject *)exc_value)->value; - Py_INCREF(value); - Py_DECREF(POP()); // The StopIteration. - Py_DECREF(POP()); // The last sent value. - Py_DECREF(POP()); // The delegated sub-iterator. - PUSH(value); + value = Py_NewRef(((PyStopIterationObject *)exc_value)->value); + DECREF_INPUTS(); } else { PyObject *exc_type = Py_NewRef(Py_TYPE(exc_value)); diff --git a/Python/generated_cases.c.h b/Python/generated_cases.c.h index 7271e22cfe7682..f60af7c65ea00d 100644 --- a/Python/generated_cases.c.h +++ b/Python/generated_cases.c.h @@ -960,7 +960,6 @@ goto error; } } - // PyObject *exc = Py_NewRef(values[oparg]); assert(exc && PyExceptionInstance_Check(exc)); Py_INCREF(exc); PyObject *typ = Py_NewRef(PyExceptionInstance_Class(exc)); @@ -1005,16 +1004,17 @@ } TARGET(CLEANUP_THROW) { + PyObject *exc_value = PEEK(1); + PyObject *last_sent_val = PEEK(2); + PyObject *sub_iter = PEEK(3); + PyObject *value; assert(throwflag); - PyObject *exc_value = TOP(); assert(exc_value && PyExceptionInstance_Check(exc_value)); if (PyErr_GivenExceptionMatches(exc_value, PyExc_StopIteration)) { - PyObject *value = ((PyStopIterationObject *)exc_value)->value; - Py_INCREF(value); - Py_DECREF(POP()); // The StopIteration. - Py_DECREF(POP()); // The last sent value. - Py_DECREF(POP()); // The delegated sub-iterator. - PUSH(value); + value = Py_NewRef(((PyStopIterationObject *)exc_value)->value); + Py_DECREF(sub_iter); + Py_DECREF(last_sent_val); + Py_DECREF(exc_value); } else { PyObject *exc_type = Py_NewRef(Py_TYPE(exc_value)); @@ -1022,6 +1022,8 @@ _PyErr_Restore(tstate, exc_type, Py_NewRef(exc_value), exc_traceback); goto exception_unwind; } + STACK_SHRINK(2); + POKE(1, value); DISPATCH(); } diff --git a/Python/opcode_metadata.h b/Python/opcode_metadata.h index 0af9fdd7ed4fda..f3bbb470079df1 100644 --- a/Python/opcode_metadata.h +++ b/Python/opcode_metadata.h @@ -111,7 +111,7 @@ _PyOpcode_num_popped(int opcode, int oparg, bool jump) { case END_ASYNC_FOR: return 2; case CLEANUP_THROW: - return -1; + return 3; case LOAD_ASSERTION_ERROR: return 0; case LOAD_BUILD_CLASS: @@ -457,7 +457,7 @@ _PyOpcode_num_pushed(int opcode, int oparg, bool jump) { case END_ASYNC_FOR: return 0; case CLEANUP_THROW: - return -1; + return 1; case LOAD_ASSERTION_ERROR: return 1; case LOAD_BUILD_CLASS: