From 3e99c9cbf67225ec1d3bb6af812e883f19ef53de Mon Sep 17 00:00:00 2001 From: Brandt Bucher Date: Mon, 6 Nov 2023 16:42:49 -0800 Subject: [PATCH] GH-111485: Make BEFORE_WITH a uop (GH-111812) --- Include/internal/pycore_opcode_metadata.h | 1 + Python/abstract_interp_cases.c.h | 7 ++++ Python/bytecodes.c | 5 +-- Python/executor_cases.c.h | 45 ++++++++++++++++++++++- Python/generated_cases.c.h | 5 +-- 5 files changed, 56 insertions(+), 7 deletions(-) diff --git a/Include/internal/pycore_opcode_metadata.h b/Include/internal/pycore_opcode_metadata.h index ed38ed0f39f..6d3bda6f127 100644 --- a/Include/internal/pycore_opcode_metadata.h +++ b/Include/internal/pycore_opcode_metadata.h @@ -1864,6 +1864,7 @@ const struct opcode_macro_expansion _PyOpcode_macro_expansion[OPCODE_MACRO_EXPAN [GET_ITER] = { .nuops = 1, .uops = { { GET_ITER, 0, 0 } } }, [GET_YIELD_FROM_ITER] = { .nuops = 1, .uops = { { GET_YIELD_FROM_ITER, 0, 0 } } }, [BEFORE_ASYNC_WITH] = { .nuops = 1, .uops = { { BEFORE_ASYNC_WITH, 0, 0 } } }, + [BEFORE_WITH] = { .nuops = 1, .uops = { { BEFORE_WITH, 0, 0 } } }, [WITH_EXCEPT_START] = { .nuops = 1, .uops = { { WITH_EXCEPT_START, 0, 0 } } }, [PUSH_EXC_INFO] = { .nuops = 1, .uops = { { PUSH_EXC_INFO, 0, 0 } } }, [LOAD_ATTR_METHOD_WITH_VALUES] = { .nuops = 4, .uops = { { _GUARD_TYPE_VERSION, 2, 1 }, { _GUARD_DORV_VALUES_INST_ATTR_FROM_DICT, 0, 0 }, { _GUARD_KEYS_VERSION, 2, 3 }, { _LOAD_ATTR_METHOD_WITH_VALUES, 4, 5 } } }, diff --git a/Python/abstract_interp_cases.c.h b/Python/abstract_interp_cases.c.h index 0e58ed1b0be..c80b5ecbebf 100644 --- a/Python/abstract_interp_cases.c.h +++ b/Python/abstract_interp_cases.c.h @@ -683,6 +683,13 @@ break; } + case BEFORE_WITH: { + STACK_GROW(1); + PARTITIONNODE_OVERWRITE((_Py_PARTITIONNODE_t *)PARTITIONNODE_NULLROOT, PEEK(-(-2)), true); + PARTITIONNODE_OVERWRITE((_Py_PARTITIONNODE_t *)PARTITIONNODE_NULLROOT, PEEK(-(-1)), true); + break; + } + case WITH_EXCEPT_START: { STACK_GROW(1); PARTITIONNODE_OVERWRITE((_Py_PARTITIONNODE_t *)PARTITIONNODE_NULLROOT, PEEK(-(-1)), true); diff --git a/Python/bytecodes.c b/Python/bytecodes.c index f487e95854b..7c8ee7b976d 100644 --- a/Python/bytecodes.c +++ b/Python/bytecodes.c @@ -2765,7 +2765,7 @@ dummy_func( GOTO_ERROR(error); } DECREF_INPUTS(); - res = _PyObject_CallNoArgs(enter); + res = _PyObject_CallNoArgsTstate(tstate, enter); Py_DECREF(enter); if (res == NULL) { Py_DECREF(exit); @@ -2774,7 +2774,6 @@ dummy_func( } inst(BEFORE_WITH, (mgr -- exit, res)) { - TIER_ONE_ONLY /* pop the context manager, push its __exit__ and the * value returned from calling its __enter__ */ @@ -2801,7 +2800,7 @@ dummy_func( GOTO_ERROR(error); } DECREF_INPUTS(); - res = _PyObject_CallNoArgs(enter); + res = _PyObject_CallNoArgsTstate(tstate, enter); Py_DECREF(enter); if (res == NULL) { Py_DECREF(exit); diff --git a/Python/executor_cases.c.h b/Python/executor_cases.c.h index eb56c34b432..df7ddf2ded1 100644 --- a/Python/executor_cases.c.h +++ b/Python/executor_cases.c.h @@ -2304,7 +2304,50 @@ GOTO_ERROR(error); } Py_DECREF(mgr); - res = _PyObject_CallNoArgs(enter); + res = _PyObject_CallNoArgsTstate(tstate, enter); + Py_DECREF(enter); + if (res == NULL) { + Py_DECREF(exit); + if (true) goto pop_1_error_tier_two; + } + STACK_GROW(1); + stack_pointer[-2] = exit; + stack_pointer[-1] = res; + break; + } + + case BEFORE_WITH: { + PyObject *mgr; + PyObject *exit; + PyObject *res; + mgr = stack_pointer[-1]; + /* pop the context manager, push its __exit__ and the + * value returned from calling its __enter__ + */ + PyObject *enter = _PyObject_LookupSpecial(mgr, &_Py_ID(__enter__)); + if (enter == NULL) { + if (!_PyErr_Occurred(tstate)) { + _PyErr_Format(tstate, PyExc_TypeError, + "'%.200s' object does not support the " + "context manager protocol", + Py_TYPE(mgr)->tp_name); + } + GOTO_ERROR(error); + } + exit = _PyObject_LookupSpecial(mgr, &_Py_ID(__exit__)); + if (exit == NULL) { + if (!_PyErr_Occurred(tstate)) { + _PyErr_Format(tstate, PyExc_TypeError, + "'%.200s' object does not support the " + "context manager protocol " + "(missed __exit__ method)", + Py_TYPE(mgr)->tp_name); + } + Py_DECREF(enter); + GOTO_ERROR(error); + } + Py_DECREF(mgr); + res = _PyObject_CallNoArgsTstate(tstate, enter); Py_DECREF(enter); if (res == NULL) { Py_DECREF(exit); diff --git a/Python/generated_cases.c.h b/Python/generated_cases.c.h index 12e4f5204cc..1c853047a26 100644 --- a/Python/generated_cases.c.h +++ b/Python/generated_cases.c.h @@ -3967,7 +3967,7 @@ GOTO_ERROR(error); } Py_DECREF(mgr); - res = _PyObject_CallNoArgs(enter); + res = _PyObject_CallNoArgsTstate(tstate, enter); Py_DECREF(enter); if (res == NULL) { Py_DECREF(exit); @@ -3987,7 +3987,6 @@ PyObject *exit; PyObject *res; mgr = stack_pointer[-1]; - TIER_ONE_ONLY /* pop the context manager, push its __exit__ and the * value returned from calling its __enter__ */ @@ -4014,7 +4013,7 @@ GOTO_ERROR(error); } Py_DECREF(mgr); - res = _PyObject_CallNoArgs(enter); + res = _PyObject_CallNoArgsTstate(tstate, enter); Py_DECREF(enter); if (res == NULL) { Py_DECREF(exit);