diff options
author | Guido van Rossum <guido@python.org> | 2023-01-30 01:28:39 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-01-30 01:28:39 (GMT) |
commit | f5a3d91b6c56ddff4644b5a5ac34d8c6d23d7c79 (patch) | |
tree | e66618346f1d30c9041239f6c93f6aeaaa319401 /Python/bytecodes.c | |
parent | c4170c36b0b54c10456f4b49245f570023a97f72 (diff) | |
download | cpython-f5a3d91b6c56ddff4644b5a5ac34d8c6d23d7c79.zip cpython-f5a3d91b6c56ddff4644b5a5ac34d8c6d23d7c79.tar.gz cpython-f5a3d91b6c56ddff4644b5a5ac34d8c6d23d7c79.tar.bz2 |
gh-98831: Support conditional effects; use for LOAD_ATTR (#101333)
Diffstat (limited to 'Python/bytecodes.c')
-rw-r--r-- | Python/bytecodes.c | 38 |
1 files changed, 13 insertions, 25 deletions
diff --git a/Python/bytecodes.c b/Python/bytecodes.c index e5769f61..fb00b88 100644 --- a/Python/bytecodes.c +++ b/Python/bytecodes.c @@ -51,7 +51,7 @@ // Dummy variables for stack effects. 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, *res2; static PyObject *list, *tuple, *dict, *owner, *set, *str, *tup, *map, *keys; static PyObject *exit_func, *lasti, *val, *retval, *obj, *iter; static PyObject *aiter, *awaitable, *iterable, *w, *exc_value, *bc; @@ -1438,13 +1438,11 @@ dummy_func( PREDICT(JUMP_BACKWARD); } - // error: LOAD_ATTR has irregular stack effect - inst(LOAD_ATTR) { + inst(LOAD_ATTR, (unused/9, owner -- res2 if (oparg & 1), res)) { #if ENABLE_SPECIALIZATION _PyAttrCache *cache = (_PyAttrCache *)next_instr; if (ADAPTIVE_COUNTER_IS_ZERO(cache->counter)) { assert(cframe.use_tracing == 0); - PyObject *owner = TOP(); PyObject *name = GETITEM(names, oparg>>1); next_instr--; _Py_Specialize_LoadAttr(owner, next_instr, name); @@ -1454,26 +1452,18 @@ dummy_func( DECREMENT_ADAPTIVE_COUNTER(cache->counter); #endif /* ENABLE_SPECIALIZATION */ PyObject *name = GETITEM(names, oparg >> 1); - PyObject *owner = TOP(); if (oparg & 1) { - /* Designed to work in tandem with CALL. */ + /* Designed to work in tandem with CALL, pushes two values. */ PyObject* meth = NULL; - - int meth_found = _PyObject_GetMethod(owner, name, &meth); - - if (meth == NULL) { - /* Most likely attribute wasn't found. */ - goto error; - } - - if (meth_found) { + if (_PyObject_GetMethod(owner, name, &meth)) { /* We can bypass temporary bound method object. meth is unbound method and obj is self. meth | self | arg1 | ... | argN */ - SET_TOP(meth); - PUSH(owner); // self + assert(meth != NULL); // No errors on this branch + res2 = meth; + res = owner; // Transfer ownership } else { /* meth is not an unbound method (but a regular attr, or @@ -1483,20 +1473,18 @@ dummy_func( NULL | meth | arg1 | ... | argN */ - SET_TOP(NULL); Py_DECREF(owner); - PUSH(meth); + ERROR_IF(meth == NULL, error); + res2 = NULL; + res = meth; } } else { - PyObject *res = PyObject_GetAttr(owner, name); - if (res == NULL) { - goto error; - } + /* Classic, pushes one value. */ + res = PyObject_GetAttr(owner, name); Py_DECREF(owner); - SET_TOP(res); + ERROR_IF(res == NULL, error); } - JUMPBY(INLINE_CACHE_ENTRIES_LOAD_ATTR); } // error: LOAD_ATTR has irregular stack effect |