summaryrefslogtreecommitdiffstats
path: root/Python/bytecodes.c
diff options
context:
space:
mode:
authorGuido van Rossum <guido@python.org>2023-01-30 01:28:39 (GMT)
committerGitHub <noreply@github.com>2023-01-30 01:28:39 (GMT)
commitf5a3d91b6c56ddff4644b5a5ac34d8c6d23d7c79 (patch)
treee66618346f1d30c9041239f6c93f6aeaaa319401 /Python/bytecodes.c
parentc4170c36b0b54c10456f4b49245f570023a97f72 (diff)
downloadcpython-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.c38
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