GH-98831: Modernize a ton of simpler instructions (#100545)

* load_const and load_fast aren't families for now
* Don't decref unmoved names
* Modernize GET_ANEXT
* Modernize GET_AWAITABLE
* Modernize ASYNC_GEN_WRAP
* Modernize YIELD_VALUE
* Modernize POP_EXCEPT (in more than one way)
* Modernize PREP_RERAISE_STAR
* Modernize LOAD_ASSERTION_ERROR
* Modernize LOAD_BUILD_CLASS
* Modernize STORE_NAME
* Modernize LOAD_NAME
* Modernize LOAD_CLASSDEREF
* Modernize LOAD_DEREF
* Modernize STORE_DEREF
* Modernize COPY_FREE_VARS (mark it as done)
* Modernize LIST_TO_TUPLE
* Modernize LIST_EXTEND
* Modernize SET_UPDATE
* Modernize SETUP_ANNOTATIONS
* Modernize DICT_UPDATE
* Modernize DICT_MERGE
* Modernize MAP_ADD
* Modernize IS_OP
* Modernize CONTAINS_OP
* Modernize CHECK_EXC_MATCH
* Modernize IMPORT_NAME
* Modernize IMPORT_STAR
* Modernize IMPORT_FROM
* Modernize JUMP_FORWARD (mark it as done)
* Modernize JUMP_BACKWARD (mark it as done)
This commit is contained in:
Guido van Rossum 2022-12-27 17:11:03 -08:00 committed by GitHub
parent 3dc48dabd4
commit 08e5594cf3
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 242 additions and 349 deletions

View file

@ -83,9 +83,11 @@ static PyObject *value, *value1, *value2, *left, *right, *res, *sum, *prod, *sub
static PyObject *container, *start, *stop, *v, *lhs, *rhs; static PyObject *container, *start, *stop, *v, *lhs, *rhs;
static PyObject *list, *tuple, *dict, *owner; static PyObject *list, *tuple, *dict, *owner;
static PyObject *exit_func, *lasti, *val, *retval, *obj, *iter; static PyObject *exit_func, *lasti, *val, *retval, *obj, *iter;
static PyObject *aiter, *awaitable, *iterable, *w, *exc_value, *bc;
static PyObject *orig, *excs, *update, *b, *fromlist, *level, *from;
static size_t jump; static size_t jump;
// Dummy variables for cache effects // Dummy variables for cache effects
static _Py_CODEUNIT when_to_jump_mask, invert, counter, index, hint; static uint16_t when_to_jump_mask, invert, counter, index, hint;
static uint32_t type_version; static uint32_t type_version;
// Dummy opcode names for 'op' opcodes // Dummy opcode names for 'op' opcodes
#define _COMPARE_OP_FLOAT 1003 #define _COMPARE_OP_FLOAT 1003
@ -638,12 +640,9 @@ dummy_func(
} }
} }
// stack effect: ( -- __0) inst(GET_ANEXT, (aiter -- aiter, awaitable)) {
inst(GET_ANEXT) {
unaryfunc getter = NULL; unaryfunc getter = NULL;
PyObject *next_iter = NULL; PyObject *next_iter = NULL;
PyObject *awaitable = NULL;
PyObject *aiter = TOP();
PyTypeObject *type = Py_TYPE(aiter); PyTypeObject *type = Py_TYPE(aiter);
if (PyAsyncGen_CheckExact(aiter)) { if (PyAsyncGen_CheckExact(aiter)) {
@ -685,20 +684,17 @@ dummy_func(
} }
} }
PUSH(awaitable);
PREDICT(LOAD_CONST); PREDICT(LOAD_CONST);
} }
// stack effect: ( -- ) inst(GET_AWAITABLE, (iterable -- iter)) {
inst(GET_AWAITABLE) { iter = _PyCoro_GetAwaitableIter(iterable);
PyObject *iterable = TOP();
PyObject *iter = _PyCoro_GetAwaitableIter(iterable);
if (iter == NULL) { if (iter == NULL) {
format_awaitable_error(tstate, Py_TYPE(iterable), oparg); format_awaitable_error(tstate, Py_TYPE(iterable), oparg);
} }
Py_DECREF(iterable); DECREF_INPUTS();
if (iter != NULL && PyCoro_CheckExact(iter)) { if (iter != NULL && PyCoro_CheckExact(iter)) {
PyObject *yf = _PyGen_yf((PyGenObject*)iter); PyObject *yf = _PyGen_yf((PyGenObject*)iter);
@ -714,11 +710,7 @@ dummy_func(
} }
} }
SET_TOP(iter); /* Even if it's NULL */ ERROR_IF(iter == NULL, error);
if (iter == NULL) {
goto error;
}
PREDICT(LOAD_CONST); PREDICT(LOAD_CONST);
} }
@ -773,29 +765,22 @@ dummy_func(
} }
} }
// stack effect: ( -- ) inst(ASYNC_GEN_WRAP, (v -- w)) {
inst(ASYNC_GEN_WRAP) {
PyObject *v = TOP();
assert(frame->f_code->co_flags & CO_ASYNC_GENERATOR); assert(frame->f_code->co_flags & CO_ASYNC_GENERATOR);
PyObject *w = _PyAsyncGenValueWrapperNew(v); w = _PyAsyncGenValueWrapperNew(v);
if (w == NULL) { DECREF_INPUTS();
goto error; ERROR_IF(w == NULL, error);
}
SET_TOP(w);
Py_DECREF(v);
} }
// stack effect: ( -- ) inst(YIELD_VALUE, (retval --)) {
inst(YIELD_VALUE) {
// NOTE: It's important that YIELD_VALUE never raises an exception! // NOTE: It's important that YIELD_VALUE never raises an exception!
// The compiler treats any exception raised here as a failed close() // The compiler treats any exception raised here as a failed close()
// or throw() call. // or throw() call.
assert(oparg == STACK_LEVEL()); assert(oparg == STACK_LEVEL());
assert(frame != &entry_frame); assert(frame != &entry_frame);
PyObject *retval = POP();
PyGenObject *gen = _PyFrame_GetGenerator(frame); PyGenObject *gen = _PyFrame_GetGenerator(frame);
gen->gi_frame_state = FRAME_SUSPENDED; gen->gi_frame_state = FRAME_SUSPENDED;
_PyFrame_SetStackPointer(frame, stack_pointer); _PyFrame_SetStackPointer(frame, stack_pointer - 1);
TRACE_FUNCTION_EXIT(); TRACE_FUNCTION_EXIT();
DTRACE_FUNCTION_EXIT(); DTRACE_FUNCTION_EXIT();
tstate->exc_info = gen->gi_exc_state.previous_item; tstate->exc_info = gen->gi_exc_state.previous_item;
@ -809,12 +794,9 @@ dummy_func(
goto resume_frame; goto resume_frame;
} }
// stack effect: (__0 -- ) inst(POP_EXCEPT, (exc_value -- )) {
inst(POP_EXCEPT) {
_PyErr_StackItem *exc_info = tstate->exc_info; _PyErr_StackItem *exc_info = tstate->exc_info;
PyObject *value = exc_info->exc_value; Py_XSETREF(exc_info->exc_value, exc_value);
exc_info->exc_value = POP();
Py_XDECREF(value);
} }
// stack effect: (__0 -- ) // stack effect: (__0 -- )
@ -839,21 +821,13 @@ dummy_func(
goto exception_unwind; goto exception_unwind;
} }
// stack effect: (__0 -- ) inst(PREP_RERAISE_STAR, (orig, excs -- val)) {
inst(PREP_RERAISE_STAR) {
PyObject *excs = POP();
assert(PyList_Check(excs)); assert(PyList_Check(excs));
PyObject *orig = POP();
PyObject *val = _PyExc_PrepReraiseStar(orig, excs); val = _PyExc_PrepReraiseStar(orig, excs);
Py_DECREF(excs); DECREF_INPUTS();
Py_DECREF(orig);
if (val == NULL) { ERROR_IF(val == NULL, error);
goto error;
}
PUSH(val);
} }
// stack effect: (__0, __1 -- ) // stack effect: (__0, __1 -- )
@ -934,16 +908,11 @@ dummy_func(
} }
} }
inst(LOAD_ASSERTION_ERROR, ( -- value)) {
// stack effect: ( -- __0) value = Py_NewRef(PyExc_AssertionError);
inst(LOAD_ASSERTION_ERROR) {
PyObject *value = PyExc_AssertionError;
PUSH(Py_NewRef(value));
} }
// stack effect: ( -- __0) inst(LOAD_BUILD_CLASS, ( -- bc)) {
inst(LOAD_BUILD_CLASS) {
PyObject *bc;
if (PyDict_CheckExact(BUILTINS())) { if (PyDict_CheckExact(BUILTINS())) {
bc = _PyDict_GetItemWithError(BUILTINS(), bc = _PyDict_GetItemWithError(BUILTINS(),
&_Py_ID(__build_class__)); &_Py_ID(__build_class__));
@ -952,7 +921,7 @@ dummy_func(
_PyErr_SetString(tstate, PyExc_NameError, _PyErr_SetString(tstate, PyExc_NameError,
"__build_class__ not found"); "__build_class__ not found");
} }
goto error; ERROR_IF(true, error);
} }
Py_INCREF(bc); Py_INCREF(bc);
} }
@ -962,31 +931,27 @@ dummy_func(
if (_PyErr_ExceptionMatches(tstate, PyExc_KeyError)) if (_PyErr_ExceptionMatches(tstate, PyExc_KeyError))
_PyErr_SetString(tstate, PyExc_NameError, _PyErr_SetString(tstate, PyExc_NameError,
"__build_class__ not found"); "__build_class__ not found");
goto error; ERROR_IF(true, error);
} }
} }
PUSH(bc);
} }
// stack effect: (__0 -- ) inst(STORE_NAME, (v -- )) {
inst(STORE_NAME) {
PyObject *name = GETITEM(names, oparg); PyObject *name = GETITEM(names, oparg);
PyObject *v = POP();
PyObject *ns = LOCALS(); PyObject *ns = LOCALS();
int err; int err;
if (ns == NULL) { if (ns == NULL) {
_PyErr_Format(tstate, PyExc_SystemError, _PyErr_Format(tstate, PyExc_SystemError,
"no locals found when storing %R", name); "no locals found when storing %R", name);
Py_DECREF(v); DECREF_INPUTS();
goto error; ERROR_IF(true, error);
} }
if (PyDict_CheckExact(ns)) if (PyDict_CheckExact(ns))
err = PyDict_SetItem(ns, name, v); err = PyDict_SetItem(ns, name, v);
else else
err = PyObject_SetItem(ns, name, v); err = PyObject_SetItem(ns, name, v);
Py_DECREF(v); DECREF_INPUTS();
if (err != 0) ERROR_IF(err, error);
goto error;
} }
inst(DELETE_NAME, (--)) { inst(DELETE_NAME, (--)) {
@ -1139,11 +1104,9 @@ dummy_func(
} }
} }
// stack effect: ( -- __0) inst(LOAD_NAME, ( -- v)) {
inst(LOAD_NAME) {
PyObject *name = GETITEM(names, oparg); PyObject *name = GETITEM(names, oparg);
PyObject *locals = LOCALS(); PyObject *locals = LOCALS();
PyObject *v;
if (locals == NULL) { if (locals == NULL) {
_PyErr_Format(tstate, PyExc_SystemError, _PyErr_Format(tstate, PyExc_SystemError,
"no locals when loading %R", name); "no locals when loading %R", name);
@ -1200,7 +1163,6 @@ dummy_func(
} }
} }
} }
PUSH(v);
} }
// error: LOAD_GLOBAL has irregular stack effect // error: LOAD_GLOBAL has irregular stack effect
@ -1339,9 +1301,8 @@ dummy_func(
Py_DECREF(oldobj); Py_DECREF(oldobj);
} }
// stack effect: ( -- __0) inst(LOAD_CLASSDEREF, ( -- value)) {
inst(LOAD_CLASSDEREF) { PyObject *name, *locals = LOCALS();
PyObject *name, *value, *locals = LOCALS();
assert(locals); assert(locals);
assert(oparg >= 0 && oparg < frame->f_code->co_nlocalsplus); assert(oparg >= 0 && oparg < frame->f_code->co_nlocalsplus);
name = PyTuple_GET_ITEM(frame->f_code->co_localsplusnames, oparg); name = PyTuple_GET_ITEM(frame->f_code->co_localsplusnames, oparg);
@ -1372,31 +1333,26 @@ dummy_func(
} }
Py_INCREF(value); Py_INCREF(value);
} }
PUSH(value);
} }
// stack effect: ( -- __0) inst(LOAD_DEREF, ( -- value)) {
inst(LOAD_DEREF) {
PyObject *cell = GETLOCAL(oparg); PyObject *cell = GETLOCAL(oparg);
PyObject *value = PyCell_GET(cell); value = PyCell_GET(cell);
if (value == NULL) { if (value == NULL) {
format_exc_unbound(tstate, frame->f_code, oparg); format_exc_unbound(tstate, frame->f_code, oparg);
goto error; ERROR_IF(true, error);
} }
PUSH(Py_NewRef(value)); Py_INCREF(value);
} }
// stack effect: (__0 -- ) inst(STORE_DEREF, (v --)) {
inst(STORE_DEREF) {
PyObject *v = POP();
PyObject *cell = GETLOCAL(oparg); PyObject *cell = GETLOCAL(oparg);
PyObject *oldobj = PyCell_GET(cell); PyObject *oldobj = PyCell_GET(cell);
PyCell_SET(cell, v); PyCell_SET(cell, v);
Py_XDECREF(oldobj); Py_XDECREF(oldobj);
} }
// stack effect: ( -- ) inst(COPY_FREE_VARS, (--)) {
inst(COPY_FREE_VARS) {
/* Copy closure variables to free variables */ /* Copy closure variables to free variables */
PyCodeObject *co = frame->f_code; PyCodeObject *co = frame->f_code;
assert(PyFunction_Check(frame->f_funcobj)); assert(PyFunction_Check(frame->f_funcobj));
@ -1444,21 +1400,14 @@ dummy_func(
PUSH(list); PUSH(list);
} }
// stack effect: ( -- ) inst(LIST_TO_TUPLE, (list -- tuple)) {
inst(LIST_TO_TUPLE) { tuple = PyList_AsTuple(list);
PyObject *list = POP(); DECREF_INPUTS();
PyObject *tuple = PyList_AsTuple(list); ERROR_IF(tuple == NULL, error);
Py_DECREF(list);
if (tuple == NULL) {
goto error;
}
PUSH(tuple);
} }
// stack effect: (__0 -- ) inst(LIST_EXTEND, (iterable -- )) {
inst(LIST_EXTEND) { PyObject *list = PEEK(oparg + 1); // iterable is still on the stack
PyObject *iterable = POP();
PyObject *list = PEEK(oparg);
PyObject *none_val = _PyList_Extend((PyListObject *)list, iterable); PyObject *none_val = _PyList_Extend((PyListObject *)list, iterable);
if (none_val == NULL) { if (none_val == NULL) {
if (_PyErr_ExceptionMatches(tstate, PyExc_TypeError) && if (_PyErr_ExceptionMatches(tstate, PyExc_TypeError) &&
@ -1469,22 +1418,18 @@ dummy_func(
"Value after * must be an iterable, not %.200s", "Value after * must be an iterable, not %.200s",
Py_TYPE(iterable)->tp_name); Py_TYPE(iterable)->tp_name);
} }
Py_DECREF(iterable); DECREF_INPUTS();
goto error; ERROR_IF(true, error);
} }
Py_DECREF(none_val); Py_DECREF(none_val);
Py_DECREF(iterable); DECREF_INPUTS();
} }
// stack effect: (__0 -- ) inst(SET_UPDATE, (iterable --)) {
inst(SET_UPDATE) { PyObject *set = PEEK(oparg + 1); // iterable is still on the stack
PyObject *iterable = POP();
PyObject *set = PEEK(oparg);
int err = _PySet_Update(set, iterable); int err = _PySet_Update(set, iterable);
Py_DECREF(iterable); DECREF_INPUTS();
if (err < 0) { ERROR_IF(err < 0, error);
goto error;
}
} }
// stack effect: (__array[oparg] -- __0) // stack effect: (__array[oparg] -- __0)
@ -1524,54 +1469,41 @@ dummy_func(
PUSH(map); PUSH(map);
} }
// stack effect: ( -- ) inst(SETUP_ANNOTATIONS, (--)) {
inst(SETUP_ANNOTATIONS) {
int err; int err;
PyObject *ann_dict; PyObject *ann_dict;
if (LOCALS() == NULL) { if (LOCALS() == NULL) {
_PyErr_Format(tstate, PyExc_SystemError, _PyErr_Format(tstate, PyExc_SystemError,
"no locals found when setting up annotations"); "no locals found when setting up annotations");
goto error; ERROR_IF(true, error);
} }
/* check if __annotations__ in locals()... */ /* check if __annotations__ in locals()... */
if (PyDict_CheckExact(LOCALS())) { if (PyDict_CheckExact(LOCALS())) {
ann_dict = _PyDict_GetItemWithError(LOCALS(), ann_dict = _PyDict_GetItemWithError(LOCALS(),
&_Py_ID(__annotations__)); &_Py_ID(__annotations__));
if (ann_dict == NULL) { if (ann_dict == NULL) {
if (_PyErr_Occurred(tstate)) { ERROR_IF(_PyErr_Occurred(tstate), error);
goto error;
}
/* ...if not, create a new one */ /* ...if not, create a new one */
ann_dict = PyDict_New(); ann_dict = PyDict_New();
if (ann_dict == NULL) { ERROR_IF(ann_dict == NULL, error);
goto error;
}
err = PyDict_SetItem(LOCALS(), &_Py_ID(__annotations__), err = PyDict_SetItem(LOCALS(), &_Py_ID(__annotations__),
ann_dict); ann_dict);
Py_DECREF(ann_dict); Py_DECREF(ann_dict);
if (err != 0) { ERROR_IF(err, error);
goto error;
}
} }
} }
else { else {
/* do the same if locals() is not a dict */ /* do the same if locals() is not a dict */
ann_dict = PyObject_GetItem(LOCALS(), &_Py_ID(__annotations__)); ann_dict = PyObject_GetItem(LOCALS(), &_Py_ID(__annotations__));
if (ann_dict == NULL) { if (ann_dict == NULL) {
if (!_PyErr_ExceptionMatches(tstate, PyExc_KeyError)) { ERROR_IF(!_PyErr_ExceptionMatches(tstate, PyExc_KeyError), error);
goto error;
}
_PyErr_Clear(tstate); _PyErr_Clear(tstate);
ann_dict = PyDict_New(); ann_dict = PyDict_New();
if (ann_dict == NULL) { ERROR_IF(ann_dict == NULL, error);
goto error;
}
err = PyObject_SetItem(LOCALS(), &_Py_ID(__annotations__), err = PyObject_SetItem(LOCALS(), &_Py_ID(__annotations__),
ann_dict); ann_dict);
Py_DECREF(ann_dict); Py_DECREF(ann_dict);
if (err != 0) { ERROR_IF(err, error);
goto error;
}
} }
else { else {
Py_DECREF(ann_dict); Py_DECREF(ann_dict);
@ -1603,48 +1535,38 @@ dummy_func(
PUSH(map); PUSH(map);
} }
// stack effect: (__0 -- ) inst(DICT_UPDATE, (update --)) {
inst(DICT_UPDATE) { PyObject *dict = PEEK(oparg + 1); // update is still on the stack
PyObject *update = POP();
PyObject *dict = PEEK(oparg);
if (PyDict_Update(dict, update) < 0) { if (PyDict_Update(dict, update) < 0) {
if (_PyErr_ExceptionMatches(tstate, PyExc_AttributeError)) { if (_PyErr_ExceptionMatches(tstate, PyExc_AttributeError)) {
_PyErr_Format(tstate, PyExc_TypeError, _PyErr_Format(tstate, PyExc_TypeError,
"'%.200s' object is not a mapping", "'%.200s' object is not a mapping",
Py_TYPE(update)->tp_name); Py_TYPE(update)->tp_name);
} }
Py_DECREF(update); DECREF_INPUTS();
goto error; ERROR_IF(true, error);
} }
Py_DECREF(update); DECREF_INPUTS();
} }
// stack effect: (__0 -- ) inst(DICT_MERGE, (update --)) {
inst(DICT_MERGE) { PyObject *dict = PEEK(oparg + 1); // update is still on the stack
PyObject *update = POP();
PyObject *dict = PEEK(oparg);
if (_PyDict_MergeEx(dict, update, 2) < 0) { if (_PyDict_MergeEx(dict, update, 2) < 0) {
format_kwargs_error(tstate, PEEK(2 + oparg), update); format_kwargs_error(tstate, PEEK(3 + oparg), update);
Py_DECREF(update); DECREF_INPUTS();
goto error; ERROR_IF(true, error);
} }
Py_DECREF(update); DECREF_INPUTS();
PREDICT(CALL_FUNCTION_EX); PREDICT(CALL_FUNCTION_EX);
} }
// stack effect: (__0, __1 -- ) inst(MAP_ADD, (key, value --)) {
inst(MAP_ADD) { PyObject *dict = PEEK(oparg + 2); // key, value are still on the stack
PyObject *value = TOP(); assert(PyDict_CheckExact(dict));
PyObject *key = SECOND(); /* dict[key] = value */
PyObject *map; // Do not DECREF INPUTS because the function steals the references
STACK_SHRINK(2); ERROR_IF(_PyDict_SetItem_Take2((PyDictObject *)dict, key, value) != 0, error);
map = PEEK(oparg); /* dict */
assert(PyDict_CheckExact(map));
/* map[key] = value */
if (_PyDict_SetItem_Take2((PyDictObject *)map, key, value) != 0) {
goto error;
}
PREDICT(JUMP_BACKWARD); PREDICT(JUMP_BACKWARD);
} }
@ -2073,29 +1995,17 @@ dummy_func(
} }
super(COMPARE_OP_STR_JUMP) = _COMPARE_OP_STR + _JUMP_IF; super(COMPARE_OP_STR_JUMP) = _COMPARE_OP_STR + _JUMP_IF;
// stack effect: (__0 -- ) inst(IS_OP, (left, right -- b)) {
inst(IS_OP) {
PyObject *right = POP();
PyObject *left = TOP();
int res = Py_Is(left, right) ^ oparg; int res = Py_Is(left, right) ^ oparg;
PyObject *b = res ? Py_True : Py_False; DECREF_INPUTS();
SET_TOP(Py_NewRef(b)); b = Py_NewRef(res ? Py_True : Py_False);
Py_DECREF(left);
Py_DECREF(right);
} }
// stack effect: (__0 -- ) inst(CONTAINS_OP, (left, right -- b)) {
inst(CONTAINS_OP) {
PyObject *right = POP();
PyObject *left = POP();
int res = PySequence_Contains(right, left); int res = PySequence_Contains(right, left);
Py_DECREF(left); DECREF_INPUTS();
Py_DECREF(right); ERROR_IF(res < 0, error);
if (res < 0) { b = Py_NewRef((res^oparg) ? Py_True : Py_False);
goto error;
}
PyObject *b = (res^oparg) ? Py_True : Py_False;
PUSH(Py_NewRef(b));
} }
// stack effect: ( -- ) // stack effect: ( -- )
@ -2139,76 +2049,57 @@ dummy_func(
} }
} }
// stack effect: ( -- ) inst(CHECK_EXC_MATCH, (left, right -- left, b)) {
inst(CHECK_EXC_MATCH) {
PyObject *right = POP();
PyObject *left = TOP();
assert(PyExceptionInstance_Check(left)); assert(PyExceptionInstance_Check(left));
if (check_except_type_valid(tstate, right) < 0) { if (check_except_type_valid(tstate, right) < 0) {
Py_DECREF(right); DECREF_INPUTS();
goto error; ERROR_IF(true, error);
} }
int res = PyErr_GivenExceptionMatches(left, right); int res = PyErr_GivenExceptionMatches(left, right);
Py_DECREF(right); DECREF_INPUTS();
PUSH(Py_NewRef(res ? Py_True : Py_False)); b = Py_NewRef(res ? Py_True : Py_False);
} }
// stack effect: (__0 -- ) inst(IMPORT_NAME, (level, fromlist -- res)) {
inst(IMPORT_NAME) {
PyObject *name = GETITEM(names, oparg); PyObject *name = GETITEM(names, oparg);
PyObject *fromlist = POP();
PyObject *level = TOP();
PyObject *res;
res = import_name(tstate, frame, name, fromlist, level); res = import_name(tstate, frame, name, fromlist, level);
Py_DECREF(level); DECREF_INPUTS();
Py_DECREF(fromlist); ERROR_IF(res == NULL, error);
SET_TOP(res);
if (res == NULL)
goto error;
} }
// stack effect: (__0 -- ) inst(IMPORT_STAR, (from --)) {
inst(IMPORT_STAR) { PyObject *locals;
PyObject *from = POP(), *locals;
int err; int err;
if (_PyFrame_FastToLocalsWithError(frame) < 0) { if (_PyFrame_FastToLocalsWithError(frame) < 0) {
Py_DECREF(from); DECREF_INPUTS();
goto error; ERROR_IF(true, error);
} }
locals = LOCALS(); locals = LOCALS();
if (locals == NULL) { if (locals == NULL) {
_PyErr_SetString(tstate, PyExc_SystemError, _PyErr_SetString(tstate, PyExc_SystemError,
"no locals found during 'import *'"); "no locals found during 'import *'");
Py_DECREF(from); DECREF_INPUTS();
goto error; ERROR_IF(true, error);
} }
err = import_all_from(tstate, locals, from); err = import_all_from(tstate, locals, from);
_PyFrame_LocalsToFast(frame, 0); _PyFrame_LocalsToFast(frame, 0);
Py_DECREF(from); DECREF_INPUTS();
if (err != 0) ERROR_IF(err, error);
goto error;
} }
// stack effect: ( -- __0) inst(IMPORT_FROM, (from -- from, res)) {
inst(IMPORT_FROM) {
PyObject *name = GETITEM(names, oparg); PyObject *name = GETITEM(names, oparg);
PyObject *from = TOP();
PyObject *res;
res = import_from(tstate, from, name); res = import_from(tstate, from, name);
PUSH(res); ERROR_IF(res == NULL, error);
if (res == NULL)
goto error;
} }
// stack effect: ( -- ) inst(JUMP_FORWARD, (--)) {
inst(JUMP_FORWARD) {
JUMPBY(oparg); JUMPBY(oparg);
} }
// stack effect: ( -- ) inst(JUMP_BACKWARD, (--)) {
inst(JUMP_BACKWARD) {
assert(oparg < INSTR_OFFSET()); assert(oparg < INSTR_OFFSET());
JUMPBY(-oparg); JUMPBY(-oparg);
CHECK_EVAL_BREAKER(); CHECK_EVAL_BREAKER();
@ -3631,8 +3522,6 @@ family(load_attr) = {
LOAD_ATTR_PROPERTY, LOAD_ATTR_SLOT, LOAD_ATTR_WITH_HINT, LOAD_ATTR_PROPERTY, LOAD_ATTR_SLOT, LOAD_ATTR_WITH_HINT,
LOAD_ATTR_METHOD_LAZY_DICT, LOAD_ATTR_METHOD_NO_DICT, LOAD_ATTR_METHOD_WITH_DICT, LOAD_ATTR_METHOD_LAZY_DICT, LOAD_ATTR_METHOD_NO_DICT, LOAD_ATTR_METHOD_WITH_DICT,
LOAD_ATTR_METHOD_WITH_VALUES }; LOAD_ATTR_METHOD_WITH_VALUES };
family(load_const) = { LOAD_CONST, LOAD_CONST__LOAD_FAST };
family(load_fast) = { LOAD_FAST, LOAD_FAST__LOAD_CONST, LOAD_FAST__LOAD_FAST };
family(load_global) = { family(load_global) = {
LOAD_GLOBAL, LOAD_GLOBAL_BUILTIN, LOAD_GLOBAL, LOAD_GLOBAL_BUILTIN,
LOAD_GLOBAL_MODULE }; LOAD_GLOBAL_MODULE };

View file

@ -795,10 +795,10 @@
} }
TARGET(GET_ANEXT) { TARGET(GET_ANEXT) {
PyObject *aiter = PEEK(1);
PyObject *awaitable;
unaryfunc getter = NULL; unaryfunc getter = NULL;
PyObject *next_iter = NULL; PyObject *next_iter = NULL;
PyObject *awaitable = NULL;
PyObject *aiter = TOP();
PyTypeObject *type = Py_TYPE(aiter); PyTypeObject *type = Py_TYPE(aiter);
if (PyAsyncGen_CheckExact(aiter)) { if (PyAsyncGen_CheckExact(aiter)) {
@ -840,15 +840,17 @@
} }
} }
PUSH(awaitable); STACK_GROW(1);
POKE(1, awaitable);
PREDICT(LOAD_CONST); PREDICT(LOAD_CONST);
DISPATCH(); DISPATCH();
} }
TARGET(GET_AWAITABLE) { TARGET(GET_AWAITABLE) {
PREDICTED(GET_AWAITABLE); PREDICTED(GET_AWAITABLE);
PyObject *iterable = TOP(); PyObject *iterable = PEEK(1);
PyObject *iter = _PyCoro_GetAwaitableIter(iterable); PyObject *iter;
iter = _PyCoro_GetAwaitableIter(iterable);
if (iter == NULL) { if (iter == NULL) {
format_awaitable_error(tstate, Py_TYPE(iterable), oparg); format_awaitable_error(tstate, Py_TYPE(iterable), oparg);
@ -870,12 +872,9 @@
} }
} }
SET_TOP(iter); /* Even if it's NULL */ if (iter == NULL) goto pop_1_error;
if (iter == NULL) {
goto error;
}
POKE(1, iter);
PREDICT(LOAD_CONST); PREDICT(LOAD_CONST);
DISPATCH(); DISPATCH();
} }
@ -931,27 +930,26 @@
} }
TARGET(ASYNC_GEN_WRAP) { TARGET(ASYNC_GEN_WRAP) {
PyObject *v = TOP(); PyObject *v = PEEK(1);
PyObject *w;
assert(frame->f_code->co_flags & CO_ASYNC_GENERATOR); assert(frame->f_code->co_flags & CO_ASYNC_GENERATOR);
PyObject *w = _PyAsyncGenValueWrapperNew(v); w = _PyAsyncGenValueWrapperNew(v);
if (w == NULL) {
goto error;
}
SET_TOP(w);
Py_DECREF(v); Py_DECREF(v);
if (w == NULL) goto pop_1_error;
POKE(1, w);
DISPATCH(); DISPATCH();
} }
TARGET(YIELD_VALUE) { TARGET(YIELD_VALUE) {
PyObject *retval = PEEK(1);
// NOTE: It's important that YIELD_VALUE never raises an exception! // NOTE: It's important that YIELD_VALUE never raises an exception!
// The compiler treats any exception raised here as a failed close() // The compiler treats any exception raised here as a failed close()
// or throw() call. // or throw() call.
assert(oparg == STACK_LEVEL()); assert(oparg == STACK_LEVEL());
assert(frame != &entry_frame); assert(frame != &entry_frame);
PyObject *retval = POP();
PyGenObject *gen = _PyFrame_GetGenerator(frame); PyGenObject *gen = _PyFrame_GetGenerator(frame);
gen->gi_frame_state = FRAME_SUSPENDED; gen->gi_frame_state = FRAME_SUSPENDED;
_PyFrame_SetStackPointer(frame, stack_pointer); _PyFrame_SetStackPointer(frame, stack_pointer - 1);
TRACE_FUNCTION_EXIT(); TRACE_FUNCTION_EXIT();
DTRACE_FUNCTION_EXIT(); DTRACE_FUNCTION_EXIT();
tstate->exc_info = gen->gi_exc_state.previous_item; tstate->exc_info = gen->gi_exc_state.previous_item;
@ -966,10 +964,10 @@
} }
TARGET(POP_EXCEPT) { TARGET(POP_EXCEPT) {
PyObject *exc_value = PEEK(1);
_PyErr_StackItem *exc_info = tstate->exc_info; _PyErr_StackItem *exc_info = tstate->exc_info;
PyObject *value = exc_info->exc_value; Py_XSETREF(exc_info->exc_value, exc_value);
exc_info->exc_value = POP(); STACK_SHRINK(1);
Py_XDECREF(value);
DISPATCH(); DISPATCH();
} }
@ -995,19 +993,18 @@
} }
TARGET(PREP_RERAISE_STAR) { TARGET(PREP_RERAISE_STAR) {
PyObject *excs = POP(); PyObject *excs = PEEK(1);
PyObject *orig = PEEK(2);
PyObject *val;
assert(PyList_Check(excs)); assert(PyList_Check(excs));
PyObject *orig = POP();
PyObject *val = _PyExc_PrepReraiseStar(orig, excs); val = _PyExc_PrepReraiseStar(orig, excs);
Py_DECREF(excs);
Py_DECREF(orig); Py_DECREF(orig);
Py_DECREF(excs);
if (val == NULL) { if (val == NULL) goto pop_2_error;
goto error; STACK_SHRINK(1);
} POKE(1, val);
PUSH(val);
DISPATCH(); DISPATCH();
} }
@ -1091,8 +1088,10 @@
} }
TARGET(LOAD_ASSERTION_ERROR) { TARGET(LOAD_ASSERTION_ERROR) {
PyObject *value = PyExc_AssertionError; PyObject *value;
PUSH(Py_NewRef(value)); value = Py_NewRef(PyExc_AssertionError);
STACK_GROW(1);
POKE(1, value);
DISPATCH(); DISPATCH();
} }
@ -1106,7 +1105,7 @@
_PyErr_SetString(tstate, PyExc_NameError, _PyErr_SetString(tstate, PyExc_NameError,
"__build_class__ not found"); "__build_class__ not found");
} }
goto error; if (true) goto error;
} }
Py_INCREF(bc); Py_INCREF(bc);
} }
@ -1116,31 +1115,32 @@
if (_PyErr_ExceptionMatches(tstate, PyExc_KeyError)) if (_PyErr_ExceptionMatches(tstate, PyExc_KeyError))
_PyErr_SetString(tstate, PyExc_NameError, _PyErr_SetString(tstate, PyExc_NameError,
"__build_class__ not found"); "__build_class__ not found");
goto error; if (true) goto error;
} }
} }
PUSH(bc); STACK_GROW(1);
POKE(1, bc);
DISPATCH(); DISPATCH();
} }
TARGET(STORE_NAME) { TARGET(STORE_NAME) {
PyObject *v = PEEK(1);
PyObject *name = GETITEM(names, oparg); PyObject *name = GETITEM(names, oparg);
PyObject *v = POP();
PyObject *ns = LOCALS(); PyObject *ns = LOCALS();
int err; int err;
if (ns == NULL) { if (ns == NULL) {
_PyErr_Format(tstate, PyExc_SystemError, _PyErr_Format(tstate, PyExc_SystemError,
"no locals found when storing %R", name); "no locals found when storing %R", name);
Py_DECREF(v); Py_DECREF(v);
goto error; if (true) goto pop_1_error;
} }
if (PyDict_CheckExact(ns)) if (PyDict_CheckExact(ns))
err = PyDict_SetItem(ns, name, v); err = PyDict_SetItem(ns, name, v);
else else
err = PyObject_SetItem(ns, name, v); err = PyObject_SetItem(ns, name, v);
Py_DECREF(v); Py_DECREF(v);
if (err != 0) if (err) goto pop_1_error;
goto error; STACK_SHRINK(1);
DISPATCH(); DISPATCH();
} }
@ -1304,9 +1304,9 @@
} }
TARGET(LOAD_NAME) { TARGET(LOAD_NAME) {
PyObject *v;
PyObject *name = GETITEM(names, oparg); PyObject *name = GETITEM(names, oparg);
PyObject *locals = LOCALS(); PyObject *locals = LOCALS();
PyObject *v;
if (locals == NULL) { if (locals == NULL) {
_PyErr_Format(tstate, PyExc_SystemError, _PyErr_Format(tstate, PyExc_SystemError,
"no locals when loading %R", name); "no locals when loading %R", name);
@ -1363,7 +1363,8 @@
} }
} }
} }
PUSH(v); STACK_GROW(1);
POKE(1, v);
DISPATCH(); DISPATCH();
} }
@ -1508,7 +1509,8 @@
} }
TARGET(LOAD_CLASSDEREF) { TARGET(LOAD_CLASSDEREF) {
PyObject *name, *value, *locals = LOCALS(); PyObject *value;
PyObject *name, *locals = LOCALS();
assert(locals); assert(locals);
assert(oparg >= 0 && oparg < frame->f_code->co_nlocalsplus); assert(oparg >= 0 && oparg < frame->f_code->co_nlocalsplus);
name = PyTuple_GET_ITEM(frame->f_code->co_localsplusnames, oparg); name = PyTuple_GET_ITEM(frame->f_code->co_localsplusnames, oparg);
@ -1539,27 +1541,32 @@
} }
Py_INCREF(value); Py_INCREF(value);
} }
PUSH(value); STACK_GROW(1);
POKE(1, value);
DISPATCH(); DISPATCH();
} }
TARGET(LOAD_DEREF) { TARGET(LOAD_DEREF) {
PyObject *value;
PyObject *cell = GETLOCAL(oparg); PyObject *cell = GETLOCAL(oparg);
PyObject *value = PyCell_GET(cell); value = PyCell_GET(cell);
if (value == NULL) { if (value == NULL) {
format_exc_unbound(tstate, frame->f_code, oparg); format_exc_unbound(tstate, frame->f_code, oparg);
goto error; if (true) goto error;
} }
PUSH(Py_NewRef(value)); Py_INCREF(value);
STACK_GROW(1);
POKE(1, value);
DISPATCH(); DISPATCH();
} }
TARGET(STORE_DEREF) { TARGET(STORE_DEREF) {
PyObject *v = POP(); PyObject *v = PEEK(1);
PyObject *cell = GETLOCAL(oparg); PyObject *cell = GETLOCAL(oparg);
PyObject *oldobj = PyCell_GET(cell); PyObject *oldobj = PyCell_GET(cell);
PyCell_SET(cell, v); PyCell_SET(cell, v);
Py_XDECREF(oldobj); Py_XDECREF(oldobj);
STACK_SHRINK(1);
DISPATCH(); DISPATCH();
} }
@ -1613,19 +1620,18 @@
} }
TARGET(LIST_TO_TUPLE) { TARGET(LIST_TO_TUPLE) {
PyObject *list = POP(); PyObject *list = PEEK(1);
PyObject *tuple = PyList_AsTuple(list); PyObject *tuple;
tuple = PyList_AsTuple(list);
Py_DECREF(list); Py_DECREF(list);
if (tuple == NULL) { if (tuple == NULL) goto pop_1_error;
goto error; POKE(1, tuple);
}
PUSH(tuple);
DISPATCH(); DISPATCH();
} }
TARGET(LIST_EXTEND) { TARGET(LIST_EXTEND) {
PyObject *iterable = POP(); PyObject *iterable = PEEK(1);
PyObject *list = PEEK(oparg); PyObject *list = PEEK(oparg + 1); // iterable is still on the stack
PyObject *none_val = _PyList_Extend((PyListObject *)list, iterable); PyObject *none_val = _PyList_Extend((PyListObject *)list, iterable);
if (none_val == NULL) { if (none_val == NULL) {
if (_PyErr_ExceptionMatches(tstate, PyExc_TypeError) && if (_PyErr_ExceptionMatches(tstate, PyExc_TypeError) &&
@ -1637,21 +1643,21 @@
Py_TYPE(iterable)->tp_name); Py_TYPE(iterable)->tp_name);
} }
Py_DECREF(iterable); Py_DECREF(iterable);
goto error; if (true) goto pop_1_error;
} }
Py_DECREF(none_val); Py_DECREF(none_val);
Py_DECREF(iterable); Py_DECREF(iterable);
STACK_SHRINK(1);
DISPATCH(); DISPATCH();
} }
TARGET(SET_UPDATE) { TARGET(SET_UPDATE) {
PyObject *iterable = POP(); PyObject *iterable = PEEK(1);
PyObject *set = PEEK(oparg); PyObject *set = PEEK(oparg + 1); // iterable is still on the stack
int err = _PySet_Update(set, iterable); int err = _PySet_Update(set, iterable);
Py_DECREF(iterable); Py_DECREF(iterable);
if (err < 0) { if (err < 0) goto pop_1_error;
goto error; STACK_SHRINK(1);
}
DISPATCH(); DISPATCH();
} }
@ -1698,47 +1704,35 @@
if (LOCALS() == NULL) { if (LOCALS() == NULL) {
_PyErr_Format(tstate, PyExc_SystemError, _PyErr_Format(tstate, PyExc_SystemError,
"no locals found when setting up annotations"); "no locals found when setting up annotations");
goto error; if (true) goto error;
} }
/* check if __annotations__ in locals()... */ /* check if __annotations__ in locals()... */
if (PyDict_CheckExact(LOCALS())) { if (PyDict_CheckExact(LOCALS())) {
ann_dict = _PyDict_GetItemWithError(LOCALS(), ann_dict = _PyDict_GetItemWithError(LOCALS(),
&_Py_ID(__annotations__)); &_Py_ID(__annotations__));
if (ann_dict == NULL) { if (ann_dict == NULL) {
if (_PyErr_Occurred(tstate)) { if (_PyErr_Occurred(tstate)) goto error;
goto error;
}
/* ...if not, create a new one */ /* ...if not, create a new one */
ann_dict = PyDict_New(); ann_dict = PyDict_New();
if (ann_dict == NULL) { if (ann_dict == NULL) goto error;
goto error;
}
err = PyDict_SetItem(LOCALS(), &_Py_ID(__annotations__), err = PyDict_SetItem(LOCALS(), &_Py_ID(__annotations__),
ann_dict); ann_dict);
Py_DECREF(ann_dict); Py_DECREF(ann_dict);
if (err != 0) { if (err) goto error;
goto error;
}
} }
} }
else { else {
/* do the same if locals() is not a dict */ /* do the same if locals() is not a dict */
ann_dict = PyObject_GetItem(LOCALS(), &_Py_ID(__annotations__)); ann_dict = PyObject_GetItem(LOCALS(), &_Py_ID(__annotations__));
if (ann_dict == NULL) { if (ann_dict == NULL) {
if (!_PyErr_ExceptionMatches(tstate, PyExc_KeyError)) { if (!_PyErr_ExceptionMatches(tstate, PyExc_KeyError)) goto error;
goto error;
}
_PyErr_Clear(tstate); _PyErr_Clear(tstate);
ann_dict = PyDict_New(); ann_dict = PyDict_New();
if (ann_dict == NULL) { if (ann_dict == NULL) goto error;
goto error;
}
err = PyObject_SetItem(LOCALS(), &_Py_ID(__annotations__), err = PyObject_SetItem(LOCALS(), &_Py_ID(__annotations__),
ann_dict); ann_dict);
Py_DECREF(ann_dict); Py_DECREF(ann_dict);
if (err != 0) { if (err) goto error;
goto error;
}
} }
else { else {
Py_DECREF(ann_dict); Py_DECREF(ann_dict);
@ -1772,8 +1766,8 @@
} }
TARGET(DICT_UPDATE) { TARGET(DICT_UPDATE) {
PyObject *update = POP(); PyObject *update = PEEK(1);
PyObject *dict = PEEK(oparg); PyObject *dict = PEEK(oparg + 1); // update is still on the stack
if (PyDict_Update(dict, update) < 0) { if (PyDict_Update(dict, update) < 0) {
if (_PyErr_ExceptionMatches(tstate, PyExc_AttributeError)) { if (_PyErr_ExceptionMatches(tstate, PyExc_AttributeError)) {
_PyErr_Format(tstate, PyExc_TypeError, _PyErr_Format(tstate, PyExc_TypeError,
@ -1781,37 +1775,37 @@
Py_TYPE(update)->tp_name); Py_TYPE(update)->tp_name);
} }
Py_DECREF(update); Py_DECREF(update);
goto error; if (true) goto pop_1_error;
} }
Py_DECREF(update); Py_DECREF(update);
STACK_SHRINK(1);
DISPATCH(); DISPATCH();
} }
TARGET(DICT_MERGE) { TARGET(DICT_MERGE) {
PyObject *update = POP(); PyObject *update = PEEK(1);
PyObject *dict = PEEK(oparg); PyObject *dict = PEEK(oparg + 1); // update is still on the stack
if (_PyDict_MergeEx(dict, update, 2) < 0) { if (_PyDict_MergeEx(dict, update, 2) < 0) {
format_kwargs_error(tstate, PEEK(2 + oparg), update); format_kwargs_error(tstate, PEEK(3 + oparg), update);
Py_DECREF(update); Py_DECREF(update);
goto error; if (true) goto pop_1_error;
} }
Py_DECREF(update); Py_DECREF(update);
STACK_SHRINK(1);
PREDICT(CALL_FUNCTION_EX); PREDICT(CALL_FUNCTION_EX);
DISPATCH(); DISPATCH();
} }
TARGET(MAP_ADD) { TARGET(MAP_ADD) {
PyObject *value = TOP(); PyObject *value = PEEK(1);
PyObject *key = SECOND(); PyObject *key = PEEK(2);
PyObject *map; PyObject *dict = PEEK(oparg + 2); // key, value are still on the stack
assert(PyDict_CheckExact(dict));
/* dict[key] = value */
// Do not DECREF INPUTS because the function steals the references
if (_PyDict_SetItem_Take2((PyDictObject *)dict, key, value) != 0) goto pop_2_error;
STACK_SHRINK(2); STACK_SHRINK(2);
map = PEEK(oparg); /* dict */
assert(PyDict_CheckExact(map));
/* map[key] = value */
if (_PyDict_SetItem_Take2((PyDictObject *)map, key, value) != 0) {
goto error;
}
PREDICT(JUMP_BACKWARD); PREDICT(JUMP_BACKWARD);
DISPATCH(); DISPATCH();
} }
@ -2312,27 +2306,29 @@
} }
TARGET(IS_OP) { TARGET(IS_OP) {
PyObject *right = POP(); PyObject *right = PEEK(1);
PyObject *left = TOP(); PyObject *left = PEEK(2);
PyObject *b;
int res = Py_Is(left, right) ^ oparg; int res = Py_Is(left, right) ^ oparg;
PyObject *b = res ? Py_True : Py_False;
SET_TOP(Py_NewRef(b));
Py_DECREF(left); Py_DECREF(left);
Py_DECREF(right); Py_DECREF(right);
b = Py_NewRef(res ? Py_True : Py_False);
STACK_SHRINK(1);
POKE(1, b);
DISPATCH(); DISPATCH();
} }
TARGET(CONTAINS_OP) { TARGET(CONTAINS_OP) {
PyObject *right = POP(); PyObject *right = PEEK(1);
PyObject *left = POP(); PyObject *left = PEEK(2);
PyObject *b;
int res = PySequence_Contains(right, left); int res = PySequence_Contains(right, left);
Py_DECREF(left); Py_DECREF(left);
Py_DECREF(right); Py_DECREF(right);
if (res < 0) { if (res < 0) goto pop_2_error;
goto error; b = Py_NewRef((res^oparg) ? Py_True : Py_False);
} STACK_SHRINK(1);
PyObject *b = (res^oparg) ? Py_True : Py_False; POKE(1, b);
PUSH(Py_NewRef(b));
DISPATCH(); DISPATCH();
} }
@ -2378,40 +2374,43 @@
} }
TARGET(CHECK_EXC_MATCH) { TARGET(CHECK_EXC_MATCH) {
PyObject *right = POP(); PyObject *right = PEEK(1);
PyObject *left = TOP(); PyObject *left = PEEK(2);
PyObject *b;
assert(PyExceptionInstance_Check(left)); assert(PyExceptionInstance_Check(left));
if (check_except_type_valid(tstate, right) < 0) { if (check_except_type_valid(tstate, right) < 0) {
Py_DECREF(right); Py_DECREF(right);
goto error; if (true) goto pop_1_error;
} }
int res = PyErr_GivenExceptionMatches(left, right); int res = PyErr_GivenExceptionMatches(left, right);
Py_DECREF(right); Py_DECREF(right);
PUSH(Py_NewRef(res ? Py_True : Py_False)); b = Py_NewRef(res ? Py_True : Py_False);
POKE(1, b);
DISPATCH(); DISPATCH();
} }
TARGET(IMPORT_NAME) { TARGET(IMPORT_NAME) {
PyObject *name = GETITEM(names, oparg); PyObject *fromlist = PEEK(1);
PyObject *fromlist = POP(); PyObject *level = PEEK(2);
PyObject *level = TOP();
PyObject *res; PyObject *res;
PyObject *name = GETITEM(names, oparg);
res = import_name(tstate, frame, name, fromlist, level); res = import_name(tstate, frame, name, fromlist, level);
Py_DECREF(level); Py_DECREF(level);
Py_DECREF(fromlist); Py_DECREF(fromlist);
SET_TOP(res); if (res == NULL) goto pop_2_error;
if (res == NULL) STACK_SHRINK(1);
goto error; POKE(1, res);
DISPATCH(); DISPATCH();
} }
TARGET(IMPORT_STAR) { TARGET(IMPORT_STAR) {
PyObject *from = POP(), *locals; PyObject *from = PEEK(1);
PyObject *locals;
int err; int err;
if (_PyFrame_FastToLocalsWithError(frame) < 0) { if (_PyFrame_FastToLocalsWithError(frame) < 0) {
Py_DECREF(from); Py_DECREF(from);
goto error; if (true) goto pop_1_error;
} }
locals = LOCALS(); locals = LOCALS();
@ -2419,24 +2418,24 @@
_PyErr_SetString(tstate, PyExc_SystemError, _PyErr_SetString(tstate, PyExc_SystemError,
"no locals found during 'import *'"); "no locals found during 'import *'");
Py_DECREF(from); Py_DECREF(from);
goto error; if (true) goto pop_1_error;
} }
err = import_all_from(tstate, locals, from); err = import_all_from(tstate, locals, from);
_PyFrame_LocalsToFast(frame, 0); _PyFrame_LocalsToFast(frame, 0);
Py_DECREF(from); Py_DECREF(from);
if (err != 0) if (err) goto pop_1_error;
goto error; STACK_SHRINK(1);
DISPATCH(); DISPATCH();
} }
TARGET(IMPORT_FROM) { TARGET(IMPORT_FROM) {
PyObject *name = GETITEM(names, oparg); PyObject *from = PEEK(1);
PyObject *from = TOP();
PyObject *res; PyObject *res;
PyObject *name = GETITEM(names, oparg);
res = import_from(tstate, from, name); res = import_from(tstate, from, name);
PUSH(res); if (res == NULL) goto error;
if (res == NULL) STACK_GROW(1);
goto error; POKE(1, res);
DISPATCH(); DISPATCH();
} }

View file

@ -125,6 +125,7 @@ class Instruction:
# Set later # Set later
family: parser.Family | None = None family: parser.Family | None = None
predicted: bool = False predicted: bool = False
unmoved_names: frozenset[str] = frozenset()
def __init__(self, inst: parser.InstDef): def __init__(self, inst: parser.InstDef):
self.inst = inst self.inst = inst
@ -141,6 +142,13 @@ class Instruction:
effect for effect in inst.inputs if isinstance(effect, StackEffect) effect for effect in inst.inputs if isinstance(effect, StackEffect)
] ]
self.output_effects = inst.outputs # For consistency/completeness self.output_effects = inst.outputs # For consistency/completeness
unmoved_names: set[str] = set()
for ieffect, oeffect in zip(self.input_effects, self.output_effects):
if ieffect.name == oeffect.name:
unmoved_names.add(ieffect.name)
else:
break
self.unmoved_names = frozenset(unmoved_names)
def write(self, out: Formatter) -> None: def write(self, out: Formatter) -> None:
"""Write one instruction, sans prologue and epilogue.""" """Write one instruction, sans prologue and epilogue."""
@ -175,12 +183,8 @@ class Instruction:
out.stack_adjust(diff) out.stack_adjust(diff)
# Write output stack effect assignments # Write output stack effect assignments
unmoved_names: set[str] = set()
for ieffect, oeffect in zip(self.input_effects, self.output_effects):
if ieffect.name == oeffect.name:
unmoved_names.add(ieffect.name)
for i, oeffect in enumerate(reversed(self.output_effects), 1): for i, oeffect in enumerate(reversed(self.output_effects), 1):
if oeffect.name not in unmoved_names: if oeffect.name not in self.unmoved_names:
dst = StackEffect(f"PEEK({i})", "") dst = StackEffect(f"PEEK({i})", "")
out.assign(dst, oeffect) out.assign(dst, oeffect)
@ -235,7 +239,8 @@ class Instruction:
elif m := re.match(r"(\s*)DECREF_INPUTS\(\);\s*$", line): elif m := re.match(r"(\s*)DECREF_INPUTS\(\);\s*$", line):
space = m.group(1) space = m.group(1)
for ieff in self.input_effects: for ieff in self.input_effects:
out.write_raw(f"{extra}{space}Py_DECREF({ieff.name});\n") if ieff.name not in self.unmoved_names:
out.write_raw(f"{extra}{space}Py_DECREF({ieff.name});\n")
else: else:
out.write_raw(extra + line) out.write_raw(extra + line)
@ -533,7 +538,7 @@ class Analyzer:
) -> tuple[list[StackEffect], int]: ) -> tuple[list[StackEffect], int]:
"""Analyze a super-instruction or macro. """Analyze a super-instruction or macro.
Print an error if there's a cache effect (which we don't support yet). Ignore cache effects.
Return the list of variable names and the initial stack pointer. Return the list of variable names and the initial stack pointer.
""" """