diff options
author | Mark Shannon <mark@hotpy.org> | 2024-08-06 07:40:39 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-08-06 07:40:39 (GMT) |
commit | a8be8fc6c4682089be45a87bd5ee1f686040116c (patch) | |
tree | 6729d2074c54a0fed44839c76b1a8fed27caf973 /Python | |
parent | b72c748d7fb4ecc0bc4626c7bc05fbc6c83f0ba8 (diff) | |
download | cpython-a8be8fc6c4682089be45a87bd5ee1f686040116c.zip cpython-a8be8fc6c4682089be45a87bd5ee1f686040116c.tar.gz cpython-a8be8fc6c4682089be45a87bd5ee1f686040116c.tar.bz2 |
GH-120024: Refactor code a bit so that escaping calls can be wrapped in spill code in code generator (GH-122693)
Diffstat (limited to 'Python')
-rw-r--r-- | Python/bytecodes.c | 50 | ||||
-rw-r--r-- | Python/executor_cases.c.h | 24 | ||||
-rw-r--r-- | Python/generated_cases.c.h | 46 |
3 files changed, 78 insertions, 42 deletions
diff --git a/Python/bytecodes.c b/Python/bytecodes.c index 996f997..a8527fe 100644 --- a/Python/bytecodes.c +++ b/Python/bytecodes.c @@ -287,7 +287,8 @@ dummy_func( /* Need to create a fake StopIteration error here, * to conform to PEP 380 */ if (PyStackRef_GenCheck(receiver)) { - if (monitor_stop_iteration(tstate, frame, this_instr, PyStackRef_AsPyObjectBorrow(value))) { + int err = monitor_stop_iteration(tstate, frame, this_instr, PyStackRef_AsPyObjectBorrow(value)); + if (err) { ERROR_NO_POP(); } } @@ -302,7 +303,8 @@ dummy_func( tier1 inst(INSTRUMENTED_END_SEND, (receiver, value -- value)) { PyObject *receiver_o = PyStackRef_AsPyObjectBorrow(receiver); if (PyGen_Check(receiver_o) || PyCoro_CheckExact(receiver_o)) { - if (monitor_stop_iteration(tstate, frame, this_instr, PyStackRef_AsPyObjectBorrow(value))) { + int err = monitor_stop_iteration(tstate, frame, this_instr, PyStackRef_AsPyObjectBorrow(value)); + if (err) { ERROR_NO_POP(); } } @@ -1069,11 +1071,12 @@ dummy_func( PyStackRef_AsPyObjectBorrow(v)); } if (retval_o == NULL) { - if (_PyErr_ExceptionMatches(tstate, PyExc_StopIteration) - ) { + int matches = _PyErr_ExceptionMatches(tstate, PyExc_StopIteration); + if (matches) { _PyEval_MonitorRaise(tstate, frame, this_instr); } - if (_PyGen_FetchStopIterationValue(&retval_o) == 0) { + int err = _PyGen_FetchStopIterationValue(&retval_o); + if (err == 0) { assert(retval_o != NULL); JUMPBY(oparg); } @@ -1210,7 +1213,8 @@ dummy_func( assert(throwflag); assert(exc_value && PyExceptionInstance_Check(exc_value)); - if (PyErr_GivenExceptionMatches(exc_value, PyExc_StopIteration)) { + int matches = PyErr_GivenExceptionMatches(exc_value, PyExc_StopIteration); + if (matches) { value = PyStackRef_FromPyObjectNew(((PyStopIterationObject *)exc_value)->value); DECREF_INPUTS(); none = PyStackRef_None; @@ -1425,7 +1429,8 @@ dummy_func( inst(LOAD_FROM_DICT_OR_GLOBALS, (mod_or_class_dict -- v)) { PyObject *name = GETITEM(FRAME_CO_NAMES, oparg); PyObject *v_o; - if (PyMapping_GetOptionalItem(PyStackRef_AsPyObjectBorrow(mod_or_class_dict), name, &v_o) < 0) { + int err = PyMapping_GetOptionalItem(PyStackRef_AsPyObjectBorrow(mod_or_class_dict), name, &v_o); + if (err < 0) { ERROR_NO_POP(); } if (v_o == NULL) { @@ -1596,7 +1601,8 @@ dummy_func( assert(class_dict); assert(oparg >= 0 && oparg < _PyFrame_GetCode(frame)->co_nlocalsplus); name = PyTuple_GET_ITEM(_PyFrame_GetCode(frame)->co_localsplusnames, oparg); - if (PyMapping_GetOptionalItem(class_dict, name, &value_o) < 0) { + int err = PyMapping_GetOptionalItem(class_dict, name, &value_o); + if (err < 0) { ERROR_NO_POP(); } if (!value_o) { @@ -1676,7 +1682,8 @@ dummy_func( PyObject *none_val = _PyList_Extend((PyListObject *)list, iterable); if (none_val == NULL) { - if (_PyErr_ExceptionMatches(tstate, PyExc_TypeError) && + int matches = _PyErr_ExceptionMatches(tstate, PyExc_TypeError); + if (matches && (Py_TYPE(iterable)->tp_iter == NULL && !PySequence_Check(iterable))) { _PyErr_Clear(tstate); @@ -1762,8 +1769,10 @@ dummy_func( PyObject *dict_o = PyStackRef_AsPyObjectBorrow(dict); PyObject *update_o = PyStackRef_AsPyObjectBorrow(update); - if (PyDict_Update(dict_o, update_o) < 0) { - if (_PyErr_ExceptionMatches(tstate, PyExc_AttributeError)) { + int err = PyDict_Update(dict_o, update_o); + if (err < 0) { + int matches = _PyErr_ExceptionMatches(tstate, PyExc_AttributeError); + if (matches) { _PyErr_Format(tstate, PyExc_TypeError, "'%.200s' object is not a mapping", Py_TYPE(update_o)->tp_name); @@ -1779,7 +1788,8 @@ dummy_func( PyObject *dict_o = PyStackRef_AsPyObjectBorrow(dict); PyObject *update_o = PyStackRef_AsPyObjectBorrow(update); - if (_PyDict_MergeEx(dict_o, update_o, 2) < 0) { + int err = _PyDict_MergeEx(dict_o, update_o, 2); + if (err < 0) { _PyEval_FormatKwargsError(tstate, callable_o, update_o); DECREF_INPUTS(); ERROR_IF(true, error); @@ -1943,7 +1953,8 @@ dummy_func( if (oparg & 1) { /* Designed to work in tandem with CALL, pushes two values. */ attr_o = NULL; - if (_PyObject_GetMethod(PyStackRef_AsPyObjectBorrow(owner), name, &attr_o)) { + int is_meth = _PyObject_GetMethod(PyStackRef_AsPyObjectBorrow(owner), name, &attr_o); + if (is_meth) { /* We can bypass temporary bound method object. meth is unbound method and obj is self. meth | self | arg1 | ... | argN @@ -2416,8 +2427,8 @@ dummy_func( inst(CHECK_EG_MATCH, (exc_value_st, match_type_st -- rest, match)) { PyObject *exc_value = PyStackRef_AsPyObjectBorrow(exc_value_st); PyObject *match_type = PyStackRef_AsPyObjectBorrow(match_type_st); - - if (_PyEval_CheckExceptStarTypeValid(tstate, match_type) < 0) { + int err = _PyEval_CheckExceptStarTypeValid(tstate, match_type); + if (err < 0) { DECREF_INPUTS(); ERROR_IF(true, error); } @@ -2704,7 +2715,8 @@ dummy_func( if (next_o == NULL) { next = PyStackRef_NULL; if (_PyErr_Occurred(tstate)) { - if (!_PyErr_ExceptionMatches(tstate, PyExc_StopIteration)) { + int matches = _PyErr_ExceptionMatches(tstate, PyExc_StopIteration); + if (!matches) { ERROR_NO_POP(); } _PyEval_MonitorRaise(tstate, frame, this_instr); @@ -2729,7 +2741,8 @@ dummy_func( PyObject *next_o = (*Py_TYPE(iter_o)->tp_iternext)(iter_o); if (next_o == NULL) { if (_PyErr_Occurred(tstate)) { - if (!_PyErr_ExceptionMatches(tstate, PyExc_StopIteration)) { + int matches = _PyErr_ExceptionMatches(tstate, PyExc_StopIteration); + if (!matches) { ERROR_NO_POP(); } _PyEval_MonitorRaise(tstate, frame, frame->instr_ptr); @@ -2756,7 +2769,8 @@ dummy_func( } else { if (_PyErr_Occurred(tstate)) { - if (!_PyErr_ExceptionMatches(tstate, PyExc_StopIteration)) { + int matches = _PyErr_ExceptionMatches(tstate, PyExc_StopIteration); + if (!matches) { ERROR_NO_POP(); } _PyEval_MonitorRaise(tstate, frame, this_instr); diff --git a/Python/executor_cases.c.h b/Python/executor_cases.c.h index cbee77d..7f520eb 100644 --- a/Python/executor_cases.c.h +++ b/Python/executor_cases.c.h @@ -1777,7 +1777,8 @@ assert(class_dict); assert(oparg >= 0 && oparg < _PyFrame_GetCode(frame)->co_nlocalsplus); name = PyTuple_GET_ITEM(_PyFrame_GetCode(frame)->co_localsplusnames, oparg); - if (PyMapping_GetOptionalItem(class_dict, name, &value_o) < 0) { + int err = PyMapping_GetOptionalItem(class_dict, name, &value_o); + if (err < 0) { JUMP_TO_ERROR(); } if (!value_o) { @@ -1907,7 +1908,8 @@ PyObject *iterable = PyStackRef_AsPyObjectBorrow(iterable_st); PyObject *none_val = _PyList_Extend((PyListObject *)list, iterable); if (none_val == NULL) { - if (_PyErr_ExceptionMatches(tstate, PyExc_TypeError) && + int matches = _PyErr_ExceptionMatches(tstate, PyExc_TypeError); + if (matches && (Py_TYPE(iterable)->tp_iter == NULL && !PySequence_Check(iterable))) { _PyErr_Clear(tstate); @@ -2031,8 +2033,10 @@ dict = stack_pointer[-2 - (oparg - 1)]; PyObject *dict_o = PyStackRef_AsPyObjectBorrow(dict); PyObject *update_o = PyStackRef_AsPyObjectBorrow(update); - if (PyDict_Update(dict_o, update_o) < 0) { - if (_PyErr_ExceptionMatches(tstate, PyExc_AttributeError)) { + int err = PyDict_Update(dict_o, update_o); + if (err < 0) { + int matches = _PyErr_ExceptionMatches(tstate, PyExc_AttributeError); + if (matches) { _PyErr_Format(tstate, PyExc_TypeError, "'%.200s' object is not a mapping", Py_TYPE(update_o)->tp_name); @@ -2057,7 +2061,8 @@ PyObject *callable_o = PyStackRef_AsPyObjectBorrow(callable); PyObject *dict_o = PyStackRef_AsPyObjectBorrow(dict); PyObject *update_o = PyStackRef_AsPyObjectBorrow(update); - if (_PyDict_MergeEx(dict_o, update_o, 2) < 0) { + int err = _PyDict_MergeEx(dict_o, update_o, 2); + if (err < 0) { _PyEval_FormatKwargsError(tstate, callable_o, update_o); PyStackRef_CLOSE(update); if (true) JUMP_TO_ERROR(); @@ -2182,7 +2187,8 @@ if (oparg & 1) { /* Designed to work in tandem with CALL, pushes two values. */ attr_o = NULL; - if (_PyObject_GetMethod(PyStackRef_AsPyObjectBorrow(owner), name, &attr_o)) { + int is_meth = _PyObject_GetMethod(PyStackRef_AsPyObjectBorrow(owner), name, &attr_o); + if (is_meth) { /* We can bypass temporary bound method object. meth is unbound method and obj is self. meth | self | arg1 | ... | argN @@ -2855,7 +2861,8 @@ exc_value_st = stack_pointer[-2]; PyObject *exc_value = PyStackRef_AsPyObjectBorrow(exc_value_st); PyObject *match_type = PyStackRef_AsPyObjectBorrow(match_type_st); - if (_PyEval_CheckExceptStarTypeValid(tstate, match_type) < 0) { + int err = _PyEval_CheckExceptStarTypeValid(tstate, match_type); + if (err < 0) { PyStackRef_CLOSE(exc_value_st); PyStackRef_CLOSE(match_type_st); if (true) JUMP_TO_ERROR(); @@ -3101,7 +3108,8 @@ PyObject *next_o = (*Py_TYPE(iter_o)->tp_iternext)(iter_o); if (next_o == NULL) { if (_PyErr_Occurred(tstate)) { - if (!_PyErr_ExceptionMatches(tstate, PyExc_StopIteration)) { + int matches = _PyErr_ExceptionMatches(tstate, PyExc_StopIteration); + if (!matches) { JUMP_TO_ERROR(); } _PyEval_MonitorRaise(tstate, frame, frame->instr_ptr); diff --git a/Python/generated_cases.c.h b/Python/generated_cases.c.h index 879c40a..3149096 100644 --- a/Python/generated_cases.c.h +++ b/Python/generated_cases.c.h @@ -2465,7 +2465,8 @@ exc_value_st = stack_pointer[-2]; PyObject *exc_value = PyStackRef_AsPyObjectBorrow(exc_value_st); PyObject *match_type = PyStackRef_AsPyObjectBorrow(match_type_st); - if (_PyEval_CheckExceptStarTypeValid(tstate, match_type) < 0) { + int err = _PyEval_CheckExceptStarTypeValid(tstate, match_type); + if (err < 0) { PyStackRef_CLOSE(exc_value_st); PyStackRef_CLOSE(match_type_st); if (true) goto pop_2_error; @@ -2528,7 +2529,8 @@ PyObject *exc_value = PyStackRef_AsPyObjectBorrow(exc_value_st); assert(throwflag); assert(exc_value && PyExceptionInstance_Check(exc_value)); - if (PyErr_GivenExceptionMatches(exc_value, PyExc_StopIteration)) { + int matches = PyErr_GivenExceptionMatches(exc_value, PyExc_StopIteration); + if (matches) { value = PyStackRef_FromPyObjectNew(((PyStopIterationObject *)exc_value)->value); PyStackRef_CLOSE(sub_iter_st); PyStackRef_CLOSE(last_sent_val_st); @@ -2982,7 +2984,8 @@ PyObject *callable_o = PyStackRef_AsPyObjectBorrow(callable); PyObject *dict_o = PyStackRef_AsPyObjectBorrow(dict); PyObject *update_o = PyStackRef_AsPyObjectBorrow(update); - if (_PyDict_MergeEx(dict_o, update_o, 2) < 0) { + int err = _PyDict_MergeEx(dict_o, update_o, 2); + if (err < 0) { _PyEval_FormatKwargsError(tstate, callable_o, update_o); PyStackRef_CLOSE(update); if (true) goto pop_1_error; @@ -3003,8 +3006,10 @@ dict = stack_pointer[-2 - (oparg - 1)]; PyObject *dict_o = PyStackRef_AsPyObjectBorrow(dict); PyObject *update_o = PyStackRef_AsPyObjectBorrow(update); - if (PyDict_Update(dict_o, update_o) < 0) { - if (_PyErr_ExceptionMatches(tstate, PyExc_AttributeError)) { + int err = PyDict_Update(dict_o, update_o); + if (err < 0) { + int matches = _PyErr_ExceptionMatches(tstate, PyExc_AttributeError); + if (matches) { _PyErr_Format(tstate, PyExc_TypeError, "'%.200s' object is not a mapping", Py_TYPE(update_o)->tp_name); @@ -3208,7 +3213,8 @@ if (next_o == NULL) { next = PyStackRef_NULL; if (_PyErr_Occurred(tstate)) { - if (!_PyErr_ExceptionMatches(tstate, PyExc_StopIteration)) { + int matches = _PyErr_ExceptionMatches(tstate, PyExc_StopIteration); + if (!matches) { goto error; } _PyEval_MonitorRaise(tstate, frame, this_instr); @@ -3786,7 +3792,8 @@ /* Need to create a fake StopIteration error here, * to conform to PEP 380 */ if (PyStackRef_GenCheck(receiver)) { - if (monitor_stop_iteration(tstate, frame, this_instr, PyStackRef_AsPyObjectBorrow(value))) { + int err = monitor_stop_iteration(tstate, frame, this_instr, PyStackRef_AsPyObjectBorrow(value)); + if (err) { goto error; } } @@ -3807,7 +3814,8 @@ receiver = stack_pointer[-2]; PyObject *receiver_o = PyStackRef_AsPyObjectBorrow(receiver); if (PyGen_Check(receiver_o) || PyCoro_CheckExact(receiver_o)) { - if (monitor_stop_iteration(tstate, frame, this_instr, PyStackRef_AsPyObjectBorrow(value))) { + int err = monitor_stop_iteration(tstate, frame, this_instr, PyStackRef_AsPyObjectBorrow(value)); + if (err) { goto error; } } @@ -3834,7 +3842,8 @@ } else { if (_PyErr_Occurred(tstate)) { - if (!_PyErr_ExceptionMatches(tstate, PyExc_StopIteration)) { + int matches = _PyErr_ExceptionMatches(tstate, PyExc_StopIteration); + if (!matches) { goto error; } _PyEval_MonitorRaise(tstate, frame, this_instr); @@ -4327,7 +4336,8 @@ PyObject *iterable = PyStackRef_AsPyObjectBorrow(iterable_st); PyObject *none_val = _PyList_Extend((PyListObject *)list, iterable); if (none_val == NULL) { - if (_PyErr_ExceptionMatches(tstate, PyExc_TypeError) && + int matches = _PyErr_ExceptionMatches(tstate, PyExc_TypeError); + if (matches && (Py_TYPE(iterable)->tp_iter == NULL && !PySequence_Check(iterable))) { _PyErr_Clear(tstate); @@ -4379,7 +4389,8 @@ if (oparg & 1) { /* Designed to work in tandem with CALL, pushes two values. */ attr_o = NULL; - if (_PyObject_GetMethod(PyStackRef_AsPyObjectBorrow(owner), name, &attr_o)) { + int is_meth = _PyObject_GetMethod(PyStackRef_AsPyObjectBorrow(owner), name, &attr_o); + if (is_meth) { /* We can bypass temporary bound method object. meth is unbound method and obj is self. meth | self | arg1 | ... | argN @@ -5074,7 +5085,8 @@ assert(class_dict); assert(oparg >= 0 && oparg < _PyFrame_GetCode(frame)->co_nlocalsplus); name = PyTuple_GET_ITEM(_PyFrame_GetCode(frame)->co_localsplusnames, oparg); - if (PyMapping_GetOptionalItem(class_dict, name, &value_o) < 0) { + int err = PyMapping_GetOptionalItem(class_dict, name, &value_o); + if (err < 0) { goto error; } if (!value_o) { @@ -5100,7 +5112,8 @@ mod_or_class_dict = stack_pointer[-1]; PyObject *name = GETITEM(FRAME_CO_NAMES, oparg); PyObject *v_o; - if (PyMapping_GetOptionalItem(PyStackRef_AsPyObjectBorrow(mod_or_class_dict), name, &v_o) < 0) { + int err = PyMapping_GetOptionalItem(PyStackRef_AsPyObjectBorrow(mod_or_class_dict), name, &v_o); + if (err < 0) { goto error; } if (v_o == NULL) { @@ -6080,11 +6093,12 @@ PyStackRef_AsPyObjectBorrow(v)); } if (retval_o == NULL) { - if (_PyErr_ExceptionMatches(tstate, PyExc_StopIteration) - ) { + int matches = _PyErr_ExceptionMatches(tstate, PyExc_StopIteration); + if (matches) { _PyEval_MonitorRaise(tstate, frame, this_instr); } - if (_PyGen_FetchStopIterationValue(&retval_o) == 0) { + int err = _PyGen_FetchStopIterationValue(&retval_o); + if (err == 0) { assert(retval_o != NULL); JUMPBY(oparg); } |