From 0675b8f032c69d265468b31d5cadac6a7ce4bd9c Mon Sep 17 00:00:00 2001 From: Irit Katriel <1055913+iritkatriel@users.noreply.github.com> Date: Thu, 2 Feb 2023 10:02:57 +0000 Subject: gh-98831: rewrite RERAISE and CLEANUP_THROW in the instruction definition DSL (#101511) --- Python/bytecodes.c | 28 +++++++++++----------------- Python/generated_cases.c.h | 32 +++++++++++++++++++------------- Python/opcode_metadata.h | 8 ++++---- 3 files changed, 34 insertions(+), 34 deletions(-) diff --git a/Python/bytecodes.c b/Python/bytecodes.c index fb41c83..169a264 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; } @@ -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 77f9b00..9726386 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,11 @@ 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; } @@ -1001,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)); @@ -1018,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 f0bdede..ca3dde3 100644 --- a/Python/opcode_metadata.h +++ b/Python/opcode_metadata.h @@ -105,13 +105,13 @@ _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: return 2; case CLEANUP_THROW: - return -1; + return 3; case LOAD_ASSERTION_ERROR: return 0; case LOAD_BUILD_CLASS: @@ -451,13 +451,13 @@ _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: return 0; case CLEANUP_THROW: - return -1; + return 1; case LOAD_ASSERTION_ERROR: return 1; case LOAD_BUILD_CLASS: -- cgit v0.12