Skip to content

Commit d094e42

Browse files
pythonGH-98831: Remove all remaining DISPATCH() calls from bytecodes.c (python#99271)
Also mark those opcodes that have no stack effect as such. Co-authored-by: Brandt Bucher <[email protected]>
1 parent 1aa0124 commit d094e42

File tree

2 files changed

+175
-169
lines changed

2 files changed

+175
-169
lines changed

Python/bytecodes.c

Lines changed: 88 additions & 94 deletions
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,6 @@ do { \
6868
#define JUMPBY(offset) ((void)0)
6969
#define GO_TO_INSTRUCTION(instname) ((void)0)
7070
#define DISPATCH_SAME_OPARG() ((void)0)
71-
#define DISPATCH() ((void)0)
7271

7372
#define inst(name, ...) case name:
7473
#define super(name) static int SUPER_##name
@@ -102,10 +101,6 @@ dummy_func(
102101

103102
switch (opcode) {
104103

105-
/* BEWARE!
106-
It is essential that any operation that fails must goto error
107-
and that all operation that succeed call DISPATCH() ! */
108-
109104
// BEGIN BYTECODES //
110105
inst(NOP, (--)) {
111106
}
@@ -150,16 +145,14 @@ dummy_func(
150145
super(LOAD_FAST__LOAD_CONST) = LOAD_FAST + LOAD_CONST;
151146
super(STORE_FAST__LOAD_FAST) = STORE_FAST + LOAD_FAST;
152147
super(STORE_FAST__STORE_FAST) = STORE_FAST + STORE_FAST;
153-
super (LOAD_CONST__LOAD_FAST) = LOAD_CONST + LOAD_FAST;
148+
super(LOAD_CONST__LOAD_FAST) = LOAD_CONST + LOAD_FAST;
154149

155150
inst(POP_TOP, (value --)) {
156151
Py_DECREF(value);
157152
}
158153

159-
// stack effect: ( -- __0)
160-
inst(PUSH_NULL) {
161-
/* Use BASIC_PUSH as NULL is not a valid object pointer */
162-
BASIC_PUSH(NULL);
154+
inst(PUSH_NULL, (-- res)) {
155+
res = NULL;
163156
}
164157

165158
inst(END_FOR, (value1, value2 --)) {
@@ -807,11 +800,12 @@ dummy_func(
807800
Py_DECREF(receiver);
808801
SET_TOP(retval);
809802
JUMPBY(oparg);
810-
DISPATCH();
811803
}
812-
assert(gen_status == PYGEN_NEXT);
813-
assert(retval != NULL);
814-
PUSH(retval);
804+
else {
805+
assert(gen_status == PYGEN_NEXT);
806+
assert(retval != NULL);
807+
PUSH(retval);
808+
}
815809
}
816810

817811
// stack effect: ( -- )
@@ -904,7 +898,6 @@ dummy_func(
904898
if (PyErr_GivenExceptionMatches(val, PyExc_StopAsyncIteration)) {
905899
Py_DECREF(val);
906900
Py_DECREF(POP());
907-
DISPATCH();
908901
}
909902
else {
910903
PyObject *exc = Py_NewRef(PyExceptionInstance_Class(val));
@@ -926,12 +919,13 @@ dummy_func(
926919
Py_DECREF(POP()); // The last sent value.
927920
Py_DECREF(POP()); // The delegated sub-iterator.
928921
PUSH(value);
929-
DISPATCH();
930922
}
931-
PyObject *exc_type = Py_NewRef(Py_TYPE(exc_value));
932-
PyObject *exc_traceback = PyException_GetTraceback(exc_value);
933-
_PyErr_Restore(tstate, exc_type, Py_NewRef(exc_value), exc_traceback);
934-
goto exception_unwind;
923+
else {
924+
PyObject *exc_type = Py_NewRef(Py_TYPE(exc_value));
925+
PyObject *exc_traceback = PyException_GetTraceback(exc_value);
926+
_PyErr_Restore(tstate, exc_type, Py_NewRef(exc_value), exc_traceback);
927+
goto exception_unwind;
928+
}
935929
}
936930

937931
inst(STOPITERATION_ERROR) {
@@ -973,7 +967,6 @@ dummy_func(
973967
PyException_SetContext(error, exc);
974968
Py_DECREF(message);
975969
}
976-
DISPATCH();
977970
}
978971

979972

@@ -1031,8 +1024,7 @@ dummy_func(
10311024
goto error;
10321025
}
10331026

1034-
// stack effect: ( -- )
1035-
inst(DELETE_NAME) {
1027+
inst(DELETE_NAME, (--)) {
10361028
PyObject *name = GETITEM(names, oparg);
10371029
PyObject *ns = LOCALS();
10381030
int err;
@@ -1042,6 +1034,7 @@ dummy_func(
10421034
goto error;
10431035
}
10441036
err = PyObject_DelItem(ns, name);
1037+
// Can't use ERROR_IF here.
10451038
if (err != 0) {
10461039
format_exc_check_arg(tstate, PyExc_NameError,
10471040
NAME_ERROR_MSG,
@@ -1181,11 +1174,11 @@ dummy_func(
11811174
goto error;
11821175
}
11831176

1184-
// stack effect: ( -- )
1185-
inst(DELETE_GLOBAL) {
1177+
inst(DELETE_GLOBAL, (--)) {
11861178
PyObject *name = GETITEM(names, oparg);
11871179
int err;
11881180
err = PyDict_DelItem(GLOBALS(), name);
1181+
// Can't use ERROR_IF here.
11891182
if (err != 0) {
11901183
if (_PyErr_ExceptionMatches(tstate, PyExc_KeyError)) {
11911184
format_exc_check_arg(tstate, PyExc_NameError,
@@ -1365,18 +1358,13 @@ dummy_func(
13651358
SET_TOP(Py_NewRef(res));
13661359
}
13671360

1368-
// stack effect: ( -- )
1369-
inst(DELETE_FAST) {
1361+
inst(DELETE_FAST, (--)) {
13701362
PyObject *v = GETLOCAL(oparg);
1371-
if (v != NULL) {
1372-
SETLOCAL(oparg, NULL);
1373-
DISPATCH();
1374-
}
1375-
goto unbound_local_error;
1363+
ERROR_IF(v == NULL, unbound_local_error);
1364+
SETLOCAL(oparg, NULL);
13761365
}
13771366

1378-
// stack effect: ( -- )
1379-
inst(MAKE_CELL) {
1367+
inst(MAKE_CELL, (--)) {
13801368
// "initial" is probably NULL but not if it's an arg (or set
13811369
// via PyFrame_LocalsToFast() before MAKE_CELL has run).
13821370
PyObject *initial = GETLOCAL(oparg);
@@ -1387,17 +1375,17 @@ dummy_func(
13871375
SETLOCAL(oparg, cell);
13881376
}
13891377

1390-
// stack effect: ( -- )
1391-
inst(DELETE_DEREF) {
1378+
inst(DELETE_DEREF, (--)) {
13921379
PyObject *cell = GETLOCAL(oparg);
13931380
PyObject *oldobj = PyCell_GET(cell);
1394-
if (oldobj != NULL) {
1395-
PyCell_SET(cell, NULL);
1396-
Py_DECREF(oldobj);
1397-
DISPATCH();
1381+
// Can't use ERROR_IF here.
1382+
// Fortunately we don't need its superpower.
1383+
if (oldobj == NULL) {
1384+
format_exc_unbound(tstate, frame->f_code, oparg);
1385+
goto error;
13981386
}
1399-
format_exc_unbound(tstate, frame->f_code, oparg);
1400-
goto error;
1387+
PyCell_SET(cell, NULL);
1388+
Py_DECREF(oldobj);
14011389
}
14021390

14031391
// stack effect: ( -- __0)
@@ -1760,15 +1748,15 @@ dummy_func(
17601748
Py_DECREF(owner);
17611749
PUSH(meth);
17621750
}
1763-
JUMPBY(INLINE_CACHE_ENTRIES_LOAD_ATTR);
1764-
DISPATCH();
17651751
}
1766-
PyObject *res = PyObject_GetAttr(owner, name);
1767-
if (res == NULL) {
1768-
goto error;
1752+
else {
1753+
PyObject *res = PyObject_GetAttr(owner, name);
1754+
if (res == NULL) {
1755+
goto error;
1756+
}
1757+
Py_DECREF(owner);
1758+
SET_TOP(res);
17691759
}
1770-
Py_DECREF(owner);
1771-
SET_TOP(res);
17721760
JUMPBY(INLINE_CACHE_ENTRIES_LOAD_ATTR);
17731761
}
17741762

@@ -2426,21 +2414,23 @@ dummy_func(
24262414
if (Py_IsTrue(cond)) {
24272415
STACK_SHRINK(1);
24282416
_Py_DECREF_NO_DEALLOC(cond);
2429-
DISPATCH();
24302417
}
2431-
if (Py_IsFalse(cond)) {
2418+
else if (Py_IsFalse(cond)) {
24322419
JUMPBY(oparg);
2433-
DISPATCH();
24342420
}
2435-
err = PyObject_IsTrue(cond);
2436-
if (err > 0) {
2437-
STACK_SHRINK(1);
2438-
Py_DECREF(cond);
2421+
else {
2422+
err = PyObject_IsTrue(cond);
2423+
if (err > 0) {
2424+
STACK_SHRINK(1);
2425+
Py_DECREF(cond);
2426+
}
2427+
else if (err == 0) {
2428+
JUMPBY(oparg);
2429+
}
2430+
else {
2431+
goto error;
2432+
}
24392433
}
2440-
else if (err == 0)
2441-
JUMPBY(oparg);
2442-
else
2443-
goto error;
24442434
}
24452435

24462436
// error: JUMP_IF_TRUE_OR_POP stack effect depends on jump flag
@@ -2450,22 +2440,23 @@ dummy_func(
24502440
if (Py_IsFalse(cond)) {
24512441
STACK_SHRINK(1);
24522442
_Py_DECREF_NO_DEALLOC(cond);
2453-
DISPATCH();
2454-
}
2455-
if (Py_IsTrue(cond)) {
2456-
JUMPBY(oparg);
2457-
DISPATCH();
24582443
}
2459-
err = PyObject_IsTrue(cond);
2460-
if (err > 0) {
2444+
else if (Py_IsTrue(cond)) {
24612445
JUMPBY(oparg);
24622446
}
2463-
else if (err == 0) {
2464-
STACK_SHRINK(1);
2465-
Py_DECREF(cond);
2447+
else {
2448+
err = PyObject_IsTrue(cond);
2449+
if (err > 0) {
2450+
JUMPBY(oparg);
2451+
}
2452+
else if (err == 0) {
2453+
STACK_SHRINK(1);
2454+
Py_DECREF(cond);
2455+
}
2456+
else {
2457+
goto error;
2458+
}
24662459
}
2467-
else
2468-
goto error;
24692460
}
24702461

24712462
// stack effect: ( -- )
@@ -2606,23 +2597,24 @@ dummy_func(
26062597
if (next != NULL) {
26072598
PUSH(next);
26082599
JUMPBY(INLINE_CACHE_ENTRIES_FOR_ITER);
2609-
DISPATCH();
26102600
}
2611-
if (_PyErr_Occurred(tstate)) {
2612-
if (!_PyErr_ExceptionMatches(tstate, PyExc_StopIteration)) {
2613-
goto error;
2614-
}
2615-
else if (tstate->c_tracefunc != NULL) {
2616-
call_exc_trace(tstate->c_tracefunc, tstate->c_traceobj, tstate, frame);
2601+
else {
2602+
if (_PyErr_Occurred(tstate)) {
2603+
if (!_PyErr_ExceptionMatches(tstate, PyExc_StopIteration)) {
2604+
goto error;
2605+
}
2606+
else if (tstate->c_tracefunc != NULL) {
2607+
call_exc_trace(tstate->c_tracefunc, tstate->c_traceobj, tstate, frame);
2608+
}
2609+
_PyErr_Clear(tstate);
26172610
}
2618-
_PyErr_Clear(tstate);
2611+
/* iterator ended normally */
2612+
assert(_Py_OPCODE(next_instr[INLINE_CACHE_ENTRIES_FOR_ITER + oparg]) == END_FOR);
2613+
STACK_SHRINK(1);
2614+
Py_DECREF(iter);
2615+
/* Skip END_FOR */
2616+
JUMPBY(INLINE_CACHE_ENTRIES_FOR_ITER + oparg + 1);
26192617
}
2620-
/* iterator ended normally */
2621-
assert(_Py_OPCODE(next_instr[INLINE_CACHE_ENTRIES_FOR_ITER + oparg]) == END_FOR);
2622-
STACK_SHRINK(1);
2623-
Py_DECREF(iter);
2624-
/* Skip END_FOR */
2625-
JUMPBY(INLINE_CACHE_ENTRIES_FOR_ITER + oparg + 1);
26262618
}
26272619

26282620
// stack effect: ( -- __0)
@@ -2637,14 +2629,15 @@ dummy_func(
26372629
PyObject *next = PyList_GET_ITEM(seq, it->it_index++);
26382630
PUSH(Py_NewRef(next));
26392631
JUMPBY(INLINE_CACHE_ENTRIES_FOR_ITER);
2640-
DISPATCH();
2632+
goto end_for_iter_list; // End of this instruction
26412633
}
26422634
it->it_seq = NULL;
26432635
Py_DECREF(seq);
26442636
}
26452637
STACK_SHRINK(1);
26462638
Py_DECREF(it);
26472639
JUMPBY(INLINE_CACHE_ENTRIES_FOR_ITER + oparg + 1);
2640+
end_for_iter_list:
26482641
}
26492642

26502643
// stack effect: ( -- __0)
@@ -2659,15 +2652,16 @@ dummy_func(
26592652
STACK_SHRINK(1);
26602653
Py_DECREF(r);
26612654
JUMPBY(INLINE_CACHE_ENTRIES_FOR_ITER + oparg + 1);
2662-
DISPATCH();
26632655
}
2664-
long value = (long)(r->start +
2665-
(unsigned long)(r->index++) * r->step);
2666-
if (_PyLong_AssignValue(&GETLOCAL(_Py_OPARG(next)), value) < 0) {
2667-
goto error;
2656+
else {
2657+
long value = (long)(r->start +
2658+
(unsigned long)(r->index++) * r->step);
2659+
if (_PyLong_AssignValue(&GETLOCAL(_Py_OPARG(next)), value) < 0) {
2660+
goto error;
2661+
}
2662+
// The STORE_FAST is already done.
2663+
JUMPBY(INLINE_CACHE_ENTRIES_FOR_ITER + 1);
26682664
}
2669-
// The STORE_FAST is already done.
2670-
JUMPBY(INLINE_CACHE_ENTRIES_FOR_ITER + 1);
26712665
}
26722666

26732667
inst(FOR_ITER_GEN) {

0 commit comments

Comments
 (0)