51
51
52
52
// Dummy variables for stack effects.
53
53
static PyObject * value , * value1 , * value2 , * left , * right , * res , * sum , * prod , * sub ;
54
- static PyObject * container , * start , * stop , * v , * lhs , * rhs ;
54
+ static PyObject * container , * start , * stop , * v , * lhs , * rhs , * res2 ;
55
55
static PyObject * list , * tuple , * dict , * owner , * set , * str , * tup , * map , * keys ;
56
56
static PyObject * exit_func , * lasti , * val , * retval , * obj , * iter ;
57
57
static PyObject * aiter , * awaitable , * iterable , * w , * exc_value , * bc ;
@@ -1438,13 +1438,11 @@ dummy_func(
1438
1438
PREDICT (JUMP_BACKWARD );
1439
1439
}
1440
1440
1441
- // error: LOAD_ATTR has irregular stack effect
1442
- inst (LOAD_ATTR ) {
1441
+ inst (LOAD_ATTR , (unused /9 , owner -- res2 if (oparg & 1 ), res )) {
1443
1442
#if ENABLE_SPECIALIZATION
1444
1443
_PyAttrCache * cache = (_PyAttrCache * )next_instr ;
1445
1444
if (ADAPTIVE_COUNTER_IS_ZERO (cache -> counter )) {
1446
1445
assert (cframe .use_tracing == 0 );
1447
- PyObject * owner = TOP ();
1448
1446
PyObject * name = GETITEM (names , oparg >>1 );
1449
1447
next_instr -- ;
1450
1448
_Py_Specialize_LoadAttr (owner , next_instr , name );
@@ -1454,26 +1452,18 @@ dummy_func(
1454
1452
DECREMENT_ADAPTIVE_COUNTER (cache -> counter );
1455
1453
#endif /* ENABLE_SPECIALIZATION */
1456
1454
PyObject * name = GETITEM (names , oparg >> 1 );
1457
- PyObject * owner = TOP ();
1458
1455
if (oparg & 1 ) {
1459
- /* Designed to work in tandem with CALL. */
1456
+ /* Designed to work in tandem with CALL, pushes two values . */
1460
1457
PyObject * meth = NULL ;
1461
-
1462
- int meth_found = _PyObject_GetMethod (owner , name , & meth );
1463
-
1464
- if (meth == NULL ) {
1465
- /* Most likely attribute wasn't found. */
1466
- goto error ;
1467
- }
1468
-
1469
- if (meth_found ) {
1458
+ if (_PyObject_GetMethod (owner , name , & meth )) {
1470
1459
/* We can bypass temporary bound method object.
1471
1460
meth is unbound method and obj is self.
1472
1461
1473
1462
meth | self | arg1 | ... | argN
1474
1463
*/
1475
- SET_TOP (meth );
1476
- PUSH (owner ); // self
1464
+ assert (meth != NULL ); // No errors on this branch
1465
+ res2 = meth ;
1466
+ res = owner ; // Transfer ownership
1477
1467
}
1478
1468
else {
1479
1469
/* meth is not an unbound method (but a regular attr, or
@@ -1483,20 +1473,18 @@ dummy_func(
1483
1473
1484
1474
NULL | meth | arg1 | ... | argN
1485
1475
*/
1486
- SET_TOP (NULL );
1487
1476
Py_DECREF (owner );
1488
- PUSH (meth );
1477
+ ERROR_IF (meth == NULL , error );
1478
+ res2 = NULL ;
1479
+ res = meth ;
1489
1480
}
1490
1481
}
1491
1482
else {
1492
- PyObject * res = PyObject_GetAttr (owner , name );
1493
- if (res == NULL ) {
1494
- goto error ;
1495
- }
1483
+ /* Classic, pushes one value. */
1484
+ res = PyObject_GetAttr (owner , name );
1496
1485
Py_DECREF (owner );
1497
- SET_TOP (res );
1486
+ ERROR_IF (res == NULL , error );
1498
1487
}
1499
- JUMPBY (INLINE_CACHE_ENTRIES_LOAD_ATTR );
1500
1488
}
1501
1489
1502
1490
// error: LOAD_ATTR has irregular stack effect
0 commit comments