Skip to content

Commit 00ee6d5

Browse files
authored
GH-99298: Don't perform jumps before error handling (GH-99299)
1 parent c41b13d commit 00ee6d5

File tree

3 files changed

+40
-30
lines changed

3 files changed

+40
-30
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Fix an issue that could potentially cause incorrect error handling for some
2+
bytecode instructions.

Python/bytecodes.c

+19-15
Original file line numberDiff line numberDiff line change
@@ -1146,6 +1146,8 @@ dummy_func(
11461146
PyObject *name = GETITEM(names, oparg);
11471147
next_instr--;
11481148
if (_Py_Specialize_StoreAttr(owner, next_instr, name)) {
1149+
// "undo" the rewind so end up in the correct handler:
1150+
next_instr++;
11491151
goto error;
11501152
}
11511153
DISPATCH_SAME_OPARG();
@@ -1725,6 +1727,8 @@ dummy_func(
17251727
PyObject *name = GETITEM(names, oparg>>1);
17261728
next_instr--;
17271729
if (_Py_Specialize_LoadAttr(owner, next_instr, name)) {
1730+
// "undo" the rewind so end up in the correct handler:
1731+
next_instr++;
17281732
goto error;
17291733
}
17301734
DISPATCH_SAME_OPARG();
@@ -3113,7 +3117,6 @@ dummy_func(
31133117
PyObject *callable = PEEK(2);
31143118
DEOPT_IF(callable != (PyObject *)&PyUnicode_Type, CALL);
31153119
STAT_INC(CALL, hit);
3116-
JUMPBY(INLINE_CACHE_ENTRIES_CALL);
31173120
PyObject *arg = TOP();
31183121
PyObject *res = PyObject_Str(arg);
31193122
Py_DECREF(arg);
@@ -3123,6 +3126,7 @@ dummy_func(
31233126
if (res == NULL) {
31243127
goto error;
31253128
}
3129+
JUMPBY(INLINE_CACHE_ENTRIES_CALL);
31263130
CHECK_EVAL_BREAKER();
31273131
}
31283132

@@ -3134,7 +3138,6 @@ dummy_func(
31343138
PyObject *callable = PEEK(2);
31353139
DEOPT_IF(callable != (PyObject *)&PyTuple_Type, CALL);
31363140
STAT_INC(CALL, hit);
3137-
JUMPBY(INLINE_CACHE_ENTRIES_CALL);
31383141
PyObject *arg = TOP();
31393142
PyObject *res = PySequence_Tuple(arg);
31403143
Py_DECREF(arg);
@@ -3144,6 +3147,7 @@ dummy_func(
31443147
if (res == NULL) {
31453148
goto error;
31463149
}
3150+
JUMPBY(INLINE_CACHE_ENTRIES_CALL);
31473151
CHECK_EVAL_BREAKER();
31483152
}
31493153

@@ -3157,7 +3161,6 @@ dummy_func(
31573161
PyTypeObject *tp = (PyTypeObject *)callable;
31583162
DEOPT_IF(tp->tp_vectorcall == NULL, CALL);
31593163
STAT_INC(CALL, hit);
3160-
JUMPBY(INLINE_CACHE_ENTRIES_CALL);
31613164
STACK_SHRINK(total_args);
31623165
PyObject *res = tp->tp_vectorcall((PyObject *)tp, stack_pointer,
31633166
total_args-kwnames_len, kwnames);
@@ -3172,6 +3175,7 @@ dummy_func(
31723175
if (res == NULL) {
31733176
goto error;
31743177
}
3178+
JUMPBY(INLINE_CACHE_ENTRIES_CALL);
31753179
CHECK_EVAL_BREAKER();
31763180
}
31773181

@@ -3187,7 +3191,6 @@ dummy_func(
31873191
DEOPT_IF(!PyCFunction_CheckExact(callable), CALL);
31883192
DEOPT_IF(PyCFunction_GET_FLAGS(callable) != METH_O, CALL);
31893193
STAT_INC(CALL, hit);
3190-
JUMPBY(INLINE_CACHE_ENTRIES_CALL);
31913194
PyCFunction cfunc = PyCFunction_GET_FUNCTION(callable);
31923195
// This is slower but CPython promises to check all non-vectorcall
31933196
// function calls.
@@ -3206,6 +3209,7 @@ dummy_func(
32063209
if (res == NULL) {
32073210
goto error;
32083211
}
3212+
JUMPBY(INLINE_CACHE_ENTRIES_CALL);
32093213
CHECK_EVAL_BREAKER();
32103214
}
32113215

@@ -3221,7 +3225,6 @@ dummy_func(
32213225
DEOPT_IF(PyCFunction_GET_FLAGS(callable) != METH_FASTCALL,
32223226
CALL);
32233227
STAT_INC(CALL, hit);
3224-
JUMPBY(INLINE_CACHE_ENTRIES_CALL);
32253228
PyCFunction cfunc = PyCFunction_GET_FUNCTION(callable);
32263229
STACK_SHRINK(total_args);
32273230
/* res = func(self, args, nargs) */
@@ -3246,6 +3249,7 @@ dummy_func(
32463249
*/
32473250
goto error;
32483251
}
3252+
JUMPBY(INLINE_CACHE_ENTRIES_CALL);
32493253
CHECK_EVAL_BREAKER();
32503254
}
32513255

@@ -3260,7 +3264,6 @@ dummy_func(
32603264
DEOPT_IF(PyCFunction_GET_FLAGS(callable) !=
32613265
(METH_FASTCALL | METH_KEYWORDS), CALL);
32623266
STAT_INC(CALL, hit);
3263-
JUMPBY(INLINE_CACHE_ENTRIES_CALL);
32643267
STACK_SHRINK(total_args);
32653268
/* res = func(self, args, nargs, kwnames) */
32663269
_PyCFunctionFastWithKeywords cfunc =
@@ -3285,6 +3288,7 @@ dummy_func(
32853288
if (res == NULL) {
32863289
goto error;
32873290
}
3291+
JUMPBY(INLINE_CACHE_ENTRIES_CALL);
32883292
CHECK_EVAL_BREAKER();
32893293
}
32903294

@@ -3300,7 +3304,6 @@ dummy_func(
33003304
PyInterpreterState *interp = _PyInterpreterState_GET();
33013305
DEOPT_IF(callable != interp->callable_cache.len, CALL);
33023306
STAT_INC(CALL, hit);
3303-
JUMPBY(INLINE_CACHE_ENTRIES_CALL);
33043307
PyObject *arg = TOP();
33053308
Py_ssize_t len_i = PyObject_Length(arg);
33063309
if (len_i < 0) {
@@ -3316,6 +3319,7 @@ dummy_func(
33163319
if (res == NULL) {
33173320
goto error;
33183321
}
3322+
JUMPBY(INLINE_CACHE_ENTRIES_CALL);
33193323
}
33203324

33213325
// stack effect: (__0, __array[oparg] -- )
@@ -3330,7 +3334,6 @@ dummy_func(
33303334
PyInterpreterState *interp = _PyInterpreterState_GET();
33313335
DEOPT_IF(callable != interp->callable_cache.isinstance, CALL);
33323336
STAT_INC(CALL, hit);
3333-
JUMPBY(INLINE_CACHE_ENTRIES_CALL);
33343337
PyObject *cls = POP();
33353338
PyObject *inst = TOP();
33363339
int retval = PyObject_IsInstance(inst, cls);
@@ -3349,6 +3352,7 @@ dummy_func(
33493352
if (res == NULL) {
33503353
goto error;
33513354
}
3355+
JUMPBY(INLINE_CACHE_ENTRIES_CALL);
33523356
}
33533357

33543358
// stack effect: (__0, __array[oparg] -- )
@@ -3362,16 +3366,16 @@ dummy_func(
33623366
PyObject *list = SECOND();
33633367
DEOPT_IF(!PyList_Check(list), CALL);
33643368
STAT_INC(CALL, hit);
3365-
// CALL + POP_TOP
3366-
JUMPBY(INLINE_CACHE_ENTRIES_CALL + 1);
3367-
assert(_Py_OPCODE(next_instr[-1]) == POP_TOP);
33683369
PyObject *arg = POP();
33693370
if (_PyList_AppendTakeRef((PyListObject *)list, arg) < 0) {
33703371
goto error;
33713372
}
33723373
STACK_SHRINK(2);
33733374
Py_DECREF(list);
33743375
Py_DECREF(callable);
3376+
// CALL + POP_TOP
3377+
JUMPBY(INLINE_CACHE_ENTRIES_CALL + 1);
3378+
assert(_Py_OPCODE(next_instr[-1]) == POP_TOP);
33753379
}
33763380

33773381
// stack effect: (__0, __array[oparg] -- )
@@ -3389,7 +3393,6 @@ dummy_func(
33893393
PyObject *self = SECOND();
33903394
DEOPT_IF(!Py_IS_TYPE(self, callable->d_common.d_type), CALL);
33913395
STAT_INC(CALL, hit);
3392-
JUMPBY(INLINE_CACHE_ENTRIES_CALL);
33933396
PyCFunction cfunc = meth->ml_meth;
33943397
// This is slower but CPython promises to check all non-vectorcall
33953398
// function calls.
@@ -3407,6 +3410,7 @@ dummy_func(
34073410
if (res == NULL) {
34083411
goto error;
34093412
}
3413+
JUMPBY(INLINE_CACHE_ENTRIES_CALL);
34103414
CHECK_EVAL_BREAKER();
34113415
}
34123416

@@ -3423,7 +3427,6 @@ dummy_func(
34233427
PyObject *self = PEEK(total_args);
34243428
DEOPT_IF(!Py_IS_TYPE(self, d_type), CALL);
34253429
STAT_INC(CALL, hit);
3426-
JUMPBY(INLINE_CACHE_ENTRIES_CALL);
34273430
int nargs = total_args-1;
34283431
STACK_SHRINK(nargs);
34293432
_PyCFunctionFastWithKeywords cfunc =
@@ -3444,6 +3447,7 @@ dummy_func(
34443447
if (res == NULL) {
34453448
goto error;
34463449
}
3450+
JUMPBY(INLINE_CACHE_ENTRIES_CALL);
34473451
CHECK_EVAL_BREAKER();
34483452
}
34493453

@@ -3461,7 +3465,6 @@ dummy_func(
34613465
DEOPT_IF(!Py_IS_TYPE(self, callable->d_common.d_type), CALL);
34623466
DEOPT_IF(meth->ml_flags != METH_NOARGS, CALL);
34633467
STAT_INC(CALL, hit);
3464-
JUMPBY(INLINE_CACHE_ENTRIES_CALL);
34653468
PyCFunction cfunc = meth->ml_meth;
34663469
// This is slower but CPython promises to check all non-vectorcall
34673470
// function calls.
@@ -3478,6 +3481,7 @@ dummy_func(
34783481
if (res == NULL) {
34793482
goto error;
34803483
}
3484+
JUMPBY(INLINE_CACHE_ENTRIES_CALL);
34813485
CHECK_EVAL_BREAKER();
34823486
}
34833487

@@ -3495,7 +3499,6 @@ dummy_func(
34953499
PyObject *self = PEEK(total_args);
34963500
DEOPT_IF(!Py_IS_TYPE(self, callable->d_common.d_type), CALL);
34973501
STAT_INC(CALL, hit);
3498-
JUMPBY(INLINE_CACHE_ENTRIES_CALL);
34993502
_PyCFunctionFast cfunc =
35003503
(_PyCFunctionFast)(void(*)(void))meth->ml_meth;
35013504
int nargs = total_args-1;
@@ -3513,6 +3516,7 @@ dummy_func(
35133516
if (res == NULL) {
35143517
goto error;
35153518
}
3519+
JUMPBY(INLINE_CACHE_ENTRIES_CALL);
35163520
CHECK_EVAL_BREAKER();
35173521
}
35183522

0 commit comments

Comments
 (0)