From 8e02ed8f317fb8247700732244ea64af0eb4bb27 Mon Sep 17 00:00:00 2001 From: Mark Shannon Date: Wed, 21 Jun 2023 06:40:59 +0100 Subject: [PATCH 1/4] Check eval-breaker in ENTER_EXECUTOR. --- Python/bytecodes.c | 15 +- Python/ceval_macros.h | 4 +- Python/generated_cases.c.h | 343 +++++++++++++++++++------------------ 3 files changed, 183 insertions(+), 179 deletions(-) diff --git a/Python/bytecodes.c b/Python/bytecodes.c index 02857104f5a4d5..c34dc568b646ed 100644 --- a/Python/bytecodes.c +++ b/Python/bytecodes.c @@ -142,8 +142,8 @@ dummy_func( ERROR_IF(err, error); next_instr--; } - else if (_Py_atomic_load_relaxed_int32(&tstate->interp->ceval.eval_breaker) && oparg < 2) { - goto handle_eval_breaker; + else if (oparg < 2) { + CHECK_EVAL_BREAKER(); } } @@ -159,6 +159,9 @@ dummy_func( next_instr--; } else { + if (oparg < 2) { + CHECK_EVAL_BREAKER(); + } _PyFrame_SetStackPointer(frame, stack_pointer); int err = _Py_call_instrumentation( tstate, oparg > 0, frame, next_instr-1); @@ -169,9 +172,6 @@ dummy_func( next_instr = frame->prev_instr; DISPATCH(); } - if (_Py_atomic_load_relaxed_int32(&tstate->interp->ceval.eval_breaker) && oparg < 2) { - goto handle_eval_breaker; - } } } @@ -2143,6 +2143,7 @@ dummy_func( } inst(JUMP_BACKWARD, (--)) { + CHECK_EVAL_BREAKER(); _Py_CODEUNIT *here = next_instr - 1; assert(oparg <= INSTR_OFFSET()); JUMPBY(1-oparg); @@ -2160,7 +2161,6 @@ dummy_func( goto resume_frame; } #endif /* ENABLE_SPECIALIZATION */ - CHECK_EVAL_BREAKER(); } pseudo(JUMP) = { @@ -2174,6 +2174,7 @@ dummy_func( }; inst(ENTER_EXECUTOR, (--)) { + CHECK_EVAL_BREAKER(); PyCodeObject *code = _PyFrame_GetCode(frame); _PyExecutorObject *executor = (_PyExecutorObject *)code->co_executors->executors[oparg&255]; Py_INCREF(executor); @@ -3512,8 +3513,8 @@ dummy_func( } inst(INSTRUMENTED_JUMP_BACKWARD, ( -- )) { - INSTRUMENTED_JUMP(next_instr-1, next_instr+1-oparg, PY_MONITORING_EVENT_JUMP); CHECK_EVAL_BREAKER(); + INSTRUMENTED_JUMP(next_instr-1, next_instr+1-oparg, PY_MONITORING_EVENT_JUMP); } inst(INSTRUMENTED_POP_JUMP_IF_TRUE, ( -- )) { diff --git a/Python/ceval_macros.h b/Python/ceval_macros.h index 0d41ef5a14cef4..72800aaaaa2ac4 100644 --- a/Python/ceval_macros.h +++ b/Python/ceval_macros.h @@ -117,7 +117,9 @@ #define CHECK_EVAL_BREAKER() \ _Py_CHECK_EMSCRIPTEN_SIGNALS_PERIODICALLY(); \ if (_Py_atomic_load_relaxed_int32(&tstate->interp->ceval.eval_breaker)) { \ - goto handle_eval_breaker; \ + if (_Py_HandlePending(tstate) != 0) { \ + goto error; \ + } \ } diff --git a/Python/generated_cases.c.h b/Python/generated_cases.c.h index 43cfd4a882c73a..6005b153c1b631 100644 --- a/Python/generated_cases.c.h +++ b/Python/generated_cases.c.h @@ -17,8 +17,8 @@ if (err) goto error; next_instr--; } - else if (_Py_atomic_load_relaxed_int32(&tstate->interp->ceval.eval_breaker) && oparg < 2) { - goto handle_eval_breaker; + else if (oparg < 2) { + CHECK_EVAL_BREAKER(); } #line 24 "Python/generated_cases.c.h" DISPATCH(); @@ -37,6 +37,9 @@ next_instr--; } else { + if (oparg < 2) { + CHECK_EVAL_BREAKER(); + } _PyFrame_SetStackPointer(frame, stack_pointer); int err = _Py_call_instrumentation( tstate, oparg > 0, frame, next_instr-1); @@ -47,9 +50,6 @@ next_instr = frame->prev_instr; DISPATCH(); } - if (_Py_atomic_load_relaxed_int32(&tstate->interp->ceval.eval_breaker) && oparg < 2) { - goto handle_eval_breaker; - } } #line 55 "Python/generated_cases.c.h" DISPATCH(); @@ -3065,6 +3065,7 @@ TARGET(JUMP_BACKWARD) { #line 2146 "Python/bytecodes.c" + CHECK_EVAL_BREAKER(); _Py_CODEUNIT *here = next_instr - 1; assert(oparg <= INSTR_OFFSET()); JUMPBY(1-oparg); @@ -3082,13 +3083,13 @@ goto resume_frame; } #endif /* ENABLE_SPECIALIZATION */ - #line 3086 "Python/generated_cases.c.h" - CHECK_EVAL_BREAKER(); + #line 3087 "Python/generated_cases.c.h" DISPATCH(); } TARGET(ENTER_EXECUTOR) { #line 2177 "Python/bytecodes.c" + CHECK_EVAL_BREAKER(); PyCodeObject *code = _PyFrame_GetCode(frame); _PyExecutorObject *executor = (_PyExecutorObject *)code->co_executors->executors[oparg&255]; Py_INCREF(executor); @@ -3098,20 +3099,20 @@ goto resume_with_error; } goto resume_frame; - #line 3102 "Python/generated_cases.c.h" + #line 3103 "Python/generated_cases.c.h" } TARGET(POP_JUMP_IF_FALSE) { PyObject *cond = stack_pointer[-1]; - #line 2189 "Python/bytecodes.c" + #line 2190 "Python/bytecodes.c" if (Py_IsFalse(cond)) { JUMPBY(oparg); } else if (!Py_IsTrue(cond)) { int err = PyObject_IsTrue(cond); - #line 3113 "Python/generated_cases.c.h" + #line 3114 "Python/generated_cases.c.h" Py_DECREF(cond); - #line 2195 "Python/bytecodes.c" + #line 2196 "Python/bytecodes.c" if (err == 0) { JUMPBY(oparg); } @@ -3119,22 +3120,22 @@ if (err < 0) goto pop_1_error; } } - #line 3123 "Python/generated_cases.c.h" + #line 3124 "Python/generated_cases.c.h" STACK_SHRINK(1); DISPATCH(); } TARGET(POP_JUMP_IF_TRUE) { PyObject *cond = stack_pointer[-1]; - #line 2205 "Python/bytecodes.c" + #line 2206 "Python/bytecodes.c" if (Py_IsTrue(cond)) { JUMPBY(oparg); } else if (!Py_IsFalse(cond)) { int err = PyObject_IsTrue(cond); - #line 3136 "Python/generated_cases.c.h" + #line 3137 "Python/generated_cases.c.h" Py_DECREF(cond); - #line 2211 "Python/bytecodes.c" + #line 2212 "Python/bytecodes.c" if (err > 0) { JUMPBY(oparg); } @@ -3142,63 +3143,63 @@ if (err < 0) goto pop_1_error; } } - #line 3146 "Python/generated_cases.c.h" + #line 3147 "Python/generated_cases.c.h" STACK_SHRINK(1); DISPATCH(); } TARGET(POP_JUMP_IF_NOT_NONE) { PyObject *value = stack_pointer[-1]; - #line 2221 "Python/bytecodes.c" + #line 2222 "Python/bytecodes.c" if (!Py_IsNone(value)) { - #line 3155 "Python/generated_cases.c.h" + #line 3156 "Python/generated_cases.c.h" Py_DECREF(value); - #line 2223 "Python/bytecodes.c" + #line 2224 "Python/bytecodes.c" JUMPBY(oparg); } - #line 3160 "Python/generated_cases.c.h" + #line 3161 "Python/generated_cases.c.h" STACK_SHRINK(1); DISPATCH(); } TARGET(POP_JUMP_IF_NONE) { PyObject *value = stack_pointer[-1]; - #line 2228 "Python/bytecodes.c" + #line 2229 "Python/bytecodes.c" if (Py_IsNone(value)) { JUMPBY(oparg); } else { - #line 3172 "Python/generated_cases.c.h" + #line 3173 "Python/generated_cases.c.h" Py_DECREF(value); - #line 2233 "Python/bytecodes.c" + #line 2234 "Python/bytecodes.c" } - #line 3176 "Python/generated_cases.c.h" + #line 3177 "Python/generated_cases.c.h" STACK_SHRINK(1); DISPATCH(); } TARGET(JUMP_BACKWARD_NO_INTERRUPT) { - #line 2237 "Python/bytecodes.c" + #line 2238 "Python/bytecodes.c" /* This bytecode is used in the `yield from` or `await` loop. * If there is an interrupt, we want it handled in the innermost * generator or coroutine, so we deliberately do not check it here. * (see bpo-30039). */ JUMPBY(-oparg); - #line 3189 "Python/generated_cases.c.h" + #line 3190 "Python/generated_cases.c.h" DISPATCH(); } TARGET(GET_LEN) { PyObject *obj = stack_pointer[-1]; PyObject *len_o; - #line 2246 "Python/bytecodes.c" + #line 2247 "Python/bytecodes.c" // PUSH(len(TOS)) Py_ssize_t len_i = PyObject_Length(obj); if (len_i < 0) goto error; len_o = PyLong_FromSsize_t(len_i); if (len_o == NULL) goto error; - #line 3202 "Python/generated_cases.c.h" + #line 3203 "Python/generated_cases.c.h" STACK_GROW(1); stack_pointer[-1] = len_o; DISPATCH(); @@ -3209,16 +3210,16 @@ PyObject *type = stack_pointer[-2]; PyObject *subject = stack_pointer[-3]; PyObject *attrs; - #line 2254 "Python/bytecodes.c" + #line 2255 "Python/bytecodes.c" // Pop TOS and TOS1. Set TOS to a tuple of attributes on success, or // None on failure. assert(PyTuple_CheckExact(names)); attrs = match_class(tstate, subject, type, oparg, names); - #line 3218 "Python/generated_cases.c.h" + #line 3219 "Python/generated_cases.c.h" Py_DECREF(subject); Py_DECREF(type); Py_DECREF(names); - #line 2259 "Python/bytecodes.c" + #line 2260 "Python/bytecodes.c" if (attrs) { assert(PyTuple_CheckExact(attrs)); // Success! } @@ -3226,7 +3227,7 @@ if (_PyErr_Occurred(tstate)) goto pop_3_error; attrs = Py_None; // Failure! } - #line 3230 "Python/generated_cases.c.h" + #line 3231 "Python/generated_cases.c.h" STACK_SHRINK(2); stack_pointer[-1] = attrs; DISPATCH(); @@ -3235,10 +3236,10 @@ TARGET(MATCH_MAPPING) { PyObject *subject = stack_pointer[-1]; PyObject *res; - #line 2269 "Python/bytecodes.c" + #line 2270 "Python/bytecodes.c" int match = Py_TYPE(subject)->tp_flags & Py_TPFLAGS_MAPPING; res = match ? Py_True : Py_False; - #line 3242 "Python/generated_cases.c.h" + #line 3243 "Python/generated_cases.c.h" STACK_GROW(1); stack_pointer[-1] = res; DISPATCH(); @@ -3247,10 +3248,10 @@ TARGET(MATCH_SEQUENCE) { PyObject *subject = stack_pointer[-1]; PyObject *res; - #line 2274 "Python/bytecodes.c" + #line 2275 "Python/bytecodes.c" int match = Py_TYPE(subject)->tp_flags & Py_TPFLAGS_SEQUENCE; res = match ? Py_True : Py_False; - #line 3254 "Python/generated_cases.c.h" + #line 3255 "Python/generated_cases.c.h" STACK_GROW(1); stack_pointer[-1] = res; DISPATCH(); @@ -3260,11 +3261,11 @@ PyObject *keys = stack_pointer[-1]; PyObject *subject = stack_pointer[-2]; PyObject *values_or_none; - #line 2279 "Python/bytecodes.c" + #line 2280 "Python/bytecodes.c" // On successful match, PUSH(values). Otherwise, PUSH(None). values_or_none = match_keys(tstate, subject, keys); if (values_or_none == NULL) goto error; - #line 3268 "Python/generated_cases.c.h" + #line 3269 "Python/generated_cases.c.h" STACK_GROW(1); stack_pointer[-1] = values_or_none; DISPATCH(); @@ -3273,14 +3274,14 @@ TARGET(GET_ITER) { PyObject *iterable = stack_pointer[-1]; PyObject *iter; - #line 2285 "Python/bytecodes.c" + #line 2286 "Python/bytecodes.c" /* before: [obj]; after [getiter(obj)] */ iter = PyObject_GetIter(iterable); - #line 3280 "Python/generated_cases.c.h" + #line 3281 "Python/generated_cases.c.h" Py_DECREF(iterable); - #line 2288 "Python/bytecodes.c" + #line 2289 "Python/bytecodes.c" if (iter == NULL) goto pop_1_error; - #line 3284 "Python/generated_cases.c.h" + #line 3285 "Python/generated_cases.c.h" stack_pointer[-1] = iter; DISPATCH(); } @@ -3288,7 +3289,7 @@ TARGET(GET_YIELD_FROM_ITER) { PyObject *iterable = stack_pointer[-1]; PyObject *iter; - #line 2292 "Python/bytecodes.c" + #line 2293 "Python/bytecodes.c" /* before: [obj]; after [getiter(obj)] */ if (PyCoro_CheckExact(iterable)) { /* `iterable` is a coroutine */ @@ -3311,11 +3312,11 @@ if (iter == NULL) { goto error; } - #line 3315 "Python/generated_cases.c.h" + #line 3316 "Python/generated_cases.c.h" Py_DECREF(iterable); - #line 2315 "Python/bytecodes.c" + #line 2316 "Python/bytecodes.c" } - #line 3319 "Python/generated_cases.c.h" + #line 3320 "Python/generated_cases.c.h" stack_pointer[-1] = iter; DISPATCH(); } @@ -3325,7 +3326,7 @@ static_assert(INLINE_CACHE_ENTRIES_FOR_ITER == 1, "incorrect cache size"); PyObject *iter = stack_pointer[-1]; PyObject *next; - #line 2333 "Python/bytecodes.c" + #line 2334 "Python/bytecodes.c" #if ENABLE_SPECIALIZATION _PyForIterCache *cache = (_PyForIterCache *)next_instr; if (ADAPTIVE_COUNTER_IS_ZERO(cache->counter)) { @@ -3357,7 +3358,7 @@ DISPATCH(); } // Common case: no jump, leave it to the code generator - #line 3361 "Python/generated_cases.c.h" + #line 3362 "Python/generated_cases.c.h" STACK_GROW(1); stack_pointer[-1] = next; next_instr += 1; @@ -3365,7 +3366,7 @@ } TARGET(INSTRUMENTED_FOR_ITER) { - #line 2367 "Python/bytecodes.c" + #line 2368 "Python/bytecodes.c" _Py_CODEUNIT *here = next_instr-1; _Py_CODEUNIT *target; PyObject *iter = TOP(); @@ -3391,14 +3392,14 @@ target = next_instr + INLINE_CACHE_ENTRIES_FOR_ITER + oparg + 1; } INSTRUMENTED_JUMP(here, target, PY_MONITORING_EVENT_BRANCH); - #line 3395 "Python/generated_cases.c.h" + #line 3396 "Python/generated_cases.c.h" DISPATCH(); } TARGET(FOR_ITER_LIST) { PyObject *iter = stack_pointer[-1]; PyObject *next; - #line 2395 "Python/bytecodes.c" + #line 2396 "Python/bytecodes.c" DEOPT_IF(Py_TYPE(iter) != &PyListIter_Type, FOR_ITER); _PyListIterObject *it = (_PyListIterObject *)iter; STAT_INC(FOR_ITER, hit); @@ -3419,7 +3420,7 @@ DISPATCH(); end_for_iter_list: // Common case: no jump, leave it to the code generator - #line 3423 "Python/generated_cases.c.h" + #line 3424 "Python/generated_cases.c.h" STACK_GROW(1); stack_pointer[-1] = next; next_instr += 1; @@ -3429,7 +3430,7 @@ TARGET(FOR_ITER_TUPLE) { PyObject *iter = stack_pointer[-1]; PyObject *next; - #line 2418 "Python/bytecodes.c" + #line 2419 "Python/bytecodes.c" _PyTupleIterObject *it = (_PyTupleIterObject *)iter; DEOPT_IF(Py_TYPE(it) != &PyTupleIter_Type, FOR_ITER); STAT_INC(FOR_ITER, hit); @@ -3450,7 +3451,7 @@ DISPATCH(); end_for_iter_tuple: // Common case: no jump, leave it to the code generator - #line 3454 "Python/generated_cases.c.h" + #line 3455 "Python/generated_cases.c.h" STACK_GROW(1); stack_pointer[-1] = next; next_instr += 1; @@ -3460,7 +3461,7 @@ TARGET(FOR_ITER_RANGE) { PyObject *iter = stack_pointer[-1]; PyObject *next; - #line 2441 "Python/bytecodes.c" + #line 2442 "Python/bytecodes.c" _PyRangeIterObject *r = (_PyRangeIterObject *)iter; DEOPT_IF(Py_TYPE(r) != &PyRangeIter_Type, FOR_ITER); STAT_INC(FOR_ITER, hit); @@ -3479,7 +3480,7 @@ if (next == NULL) { goto error; } - #line 3483 "Python/generated_cases.c.h" + #line 3484 "Python/generated_cases.c.h" STACK_GROW(1); stack_pointer[-1] = next; next_instr += 1; @@ -3488,7 +3489,7 @@ TARGET(FOR_ITER_GEN) { PyObject *iter = stack_pointer[-1]; - #line 2462 "Python/bytecodes.c" + #line 2463 "Python/bytecodes.c" DEOPT_IF(tstate->interp->eval_frame, FOR_ITER); PyGenObject *gen = (PyGenObject *)iter; DEOPT_IF(Py_TYPE(gen) != &PyGen_Type, FOR_ITER); @@ -3504,14 +3505,14 @@ assert(next_instr[oparg].op.code == END_FOR || next_instr[oparg].op.code == INSTRUMENTED_END_FOR); DISPATCH_INLINED(gen_frame); - #line 3508 "Python/generated_cases.c.h" + #line 3509 "Python/generated_cases.c.h" } TARGET(BEFORE_ASYNC_WITH) { PyObject *mgr = stack_pointer[-1]; PyObject *exit; PyObject *res; - #line 2480 "Python/bytecodes.c" + #line 2481 "Python/bytecodes.c" PyObject *enter = _PyObject_LookupSpecial(mgr, &_Py_ID(__aenter__)); if (enter == NULL) { if (!_PyErr_Occurred(tstate)) { @@ -3534,16 +3535,16 @@ Py_DECREF(enter); goto error; } - #line 3538 "Python/generated_cases.c.h" + #line 3539 "Python/generated_cases.c.h" Py_DECREF(mgr); - #line 2503 "Python/bytecodes.c" + #line 2504 "Python/bytecodes.c" res = _PyObject_CallNoArgs(enter); Py_DECREF(enter); if (res == NULL) { Py_DECREF(exit); if (true) goto pop_1_error; } - #line 3547 "Python/generated_cases.c.h" + #line 3548 "Python/generated_cases.c.h" STACK_GROW(1); stack_pointer[-1] = res; stack_pointer[-2] = exit; @@ -3554,7 +3555,7 @@ PyObject *mgr = stack_pointer[-1]; PyObject *exit; PyObject *res; - #line 2512 "Python/bytecodes.c" + #line 2513 "Python/bytecodes.c" /* pop the context manager, push its __exit__ and the * value returned from calling its __enter__ */ @@ -3580,16 +3581,16 @@ Py_DECREF(enter); goto error; } - #line 3584 "Python/generated_cases.c.h" + #line 3585 "Python/generated_cases.c.h" Py_DECREF(mgr); - #line 2538 "Python/bytecodes.c" + #line 2539 "Python/bytecodes.c" res = _PyObject_CallNoArgs(enter); Py_DECREF(enter); if (res == NULL) { Py_DECREF(exit); if (true) goto pop_1_error; } - #line 3593 "Python/generated_cases.c.h" + #line 3594 "Python/generated_cases.c.h" STACK_GROW(1); stack_pointer[-1] = res; stack_pointer[-2] = exit; @@ -3601,7 +3602,7 @@ PyObject *lasti = stack_pointer[-3]; PyObject *exit_func = stack_pointer[-4]; PyObject *res; - #line 2547 "Python/bytecodes.c" + #line 2548 "Python/bytecodes.c" /* At the top of the stack are 4 values: - val: TOP = exc_info() - unused: SECOND = previous exception @@ -3622,7 +3623,7 @@ res = PyObject_Vectorcall(exit_func, stack + 1, 3 | PY_VECTORCALL_ARGUMENTS_OFFSET, NULL); if (res == NULL) goto error; - #line 3626 "Python/generated_cases.c.h" + #line 3627 "Python/generated_cases.c.h" STACK_GROW(1); stack_pointer[-1] = res; DISPATCH(); @@ -3631,7 +3632,7 @@ TARGET(PUSH_EXC_INFO) { PyObject *new_exc = stack_pointer[-1]; PyObject *prev_exc; - #line 2586 "Python/bytecodes.c" + #line 2587 "Python/bytecodes.c" _PyErr_StackItem *exc_info = tstate->exc_info; if (exc_info->exc_value != NULL) { prev_exc = exc_info->exc_value; @@ -3641,7 +3642,7 @@ } assert(PyExceptionInstance_Check(new_exc)); exc_info->exc_value = Py_NewRef(new_exc); - #line 3645 "Python/generated_cases.c.h" + #line 3646 "Python/generated_cases.c.h" STACK_GROW(1); stack_pointer[-1] = new_exc; stack_pointer[-2] = prev_exc; @@ -3655,7 +3656,7 @@ uint32_t type_version = read_u32(&next_instr[1].cache); uint32_t keys_version = read_u32(&next_instr[3].cache); PyObject *descr = read_obj(&next_instr[5].cache); - #line 2598 "Python/bytecodes.c" + #line 2599 "Python/bytecodes.c" /* Cached method object */ PyTypeObject *self_cls = Py_TYPE(self); assert(type_version != 0); @@ -3672,7 +3673,7 @@ assert(_PyType_HasFeature(Py_TYPE(res2), Py_TPFLAGS_METHOD_DESCRIPTOR)); res = self; assert(oparg & 1); - #line 3676 "Python/generated_cases.c.h" + #line 3677 "Python/generated_cases.c.h" STACK_GROW(((oparg & 1) ? 1 : 0)); stack_pointer[-1] = res; if (oparg & 1) { stack_pointer[-(1 + ((oparg & 1) ? 1 : 0))] = res2; } @@ -3686,7 +3687,7 @@ PyObject *res; uint32_t type_version = read_u32(&next_instr[1].cache); PyObject *descr = read_obj(&next_instr[5].cache); - #line 2617 "Python/bytecodes.c" + #line 2618 "Python/bytecodes.c" PyTypeObject *self_cls = Py_TYPE(self); DEOPT_IF(self_cls->tp_version_tag != type_version, LOAD_ATTR); assert(self_cls->tp_dictoffset == 0); @@ -3696,7 +3697,7 @@ res2 = Py_NewRef(descr); res = self; assert(oparg & 1); - #line 3700 "Python/generated_cases.c.h" + #line 3701 "Python/generated_cases.c.h" STACK_GROW(((oparg & 1) ? 1 : 0)); stack_pointer[-1] = res; if (oparg & 1) { stack_pointer[-(1 + ((oparg & 1) ? 1 : 0))] = res2; } @@ -3710,7 +3711,7 @@ PyObject *res; uint32_t type_version = read_u32(&next_instr[1].cache); PyObject *descr = read_obj(&next_instr[5].cache); - #line 2629 "Python/bytecodes.c" + #line 2630 "Python/bytecodes.c" PyTypeObject *self_cls = Py_TYPE(self); DEOPT_IF(self_cls->tp_version_tag != type_version, LOAD_ATTR); Py_ssize_t dictoffset = self_cls->tp_dictoffset; @@ -3724,7 +3725,7 @@ res2 = Py_NewRef(descr); res = self; assert(oparg & 1); - #line 3728 "Python/generated_cases.c.h" + #line 3729 "Python/generated_cases.c.h" STACK_GROW(((oparg & 1) ? 1 : 0)); stack_pointer[-1] = res; if (oparg & 1) { stack_pointer[-(1 + ((oparg & 1) ? 1 : 0))] = res2; } @@ -3733,16 +3734,16 @@ } TARGET(KW_NAMES) { - #line 2645 "Python/bytecodes.c" + #line 2646 "Python/bytecodes.c" assert(kwnames == NULL); assert(oparg < PyTuple_GET_SIZE(FRAME_CO_CONSTS)); kwnames = GETITEM(FRAME_CO_CONSTS, oparg); - #line 3741 "Python/generated_cases.c.h" + #line 3742 "Python/generated_cases.c.h" DISPATCH(); } TARGET(INSTRUMENTED_CALL) { - #line 2651 "Python/bytecodes.c" + #line 2652 "Python/bytecodes.c" int is_meth = PEEK(oparg+2) != NULL; int total_args = oparg + is_meth; PyObject *function = PEEK(total_args + 1); @@ -3755,7 +3756,7 @@ _PyCallCache *cache = (_PyCallCache *)next_instr; INCREMENT_ADAPTIVE_COUNTER(cache->counter); GO_TO_INSTRUCTION(CALL); - #line 3759 "Python/generated_cases.c.h" + #line 3760 "Python/generated_cases.c.h" } TARGET(CALL) { @@ -3765,7 +3766,7 @@ PyObject *callable = stack_pointer[-(1 + oparg)]; PyObject *method = stack_pointer[-(2 + oparg)]; PyObject *res; - #line 2697 "Python/bytecodes.c" + #line 2698 "Python/bytecodes.c" int is_meth = method != NULL; int total_args = oparg; if (is_meth) { @@ -3847,7 +3848,7 @@ Py_DECREF(args[i]); } if (res == NULL) { STACK_SHRINK(oparg); goto pop_2_error; } - #line 3851 "Python/generated_cases.c.h" + #line 3852 "Python/generated_cases.c.h" STACK_SHRINK(oparg); STACK_SHRINK(1); stack_pointer[-1] = res; @@ -3859,7 +3860,7 @@ TARGET(CALL_BOUND_METHOD_EXACT_ARGS) { PyObject *callable = stack_pointer[-(1 + oparg)]; PyObject *method = stack_pointer[-(2 + oparg)]; - #line 2785 "Python/bytecodes.c" + #line 2786 "Python/bytecodes.c" DEOPT_IF(method != NULL, CALL); DEOPT_IF(Py_TYPE(callable) != &PyMethod_Type, CALL); STAT_INC(CALL, hit); @@ -3869,7 +3870,7 @@ PEEK(oparg + 2) = Py_NewRef(meth); // method Py_DECREF(callable); GO_TO_INSTRUCTION(CALL_PY_EXACT_ARGS); - #line 3873 "Python/generated_cases.c.h" + #line 3874 "Python/generated_cases.c.h" } TARGET(CALL_PY_EXACT_ARGS) { @@ -3878,7 +3879,7 @@ PyObject *callable = stack_pointer[-(1 + oparg)]; PyObject *method = stack_pointer[-(2 + oparg)]; uint32_t func_version = read_u32(&next_instr[1].cache); - #line 2797 "Python/bytecodes.c" + #line 2798 "Python/bytecodes.c" assert(kwnames == NULL); DEOPT_IF(tstate->interp->eval_frame, CALL); int is_meth = method != NULL; @@ -3904,7 +3905,7 @@ SKIP_OVER(INLINE_CACHE_ENTRIES_CALL); frame->return_offset = 0; DISPATCH_INLINED(new_frame); - #line 3908 "Python/generated_cases.c.h" + #line 3909 "Python/generated_cases.c.h" } TARGET(CALL_PY_WITH_DEFAULTS) { @@ -3912,7 +3913,7 @@ PyObject *callable = stack_pointer[-(1 + oparg)]; PyObject *method = stack_pointer[-(2 + oparg)]; uint32_t func_version = read_u32(&next_instr[1].cache); - #line 2825 "Python/bytecodes.c" + #line 2826 "Python/bytecodes.c" assert(kwnames == NULL); DEOPT_IF(tstate->interp->eval_frame, CALL); int is_meth = method != NULL; @@ -3948,7 +3949,7 @@ SKIP_OVER(INLINE_CACHE_ENTRIES_CALL); frame->return_offset = 0; DISPATCH_INLINED(new_frame); - #line 3952 "Python/generated_cases.c.h" + #line 3953 "Python/generated_cases.c.h" } TARGET(CALL_NO_KW_TYPE_1) { @@ -3956,7 +3957,7 @@ PyObject *callable = stack_pointer[-(1 + oparg)]; PyObject *null = stack_pointer[-(2 + oparg)]; PyObject *res; - #line 2863 "Python/bytecodes.c" + #line 2864 "Python/bytecodes.c" assert(kwnames == NULL); assert(oparg == 1); DEOPT_IF(null != NULL, CALL); @@ -3966,7 +3967,7 @@ res = Py_NewRef(Py_TYPE(obj)); Py_DECREF(obj); Py_DECREF(&PyType_Type); // I.e., callable - #line 3970 "Python/generated_cases.c.h" + #line 3971 "Python/generated_cases.c.h" STACK_SHRINK(oparg); STACK_SHRINK(1); stack_pointer[-1] = res; @@ -3979,7 +3980,7 @@ PyObject *callable = stack_pointer[-(1 + oparg)]; PyObject *null = stack_pointer[-(2 + oparg)]; PyObject *res; - #line 2875 "Python/bytecodes.c" + #line 2876 "Python/bytecodes.c" assert(kwnames == NULL); assert(oparg == 1); DEOPT_IF(null != NULL, CALL); @@ -3990,7 +3991,7 @@ Py_DECREF(arg); Py_DECREF(&PyUnicode_Type); // I.e., callable if (res == NULL) { STACK_SHRINK(oparg); goto pop_2_error; } - #line 3994 "Python/generated_cases.c.h" + #line 3995 "Python/generated_cases.c.h" STACK_SHRINK(oparg); STACK_SHRINK(1); stack_pointer[-1] = res; @@ -4004,7 +4005,7 @@ PyObject *callable = stack_pointer[-(1 + oparg)]; PyObject *null = stack_pointer[-(2 + oparg)]; PyObject *res; - #line 2889 "Python/bytecodes.c" + #line 2890 "Python/bytecodes.c" assert(kwnames == NULL); assert(oparg == 1); DEOPT_IF(null != NULL, CALL); @@ -4015,7 +4016,7 @@ Py_DECREF(arg); Py_DECREF(&PyTuple_Type); // I.e., tuple if (res == NULL) { STACK_SHRINK(oparg); goto pop_2_error; } - #line 4019 "Python/generated_cases.c.h" + #line 4020 "Python/generated_cases.c.h" STACK_SHRINK(oparg); STACK_SHRINK(1); stack_pointer[-1] = res; @@ -4028,7 +4029,7 @@ PyObject **args = (stack_pointer - oparg); PyObject *callable = stack_pointer[-(1 + oparg)]; PyObject *null = stack_pointer[-(2 + oparg)]; - #line 2903 "Python/bytecodes.c" + #line 2904 "Python/bytecodes.c" /* This instruction does the following: * 1. Creates the object (by calling ``object.__new__``) * 2. Pushes a shim frame to the frame stack (to cleanup after ``__init__``) @@ -4078,12 +4079,12 @@ frame = cframe.current_frame = init_frame; CALL_STAT_INC(inlined_py_calls); goto start_frame; - #line 4082 "Python/generated_cases.c.h" + #line 4083 "Python/generated_cases.c.h" } TARGET(EXIT_INIT_CHECK) { PyObject *should_be_none = stack_pointer[-1]; - #line 2955 "Python/bytecodes.c" + #line 2956 "Python/bytecodes.c" assert(STACK_LEVEL() == 2); if (should_be_none != Py_None) { PyErr_Format(PyExc_TypeError, @@ -4091,7 +4092,7 @@ Py_TYPE(should_be_none)->tp_name); goto error; } - #line 4095 "Python/generated_cases.c.h" + #line 4096 "Python/generated_cases.c.h" STACK_SHRINK(1); DISPATCH(); } @@ -4101,7 +4102,7 @@ PyObject *callable = stack_pointer[-(1 + oparg)]; PyObject *method = stack_pointer[-(2 + oparg)]; PyObject *res; - #line 2965 "Python/bytecodes.c" + #line 2966 "Python/bytecodes.c" int is_meth = method != NULL; int total_args = oparg; if (is_meth) { @@ -4123,7 +4124,7 @@ } Py_DECREF(tp); if (res == NULL) { STACK_SHRINK(oparg); goto pop_2_error; } - #line 4127 "Python/generated_cases.c.h" + #line 4128 "Python/generated_cases.c.h" STACK_SHRINK(oparg); STACK_SHRINK(1); stack_pointer[-1] = res; @@ -4137,7 +4138,7 @@ PyObject *callable = stack_pointer[-(1 + oparg)]; PyObject *method = stack_pointer[-(2 + oparg)]; PyObject *res; - #line 2990 "Python/bytecodes.c" + #line 2991 "Python/bytecodes.c" /* Builtin METH_O functions */ assert(kwnames == NULL); int is_meth = method != NULL; @@ -4165,7 +4166,7 @@ Py_DECREF(arg); Py_DECREF(callable); if (res == NULL) { STACK_SHRINK(oparg); goto pop_2_error; } - #line 4169 "Python/generated_cases.c.h" + #line 4170 "Python/generated_cases.c.h" STACK_SHRINK(oparg); STACK_SHRINK(1); stack_pointer[-1] = res; @@ -4179,7 +4180,7 @@ PyObject *callable = stack_pointer[-(1 + oparg)]; PyObject *method = stack_pointer[-(2 + oparg)]; PyObject *res; - #line 3021 "Python/bytecodes.c" + #line 3022 "Python/bytecodes.c" /* Builtin METH_FASTCALL functions, without keywords */ assert(kwnames == NULL); int is_meth = method != NULL; @@ -4211,7 +4212,7 @@ 'invalid'). In those cases an exception is set, so we must handle it. */ - #line 4215 "Python/generated_cases.c.h" + #line 4216 "Python/generated_cases.c.h" STACK_SHRINK(oparg); STACK_SHRINK(1); stack_pointer[-1] = res; @@ -4225,7 +4226,7 @@ PyObject *callable = stack_pointer[-(1 + oparg)]; PyObject *method = stack_pointer[-(2 + oparg)]; PyObject *res; - #line 3056 "Python/bytecodes.c" + #line 3057 "Python/bytecodes.c" /* Builtin METH_FASTCALL | METH_KEYWORDS functions */ int is_meth = method != NULL; int total_args = oparg; @@ -4257,7 +4258,7 @@ } Py_DECREF(callable); if (res == NULL) { STACK_SHRINK(oparg); goto pop_2_error; } - #line 4261 "Python/generated_cases.c.h" + #line 4262 "Python/generated_cases.c.h" STACK_SHRINK(oparg); STACK_SHRINK(1); stack_pointer[-1] = res; @@ -4271,7 +4272,7 @@ PyObject *callable = stack_pointer[-(1 + oparg)]; PyObject *method = stack_pointer[-(2 + oparg)]; PyObject *res; - #line 3091 "Python/bytecodes.c" + #line 3092 "Python/bytecodes.c" assert(kwnames == NULL); /* len(o) */ int is_meth = method != NULL; @@ -4296,7 +4297,7 @@ Py_DECREF(callable); Py_DECREF(arg); if (res == NULL) { STACK_SHRINK(oparg); goto pop_2_error; } - #line 4300 "Python/generated_cases.c.h" + #line 4301 "Python/generated_cases.c.h" STACK_SHRINK(oparg); STACK_SHRINK(1); stack_pointer[-1] = res; @@ -4309,7 +4310,7 @@ PyObject *callable = stack_pointer[-(1 + oparg)]; PyObject *method = stack_pointer[-(2 + oparg)]; PyObject *res; - #line 3118 "Python/bytecodes.c" + #line 3119 "Python/bytecodes.c" assert(kwnames == NULL); /* isinstance(o, o2) */ int is_meth = method != NULL; @@ -4336,7 +4337,7 @@ Py_DECREF(cls); Py_DECREF(callable); if (res == NULL) { STACK_SHRINK(oparg); goto pop_2_error; } - #line 4340 "Python/generated_cases.c.h" + #line 4341 "Python/generated_cases.c.h" STACK_SHRINK(oparg); STACK_SHRINK(1); stack_pointer[-1] = res; @@ -4348,7 +4349,7 @@ PyObject **args = (stack_pointer - oparg); PyObject *self = stack_pointer[-(1 + oparg)]; PyObject *method = stack_pointer[-(2 + oparg)]; - #line 3148 "Python/bytecodes.c" + #line 3149 "Python/bytecodes.c" assert(kwnames == NULL); assert(oparg == 1); assert(method != NULL); @@ -4366,14 +4367,14 @@ SKIP_OVER(INLINE_CACHE_ENTRIES_CALL + 1); assert(next_instr[-1].op.code == POP_TOP); DISPATCH(); - #line 4370 "Python/generated_cases.c.h" + #line 4371 "Python/generated_cases.c.h" } TARGET(CALL_NO_KW_METHOD_DESCRIPTOR_O) { PyObject **args = (stack_pointer - oparg); PyObject *method = stack_pointer[-(2 + oparg)]; PyObject *res; - #line 3168 "Python/bytecodes.c" + #line 3169 "Python/bytecodes.c" assert(kwnames == NULL); int is_meth = method != NULL; int total_args = oparg; @@ -4404,7 +4405,7 @@ Py_DECREF(arg); Py_DECREF(callable); if (res == NULL) { STACK_SHRINK(oparg); goto pop_2_error; } - #line 4408 "Python/generated_cases.c.h" + #line 4409 "Python/generated_cases.c.h" STACK_SHRINK(oparg); STACK_SHRINK(1); stack_pointer[-1] = res; @@ -4417,7 +4418,7 @@ PyObject **args = (stack_pointer - oparg); PyObject *method = stack_pointer[-(2 + oparg)]; PyObject *res; - #line 3202 "Python/bytecodes.c" + #line 3203 "Python/bytecodes.c" int is_meth = method != NULL; int total_args = oparg; if (is_meth) { @@ -4446,7 +4447,7 @@ } Py_DECREF(callable); if (res == NULL) { STACK_SHRINK(oparg); goto pop_2_error; } - #line 4450 "Python/generated_cases.c.h" + #line 4451 "Python/generated_cases.c.h" STACK_SHRINK(oparg); STACK_SHRINK(1); stack_pointer[-1] = res; @@ -4459,7 +4460,7 @@ PyObject **args = (stack_pointer - oparg); PyObject *method = stack_pointer[-(2 + oparg)]; PyObject *res; - #line 3234 "Python/bytecodes.c" + #line 3235 "Python/bytecodes.c" assert(kwnames == NULL); assert(oparg == 0 || oparg == 1); int is_meth = method != NULL; @@ -4488,7 +4489,7 @@ Py_DECREF(self); Py_DECREF(callable); if (res == NULL) { STACK_SHRINK(oparg); goto pop_2_error; } - #line 4492 "Python/generated_cases.c.h" + #line 4493 "Python/generated_cases.c.h" STACK_SHRINK(oparg); STACK_SHRINK(1); stack_pointer[-1] = res; @@ -4501,7 +4502,7 @@ PyObject **args = (stack_pointer - oparg); PyObject *method = stack_pointer[-(2 + oparg)]; PyObject *res; - #line 3266 "Python/bytecodes.c" + #line 3267 "Python/bytecodes.c" assert(kwnames == NULL); int is_meth = method != NULL; int total_args = oparg; @@ -4529,7 +4530,7 @@ } Py_DECREF(callable); if (res == NULL) { STACK_SHRINK(oparg); goto pop_2_error; } - #line 4533 "Python/generated_cases.c.h" + #line 4534 "Python/generated_cases.c.h" STACK_SHRINK(oparg); STACK_SHRINK(1); stack_pointer[-1] = res; @@ -4539,9 +4540,9 @@ } TARGET(INSTRUMENTED_CALL_FUNCTION_EX) { - #line 3297 "Python/bytecodes.c" + #line 3298 "Python/bytecodes.c" GO_TO_INSTRUCTION(CALL_FUNCTION_EX); - #line 4545 "Python/generated_cases.c.h" + #line 4546 "Python/generated_cases.c.h" } TARGET(CALL_FUNCTION_EX) { @@ -4550,7 +4551,7 @@ PyObject *callargs = stack_pointer[-(1 + ((oparg & 1) ? 1 : 0))]; PyObject *func = stack_pointer[-(2 + ((oparg & 1) ? 1 : 0))]; PyObject *result; - #line 3301 "Python/bytecodes.c" + #line 3302 "Python/bytecodes.c" // DICT_MERGE is called before this opcode if there are kwargs. // It converts all dict subtypes in kwargs into regular dicts. assert(kwargs == NULL || PyDict_CheckExact(kwargs)); @@ -4612,14 +4613,14 @@ } result = PyObject_Call(func, callargs, kwargs); } - #line 4616 "Python/generated_cases.c.h" + #line 4617 "Python/generated_cases.c.h" Py_DECREF(func); Py_DECREF(callargs); Py_XDECREF(kwargs); - #line 3363 "Python/bytecodes.c" + #line 3364 "Python/bytecodes.c" assert(PEEK(3 + (oparg & 1)) == NULL); if (result == NULL) { STACK_SHRINK(((oparg & 1) ? 1 : 0)); goto pop_3_error; } - #line 4623 "Python/generated_cases.c.h" + #line 4624 "Python/generated_cases.c.h" STACK_SHRINK(((oparg & 1) ? 1 : 0)); STACK_SHRINK(2); stack_pointer[-1] = result; @@ -4630,7 +4631,7 @@ TARGET(MAKE_FUNCTION) { PyObject *codeobj = stack_pointer[-1]; PyObject *func; - #line 3369 "Python/bytecodes.c" + #line 3370 "Python/bytecodes.c" PyFunctionObject *func_obj = (PyFunctionObject *) PyFunction_New(codeobj, GLOBALS()); @@ -4642,7 +4643,7 @@ func_obj->func_version = ((PyCodeObject *)codeobj)->co_version; func = (PyObject *)func_obj; - #line 4646 "Python/generated_cases.c.h" + #line 4647 "Python/generated_cases.c.h" stack_pointer[-1] = func; DISPATCH(); } @@ -4650,7 +4651,7 @@ TARGET(SET_FUNCTION_ATTRIBUTE) { PyObject *func = stack_pointer[-1]; PyObject *attr = stack_pointer[-2]; - #line 3383 "Python/bytecodes.c" + #line 3384 "Python/bytecodes.c" assert(PyFunction_Check(func)); PyFunctionObject *func_obj = (PyFunctionObject *)func; switch(oparg) { @@ -4675,14 +4676,14 @@ default: Py_UNREACHABLE(); } - #line 4679 "Python/generated_cases.c.h" + #line 4680 "Python/generated_cases.c.h" STACK_SHRINK(1); stack_pointer[-1] = func; DISPATCH(); } TARGET(RETURN_GENERATOR) { - #line 3410 "Python/bytecodes.c" + #line 3411 "Python/bytecodes.c" assert(PyFunction_Check(frame->f_funcobj)); PyFunctionObject *func = (PyFunctionObject *)frame->f_funcobj; PyGenObject *gen = (PyGenObject *)_Py_MakeCoro(func); @@ -4703,7 +4704,7 @@ frame = cframe.current_frame = prev; _PyFrame_StackPush(frame, (PyObject *)gen); goto resume_frame; - #line 4707 "Python/generated_cases.c.h" + #line 4708 "Python/generated_cases.c.h" } TARGET(BUILD_SLICE) { @@ -4711,15 +4712,15 @@ PyObject *stop = stack_pointer[-(1 + ((oparg == 3) ? 1 : 0))]; PyObject *start = stack_pointer[-(2 + ((oparg == 3) ? 1 : 0))]; PyObject *slice; - #line 3433 "Python/bytecodes.c" + #line 3434 "Python/bytecodes.c" slice = PySlice_New(start, stop, step); - #line 4717 "Python/generated_cases.c.h" + #line 4718 "Python/generated_cases.c.h" Py_DECREF(start); Py_DECREF(stop); Py_XDECREF(step); - #line 3435 "Python/bytecodes.c" + #line 3436 "Python/bytecodes.c" if (slice == NULL) { STACK_SHRINK(((oparg == 3) ? 1 : 0)); goto pop_2_error; } - #line 4723 "Python/generated_cases.c.h" + #line 4724 "Python/generated_cases.c.h" STACK_SHRINK(((oparg == 3) ? 1 : 0)); STACK_SHRINK(1); stack_pointer[-1] = slice; @@ -4729,14 +4730,14 @@ TARGET(CONVERT_VALUE) { PyObject *value = stack_pointer[-1]; PyObject *result; - #line 3439 "Python/bytecodes.c" + #line 3440 "Python/bytecodes.c" convertion_func_ptr conv_fn; assert(oparg >= FVC_STR && oparg <= FVC_ASCII); conv_fn = CONVERSION_FUNCTIONS[oparg]; result = conv_fn(value); Py_DECREF(value); if (result == NULL) goto pop_1_error; - #line 4740 "Python/generated_cases.c.h" + #line 4741 "Python/generated_cases.c.h" stack_pointer[-1] = result; DISPATCH(); } @@ -4744,7 +4745,7 @@ TARGET(FORMAT_SIMPLE) { PyObject *value = stack_pointer[-1]; PyObject *res; - #line 3448 "Python/bytecodes.c" + #line 3449 "Python/bytecodes.c" /* If value is a unicode object, then we know the result * of format(value) is value itself. */ if (!PyUnicode_CheckExact(value)) { @@ -4755,7 +4756,7 @@ else { res = value; } - #line 4759 "Python/generated_cases.c.h" + #line 4760 "Python/generated_cases.c.h" stack_pointer[-1] = res; DISPATCH(); } @@ -4764,12 +4765,12 @@ PyObject *fmt_spec = stack_pointer[-1]; PyObject *value = stack_pointer[-2]; PyObject *res; - #line 3461 "Python/bytecodes.c" + #line 3462 "Python/bytecodes.c" res = PyObject_Format(value, fmt_spec); Py_DECREF(value); Py_DECREF(fmt_spec); if (res == NULL) goto pop_2_error; - #line 4773 "Python/generated_cases.c.h" + #line 4774 "Python/generated_cases.c.h" STACK_SHRINK(1); stack_pointer[-1] = res; DISPATCH(); @@ -4778,10 +4779,10 @@ TARGET(COPY) { PyObject *bottom = stack_pointer[-(1 + (oparg-1))]; PyObject *top; - #line 3468 "Python/bytecodes.c" + #line 3469 "Python/bytecodes.c" assert(oparg > 0); top = Py_NewRef(bottom); - #line 4785 "Python/generated_cases.c.h" + #line 4786 "Python/generated_cases.c.h" STACK_GROW(1); stack_pointer[-1] = top; DISPATCH(); @@ -4793,7 +4794,7 @@ PyObject *rhs = stack_pointer[-1]; PyObject *lhs = stack_pointer[-2]; PyObject *res; - #line 3473 "Python/bytecodes.c" + #line 3474 "Python/bytecodes.c" #if ENABLE_SPECIALIZATION _PyBinaryOpCache *cache = (_PyBinaryOpCache *)next_instr; if (ADAPTIVE_COUNTER_IS_ZERO(cache->counter)) { @@ -4808,12 +4809,12 @@ assert((unsigned)oparg < Py_ARRAY_LENGTH(binary_ops)); assert(binary_ops[oparg]); res = binary_ops[oparg](lhs, rhs); - #line 4812 "Python/generated_cases.c.h" + #line 4813 "Python/generated_cases.c.h" Py_DECREF(lhs); Py_DECREF(rhs); - #line 3488 "Python/bytecodes.c" + #line 3489 "Python/bytecodes.c" if (res == NULL) goto pop_2_error; - #line 4817 "Python/generated_cases.c.h" + #line 4818 "Python/generated_cases.c.h" STACK_SHRINK(1); stack_pointer[-1] = res; next_instr += 1; @@ -4823,16 +4824,16 @@ TARGET(SWAP) { PyObject *top = stack_pointer[-1]; PyObject *bottom = stack_pointer[-(2 + (oparg-2))]; - #line 3493 "Python/bytecodes.c" + #line 3494 "Python/bytecodes.c" assert(oparg >= 2); - #line 4829 "Python/generated_cases.c.h" + #line 4830 "Python/generated_cases.c.h" stack_pointer[-1] = bottom; stack_pointer[-(2 + (oparg-2))] = top; DISPATCH(); } TARGET(INSTRUMENTED_INSTRUCTION) { - #line 3497 "Python/bytecodes.c" + #line 3498 "Python/bytecodes.c" int next_opcode = _Py_call_instrumentation_instruction( tstate, frame, next_instr-1); if (next_opcode < 0) goto error; @@ -4844,26 +4845,26 @@ assert(next_opcode > 0 && next_opcode < 256); opcode = next_opcode; DISPATCH_GOTO(); - #line 4848 "Python/generated_cases.c.h" + #line 4849 "Python/generated_cases.c.h" } TARGET(INSTRUMENTED_JUMP_FORWARD) { - #line 3511 "Python/bytecodes.c" + #line 3512 "Python/bytecodes.c" INSTRUMENTED_JUMP(next_instr-1, next_instr+oparg, PY_MONITORING_EVENT_JUMP); - #line 4854 "Python/generated_cases.c.h" + #line 4855 "Python/generated_cases.c.h" DISPATCH(); } TARGET(INSTRUMENTED_JUMP_BACKWARD) { - #line 3515 "Python/bytecodes.c" - INSTRUMENTED_JUMP(next_instr-1, next_instr+1-oparg, PY_MONITORING_EVENT_JUMP); - #line 4861 "Python/generated_cases.c.h" + #line 3516 "Python/bytecodes.c" CHECK_EVAL_BREAKER(); + INSTRUMENTED_JUMP(next_instr-1, next_instr+1-oparg, PY_MONITORING_EVENT_JUMP); + #line 4863 "Python/generated_cases.c.h" DISPATCH(); } TARGET(INSTRUMENTED_POP_JUMP_IF_TRUE) { - #line 3520 "Python/bytecodes.c" + #line 3521 "Python/bytecodes.c" PyObject *cond = POP(); int err = PyObject_IsTrue(cond); Py_DECREF(cond); @@ -4872,12 +4873,12 @@ assert(err == 0 || err == 1); int offset = err*oparg; INSTRUMENTED_JUMP(here, next_instr + offset, PY_MONITORING_EVENT_BRANCH); - #line 4876 "Python/generated_cases.c.h" + #line 4877 "Python/generated_cases.c.h" DISPATCH(); } TARGET(INSTRUMENTED_POP_JUMP_IF_FALSE) { - #line 3531 "Python/bytecodes.c" + #line 3532 "Python/bytecodes.c" PyObject *cond = POP(); int err = PyObject_IsTrue(cond); Py_DECREF(cond); @@ -4886,12 +4887,12 @@ assert(err == 0 || err == 1); int offset = (1-err)*oparg; INSTRUMENTED_JUMP(here, next_instr + offset, PY_MONITORING_EVENT_BRANCH); - #line 4890 "Python/generated_cases.c.h" + #line 4891 "Python/generated_cases.c.h" DISPATCH(); } TARGET(INSTRUMENTED_POP_JUMP_IF_NONE) { - #line 3542 "Python/bytecodes.c" + #line 3543 "Python/bytecodes.c" PyObject *value = POP(); _Py_CODEUNIT *here = next_instr-1; int offset; @@ -4903,12 +4904,12 @@ offset = 0; } INSTRUMENTED_JUMP(here, next_instr + offset, PY_MONITORING_EVENT_BRANCH); - #line 4907 "Python/generated_cases.c.h" + #line 4908 "Python/generated_cases.c.h" DISPATCH(); } TARGET(INSTRUMENTED_POP_JUMP_IF_NOT_NONE) { - #line 3556 "Python/bytecodes.c" + #line 3557 "Python/bytecodes.c" PyObject *value = POP(); _Py_CODEUNIT *here = next_instr-1; int offset; @@ -4920,30 +4921,30 @@ offset = oparg; } INSTRUMENTED_JUMP(here, next_instr + offset, PY_MONITORING_EVENT_BRANCH); - #line 4924 "Python/generated_cases.c.h" + #line 4925 "Python/generated_cases.c.h" DISPATCH(); } TARGET(EXTENDED_ARG) { - #line 3570 "Python/bytecodes.c" + #line 3571 "Python/bytecodes.c" assert(oparg); opcode = next_instr->op.code; oparg = oparg << 8 | next_instr->op.arg; PRE_DISPATCH_GOTO(); DISPATCH_GOTO(); - #line 4935 "Python/generated_cases.c.h" + #line 4936 "Python/generated_cases.c.h" } TARGET(CACHE) { - #line 3578 "Python/bytecodes.c" + #line 3579 "Python/bytecodes.c" assert(0 && "Executing a cache."); Py_UNREACHABLE(); - #line 4942 "Python/generated_cases.c.h" + #line 4943 "Python/generated_cases.c.h" } TARGET(RESERVED) { - #line 3583 "Python/bytecodes.c" + #line 3584 "Python/bytecodes.c" assert(0 && "Executing RESERVED instruction."); Py_UNREACHABLE(); - #line 4949 "Python/generated_cases.c.h" + #line 4950 "Python/generated_cases.c.h" } From f2cf146451a6a4cd0e3e846286b1451d13b67ecb Mon Sep 17 00:00:00 2001 From: Mark Shannon Date: Wed, 21 Jun 2023 06:51:10 +0100 Subject: [PATCH 2/4] Make sure that frame->prev_instr is set before entering executor. --- Python/bytecodes.c | 2 + Python/generated_cases.c.h | 328 +++++++++++++++++++------------------ Python/opcode_metadata.h | 2 +- 3 files changed, 168 insertions(+), 164 deletions(-) diff --git a/Python/bytecodes.c b/Python/bytecodes.c index c34dc568b646ed..7eb4cd66da8146 100644 --- a/Python/bytecodes.c +++ b/Python/bytecodes.c @@ -2175,6 +2175,8 @@ dummy_func( inst(ENTER_EXECUTOR, (--)) { CHECK_EVAL_BREAKER(); + JUMPBY(1-oparg); + frame->prev_instr = next_instr - 1; PyCodeObject *code = _PyFrame_GetCode(frame); _PyExecutorObject *executor = (_PyExecutorObject *)code->co_executors->executors[oparg&255]; Py_INCREF(executor); diff --git a/Python/generated_cases.c.h b/Python/generated_cases.c.h index 6005b153c1b631..528ff19dc95064 100644 --- a/Python/generated_cases.c.h +++ b/Python/generated_cases.c.h @@ -3090,6 +3090,8 @@ TARGET(ENTER_EXECUTOR) { #line 2177 "Python/bytecodes.c" CHECK_EVAL_BREAKER(); + JUMPBY(1-oparg); + frame->prev_instr = next_instr - 1; PyCodeObject *code = _PyFrame_GetCode(frame); _PyExecutorObject *executor = (_PyExecutorObject *)code->co_executors->executors[oparg&255]; Py_INCREF(executor); @@ -3099,20 +3101,20 @@ goto resume_with_error; } goto resume_frame; - #line 3103 "Python/generated_cases.c.h" + #line 3105 "Python/generated_cases.c.h" } TARGET(POP_JUMP_IF_FALSE) { PyObject *cond = stack_pointer[-1]; - #line 2190 "Python/bytecodes.c" + #line 2192 "Python/bytecodes.c" if (Py_IsFalse(cond)) { JUMPBY(oparg); } else if (!Py_IsTrue(cond)) { int err = PyObject_IsTrue(cond); - #line 3114 "Python/generated_cases.c.h" + #line 3116 "Python/generated_cases.c.h" Py_DECREF(cond); - #line 2196 "Python/bytecodes.c" + #line 2198 "Python/bytecodes.c" if (err == 0) { JUMPBY(oparg); } @@ -3120,22 +3122,22 @@ if (err < 0) goto pop_1_error; } } - #line 3124 "Python/generated_cases.c.h" + #line 3126 "Python/generated_cases.c.h" STACK_SHRINK(1); DISPATCH(); } TARGET(POP_JUMP_IF_TRUE) { PyObject *cond = stack_pointer[-1]; - #line 2206 "Python/bytecodes.c" + #line 2208 "Python/bytecodes.c" if (Py_IsTrue(cond)) { JUMPBY(oparg); } else if (!Py_IsFalse(cond)) { int err = PyObject_IsTrue(cond); - #line 3137 "Python/generated_cases.c.h" + #line 3139 "Python/generated_cases.c.h" Py_DECREF(cond); - #line 2212 "Python/bytecodes.c" + #line 2214 "Python/bytecodes.c" if (err > 0) { JUMPBY(oparg); } @@ -3143,63 +3145,63 @@ if (err < 0) goto pop_1_error; } } - #line 3147 "Python/generated_cases.c.h" + #line 3149 "Python/generated_cases.c.h" STACK_SHRINK(1); DISPATCH(); } TARGET(POP_JUMP_IF_NOT_NONE) { PyObject *value = stack_pointer[-1]; - #line 2222 "Python/bytecodes.c" + #line 2224 "Python/bytecodes.c" if (!Py_IsNone(value)) { - #line 3156 "Python/generated_cases.c.h" + #line 3158 "Python/generated_cases.c.h" Py_DECREF(value); - #line 2224 "Python/bytecodes.c" + #line 2226 "Python/bytecodes.c" JUMPBY(oparg); } - #line 3161 "Python/generated_cases.c.h" + #line 3163 "Python/generated_cases.c.h" STACK_SHRINK(1); DISPATCH(); } TARGET(POP_JUMP_IF_NONE) { PyObject *value = stack_pointer[-1]; - #line 2229 "Python/bytecodes.c" + #line 2231 "Python/bytecodes.c" if (Py_IsNone(value)) { JUMPBY(oparg); } else { - #line 3173 "Python/generated_cases.c.h" + #line 3175 "Python/generated_cases.c.h" Py_DECREF(value); - #line 2234 "Python/bytecodes.c" + #line 2236 "Python/bytecodes.c" } - #line 3177 "Python/generated_cases.c.h" + #line 3179 "Python/generated_cases.c.h" STACK_SHRINK(1); DISPATCH(); } TARGET(JUMP_BACKWARD_NO_INTERRUPT) { - #line 2238 "Python/bytecodes.c" + #line 2240 "Python/bytecodes.c" /* This bytecode is used in the `yield from` or `await` loop. * If there is an interrupt, we want it handled in the innermost * generator or coroutine, so we deliberately do not check it here. * (see bpo-30039). */ JUMPBY(-oparg); - #line 3190 "Python/generated_cases.c.h" + #line 3192 "Python/generated_cases.c.h" DISPATCH(); } TARGET(GET_LEN) { PyObject *obj = stack_pointer[-1]; PyObject *len_o; - #line 2247 "Python/bytecodes.c" + #line 2249 "Python/bytecodes.c" // PUSH(len(TOS)) Py_ssize_t len_i = PyObject_Length(obj); if (len_i < 0) goto error; len_o = PyLong_FromSsize_t(len_i); if (len_o == NULL) goto error; - #line 3203 "Python/generated_cases.c.h" + #line 3205 "Python/generated_cases.c.h" STACK_GROW(1); stack_pointer[-1] = len_o; DISPATCH(); @@ -3210,16 +3212,16 @@ PyObject *type = stack_pointer[-2]; PyObject *subject = stack_pointer[-3]; PyObject *attrs; - #line 2255 "Python/bytecodes.c" + #line 2257 "Python/bytecodes.c" // Pop TOS and TOS1. Set TOS to a tuple of attributes on success, or // None on failure. assert(PyTuple_CheckExact(names)); attrs = match_class(tstate, subject, type, oparg, names); - #line 3219 "Python/generated_cases.c.h" + #line 3221 "Python/generated_cases.c.h" Py_DECREF(subject); Py_DECREF(type); Py_DECREF(names); - #line 2260 "Python/bytecodes.c" + #line 2262 "Python/bytecodes.c" if (attrs) { assert(PyTuple_CheckExact(attrs)); // Success! } @@ -3227,7 +3229,7 @@ if (_PyErr_Occurred(tstate)) goto pop_3_error; attrs = Py_None; // Failure! } - #line 3231 "Python/generated_cases.c.h" + #line 3233 "Python/generated_cases.c.h" STACK_SHRINK(2); stack_pointer[-1] = attrs; DISPATCH(); @@ -3236,10 +3238,10 @@ TARGET(MATCH_MAPPING) { PyObject *subject = stack_pointer[-1]; PyObject *res; - #line 2270 "Python/bytecodes.c" + #line 2272 "Python/bytecodes.c" int match = Py_TYPE(subject)->tp_flags & Py_TPFLAGS_MAPPING; res = match ? Py_True : Py_False; - #line 3243 "Python/generated_cases.c.h" + #line 3245 "Python/generated_cases.c.h" STACK_GROW(1); stack_pointer[-1] = res; DISPATCH(); @@ -3248,10 +3250,10 @@ TARGET(MATCH_SEQUENCE) { PyObject *subject = stack_pointer[-1]; PyObject *res; - #line 2275 "Python/bytecodes.c" + #line 2277 "Python/bytecodes.c" int match = Py_TYPE(subject)->tp_flags & Py_TPFLAGS_SEQUENCE; res = match ? Py_True : Py_False; - #line 3255 "Python/generated_cases.c.h" + #line 3257 "Python/generated_cases.c.h" STACK_GROW(1); stack_pointer[-1] = res; DISPATCH(); @@ -3261,11 +3263,11 @@ PyObject *keys = stack_pointer[-1]; PyObject *subject = stack_pointer[-2]; PyObject *values_or_none; - #line 2280 "Python/bytecodes.c" + #line 2282 "Python/bytecodes.c" // On successful match, PUSH(values). Otherwise, PUSH(None). values_or_none = match_keys(tstate, subject, keys); if (values_or_none == NULL) goto error; - #line 3269 "Python/generated_cases.c.h" + #line 3271 "Python/generated_cases.c.h" STACK_GROW(1); stack_pointer[-1] = values_or_none; DISPATCH(); @@ -3274,14 +3276,14 @@ TARGET(GET_ITER) { PyObject *iterable = stack_pointer[-1]; PyObject *iter; - #line 2286 "Python/bytecodes.c" + #line 2288 "Python/bytecodes.c" /* before: [obj]; after [getiter(obj)] */ iter = PyObject_GetIter(iterable); - #line 3281 "Python/generated_cases.c.h" + #line 3283 "Python/generated_cases.c.h" Py_DECREF(iterable); - #line 2289 "Python/bytecodes.c" + #line 2291 "Python/bytecodes.c" if (iter == NULL) goto pop_1_error; - #line 3285 "Python/generated_cases.c.h" + #line 3287 "Python/generated_cases.c.h" stack_pointer[-1] = iter; DISPATCH(); } @@ -3289,7 +3291,7 @@ TARGET(GET_YIELD_FROM_ITER) { PyObject *iterable = stack_pointer[-1]; PyObject *iter; - #line 2293 "Python/bytecodes.c" + #line 2295 "Python/bytecodes.c" /* before: [obj]; after [getiter(obj)] */ if (PyCoro_CheckExact(iterable)) { /* `iterable` is a coroutine */ @@ -3312,11 +3314,11 @@ if (iter == NULL) { goto error; } - #line 3316 "Python/generated_cases.c.h" + #line 3318 "Python/generated_cases.c.h" Py_DECREF(iterable); - #line 2316 "Python/bytecodes.c" + #line 2318 "Python/bytecodes.c" } - #line 3320 "Python/generated_cases.c.h" + #line 3322 "Python/generated_cases.c.h" stack_pointer[-1] = iter; DISPATCH(); } @@ -3326,7 +3328,7 @@ static_assert(INLINE_CACHE_ENTRIES_FOR_ITER == 1, "incorrect cache size"); PyObject *iter = stack_pointer[-1]; PyObject *next; - #line 2334 "Python/bytecodes.c" + #line 2336 "Python/bytecodes.c" #if ENABLE_SPECIALIZATION _PyForIterCache *cache = (_PyForIterCache *)next_instr; if (ADAPTIVE_COUNTER_IS_ZERO(cache->counter)) { @@ -3358,7 +3360,7 @@ DISPATCH(); } // Common case: no jump, leave it to the code generator - #line 3362 "Python/generated_cases.c.h" + #line 3364 "Python/generated_cases.c.h" STACK_GROW(1); stack_pointer[-1] = next; next_instr += 1; @@ -3366,7 +3368,7 @@ } TARGET(INSTRUMENTED_FOR_ITER) { - #line 2368 "Python/bytecodes.c" + #line 2370 "Python/bytecodes.c" _Py_CODEUNIT *here = next_instr-1; _Py_CODEUNIT *target; PyObject *iter = TOP(); @@ -3392,14 +3394,14 @@ target = next_instr + INLINE_CACHE_ENTRIES_FOR_ITER + oparg + 1; } INSTRUMENTED_JUMP(here, target, PY_MONITORING_EVENT_BRANCH); - #line 3396 "Python/generated_cases.c.h" + #line 3398 "Python/generated_cases.c.h" DISPATCH(); } TARGET(FOR_ITER_LIST) { PyObject *iter = stack_pointer[-1]; PyObject *next; - #line 2396 "Python/bytecodes.c" + #line 2398 "Python/bytecodes.c" DEOPT_IF(Py_TYPE(iter) != &PyListIter_Type, FOR_ITER); _PyListIterObject *it = (_PyListIterObject *)iter; STAT_INC(FOR_ITER, hit); @@ -3420,7 +3422,7 @@ DISPATCH(); end_for_iter_list: // Common case: no jump, leave it to the code generator - #line 3424 "Python/generated_cases.c.h" + #line 3426 "Python/generated_cases.c.h" STACK_GROW(1); stack_pointer[-1] = next; next_instr += 1; @@ -3430,7 +3432,7 @@ TARGET(FOR_ITER_TUPLE) { PyObject *iter = stack_pointer[-1]; PyObject *next; - #line 2419 "Python/bytecodes.c" + #line 2421 "Python/bytecodes.c" _PyTupleIterObject *it = (_PyTupleIterObject *)iter; DEOPT_IF(Py_TYPE(it) != &PyTupleIter_Type, FOR_ITER); STAT_INC(FOR_ITER, hit); @@ -3451,7 +3453,7 @@ DISPATCH(); end_for_iter_tuple: // Common case: no jump, leave it to the code generator - #line 3455 "Python/generated_cases.c.h" + #line 3457 "Python/generated_cases.c.h" STACK_GROW(1); stack_pointer[-1] = next; next_instr += 1; @@ -3461,7 +3463,7 @@ TARGET(FOR_ITER_RANGE) { PyObject *iter = stack_pointer[-1]; PyObject *next; - #line 2442 "Python/bytecodes.c" + #line 2444 "Python/bytecodes.c" _PyRangeIterObject *r = (_PyRangeIterObject *)iter; DEOPT_IF(Py_TYPE(r) != &PyRangeIter_Type, FOR_ITER); STAT_INC(FOR_ITER, hit); @@ -3480,7 +3482,7 @@ if (next == NULL) { goto error; } - #line 3484 "Python/generated_cases.c.h" + #line 3486 "Python/generated_cases.c.h" STACK_GROW(1); stack_pointer[-1] = next; next_instr += 1; @@ -3489,7 +3491,7 @@ TARGET(FOR_ITER_GEN) { PyObject *iter = stack_pointer[-1]; - #line 2463 "Python/bytecodes.c" + #line 2465 "Python/bytecodes.c" DEOPT_IF(tstate->interp->eval_frame, FOR_ITER); PyGenObject *gen = (PyGenObject *)iter; DEOPT_IF(Py_TYPE(gen) != &PyGen_Type, FOR_ITER); @@ -3505,14 +3507,14 @@ assert(next_instr[oparg].op.code == END_FOR || next_instr[oparg].op.code == INSTRUMENTED_END_FOR); DISPATCH_INLINED(gen_frame); - #line 3509 "Python/generated_cases.c.h" + #line 3511 "Python/generated_cases.c.h" } TARGET(BEFORE_ASYNC_WITH) { PyObject *mgr = stack_pointer[-1]; PyObject *exit; PyObject *res; - #line 2481 "Python/bytecodes.c" + #line 2483 "Python/bytecodes.c" PyObject *enter = _PyObject_LookupSpecial(mgr, &_Py_ID(__aenter__)); if (enter == NULL) { if (!_PyErr_Occurred(tstate)) { @@ -3535,16 +3537,16 @@ Py_DECREF(enter); goto error; } - #line 3539 "Python/generated_cases.c.h" + #line 3541 "Python/generated_cases.c.h" Py_DECREF(mgr); - #line 2504 "Python/bytecodes.c" + #line 2506 "Python/bytecodes.c" res = _PyObject_CallNoArgs(enter); Py_DECREF(enter); if (res == NULL) { Py_DECREF(exit); if (true) goto pop_1_error; } - #line 3548 "Python/generated_cases.c.h" + #line 3550 "Python/generated_cases.c.h" STACK_GROW(1); stack_pointer[-1] = res; stack_pointer[-2] = exit; @@ -3555,7 +3557,7 @@ PyObject *mgr = stack_pointer[-1]; PyObject *exit; PyObject *res; - #line 2513 "Python/bytecodes.c" + #line 2515 "Python/bytecodes.c" /* pop the context manager, push its __exit__ and the * value returned from calling its __enter__ */ @@ -3581,16 +3583,16 @@ Py_DECREF(enter); goto error; } - #line 3585 "Python/generated_cases.c.h" + #line 3587 "Python/generated_cases.c.h" Py_DECREF(mgr); - #line 2539 "Python/bytecodes.c" + #line 2541 "Python/bytecodes.c" res = _PyObject_CallNoArgs(enter); Py_DECREF(enter); if (res == NULL) { Py_DECREF(exit); if (true) goto pop_1_error; } - #line 3594 "Python/generated_cases.c.h" + #line 3596 "Python/generated_cases.c.h" STACK_GROW(1); stack_pointer[-1] = res; stack_pointer[-2] = exit; @@ -3602,7 +3604,7 @@ PyObject *lasti = stack_pointer[-3]; PyObject *exit_func = stack_pointer[-4]; PyObject *res; - #line 2548 "Python/bytecodes.c" + #line 2550 "Python/bytecodes.c" /* At the top of the stack are 4 values: - val: TOP = exc_info() - unused: SECOND = previous exception @@ -3623,7 +3625,7 @@ res = PyObject_Vectorcall(exit_func, stack + 1, 3 | PY_VECTORCALL_ARGUMENTS_OFFSET, NULL); if (res == NULL) goto error; - #line 3627 "Python/generated_cases.c.h" + #line 3629 "Python/generated_cases.c.h" STACK_GROW(1); stack_pointer[-1] = res; DISPATCH(); @@ -3632,7 +3634,7 @@ TARGET(PUSH_EXC_INFO) { PyObject *new_exc = stack_pointer[-1]; PyObject *prev_exc; - #line 2587 "Python/bytecodes.c" + #line 2589 "Python/bytecodes.c" _PyErr_StackItem *exc_info = tstate->exc_info; if (exc_info->exc_value != NULL) { prev_exc = exc_info->exc_value; @@ -3642,7 +3644,7 @@ } assert(PyExceptionInstance_Check(new_exc)); exc_info->exc_value = Py_NewRef(new_exc); - #line 3646 "Python/generated_cases.c.h" + #line 3648 "Python/generated_cases.c.h" STACK_GROW(1); stack_pointer[-1] = new_exc; stack_pointer[-2] = prev_exc; @@ -3656,7 +3658,7 @@ uint32_t type_version = read_u32(&next_instr[1].cache); uint32_t keys_version = read_u32(&next_instr[3].cache); PyObject *descr = read_obj(&next_instr[5].cache); - #line 2599 "Python/bytecodes.c" + #line 2601 "Python/bytecodes.c" /* Cached method object */ PyTypeObject *self_cls = Py_TYPE(self); assert(type_version != 0); @@ -3673,7 +3675,7 @@ assert(_PyType_HasFeature(Py_TYPE(res2), Py_TPFLAGS_METHOD_DESCRIPTOR)); res = self; assert(oparg & 1); - #line 3677 "Python/generated_cases.c.h" + #line 3679 "Python/generated_cases.c.h" STACK_GROW(((oparg & 1) ? 1 : 0)); stack_pointer[-1] = res; if (oparg & 1) { stack_pointer[-(1 + ((oparg & 1) ? 1 : 0))] = res2; } @@ -3687,7 +3689,7 @@ PyObject *res; uint32_t type_version = read_u32(&next_instr[1].cache); PyObject *descr = read_obj(&next_instr[5].cache); - #line 2618 "Python/bytecodes.c" + #line 2620 "Python/bytecodes.c" PyTypeObject *self_cls = Py_TYPE(self); DEOPT_IF(self_cls->tp_version_tag != type_version, LOAD_ATTR); assert(self_cls->tp_dictoffset == 0); @@ -3697,7 +3699,7 @@ res2 = Py_NewRef(descr); res = self; assert(oparg & 1); - #line 3701 "Python/generated_cases.c.h" + #line 3703 "Python/generated_cases.c.h" STACK_GROW(((oparg & 1) ? 1 : 0)); stack_pointer[-1] = res; if (oparg & 1) { stack_pointer[-(1 + ((oparg & 1) ? 1 : 0))] = res2; } @@ -3711,7 +3713,7 @@ PyObject *res; uint32_t type_version = read_u32(&next_instr[1].cache); PyObject *descr = read_obj(&next_instr[5].cache); - #line 2630 "Python/bytecodes.c" + #line 2632 "Python/bytecodes.c" PyTypeObject *self_cls = Py_TYPE(self); DEOPT_IF(self_cls->tp_version_tag != type_version, LOAD_ATTR); Py_ssize_t dictoffset = self_cls->tp_dictoffset; @@ -3725,7 +3727,7 @@ res2 = Py_NewRef(descr); res = self; assert(oparg & 1); - #line 3729 "Python/generated_cases.c.h" + #line 3731 "Python/generated_cases.c.h" STACK_GROW(((oparg & 1) ? 1 : 0)); stack_pointer[-1] = res; if (oparg & 1) { stack_pointer[-(1 + ((oparg & 1) ? 1 : 0))] = res2; } @@ -3734,16 +3736,16 @@ } TARGET(KW_NAMES) { - #line 2646 "Python/bytecodes.c" + #line 2648 "Python/bytecodes.c" assert(kwnames == NULL); assert(oparg < PyTuple_GET_SIZE(FRAME_CO_CONSTS)); kwnames = GETITEM(FRAME_CO_CONSTS, oparg); - #line 3742 "Python/generated_cases.c.h" + #line 3744 "Python/generated_cases.c.h" DISPATCH(); } TARGET(INSTRUMENTED_CALL) { - #line 2652 "Python/bytecodes.c" + #line 2654 "Python/bytecodes.c" int is_meth = PEEK(oparg+2) != NULL; int total_args = oparg + is_meth; PyObject *function = PEEK(total_args + 1); @@ -3756,7 +3758,7 @@ _PyCallCache *cache = (_PyCallCache *)next_instr; INCREMENT_ADAPTIVE_COUNTER(cache->counter); GO_TO_INSTRUCTION(CALL); - #line 3760 "Python/generated_cases.c.h" + #line 3762 "Python/generated_cases.c.h" } TARGET(CALL) { @@ -3766,7 +3768,7 @@ PyObject *callable = stack_pointer[-(1 + oparg)]; PyObject *method = stack_pointer[-(2 + oparg)]; PyObject *res; - #line 2698 "Python/bytecodes.c" + #line 2700 "Python/bytecodes.c" int is_meth = method != NULL; int total_args = oparg; if (is_meth) { @@ -3848,7 +3850,7 @@ Py_DECREF(args[i]); } if (res == NULL) { STACK_SHRINK(oparg); goto pop_2_error; } - #line 3852 "Python/generated_cases.c.h" + #line 3854 "Python/generated_cases.c.h" STACK_SHRINK(oparg); STACK_SHRINK(1); stack_pointer[-1] = res; @@ -3860,7 +3862,7 @@ TARGET(CALL_BOUND_METHOD_EXACT_ARGS) { PyObject *callable = stack_pointer[-(1 + oparg)]; PyObject *method = stack_pointer[-(2 + oparg)]; - #line 2786 "Python/bytecodes.c" + #line 2788 "Python/bytecodes.c" DEOPT_IF(method != NULL, CALL); DEOPT_IF(Py_TYPE(callable) != &PyMethod_Type, CALL); STAT_INC(CALL, hit); @@ -3870,7 +3872,7 @@ PEEK(oparg + 2) = Py_NewRef(meth); // method Py_DECREF(callable); GO_TO_INSTRUCTION(CALL_PY_EXACT_ARGS); - #line 3874 "Python/generated_cases.c.h" + #line 3876 "Python/generated_cases.c.h" } TARGET(CALL_PY_EXACT_ARGS) { @@ -3879,7 +3881,7 @@ PyObject *callable = stack_pointer[-(1 + oparg)]; PyObject *method = stack_pointer[-(2 + oparg)]; uint32_t func_version = read_u32(&next_instr[1].cache); - #line 2798 "Python/bytecodes.c" + #line 2800 "Python/bytecodes.c" assert(kwnames == NULL); DEOPT_IF(tstate->interp->eval_frame, CALL); int is_meth = method != NULL; @@ -3905,7 +3907,7 @@ SKIP_OVER(INLINE_CACHE_ENTRIES_CALL); frame->return_offset = 0; DISPATCH_INLINED(new_frame); - #line 3909 "Python/generated_cases.c.h" + #line 3911 "Python/generated_cases.c.h" } TARGET(CALL_PY_WITH_DEFAULTS) { @@ -3913,7 +3915,7 @@ PyObject *callable = stack_pointer[-(1 + oparg)]; PyObject *method = stack_pointer[-(2 + oparg)]; uint32_t func_version = read_u32(&next_instr[1].cache); - #line 2826 "Python/bytecodes.c" + #line 2828 "Python/bytecodes.c" assert(kwnames == NULL); DEOPT_IF(tstate->interp->eval_frame, CALL); int is_meth = method != NULL; @@ -3949,7 +3951,7 @@ SKIP_OVER(INLINE_CACHE_ENTRIES_CALL); frame->return_offset = 0; DISPATCH_INLINED(new_frame); - #line 3953 "Python/generated_cases.c.h" + #line 3955 "Python/generated_cases.c.h" } TARGET(CALL_NO_KW_TYPE_1) { @@ -3957,7 +3959,7 @@ PyObject *callable = stack_pointer[-(1 + oparg)]; PyObject *null = stack_pointer[-(2 + oparg)]; PyObject *res; - #line 2864 "Python/bytecodes.c" + #line 2866 "Python/bytecodes.c" assert(kwnames == NULL); assert(oparg == 1); DEOPT_IF(null != NULL, CALL); @@ -3967,7 +3969,7 @@ res = Py_NewRef(Py_TYPE(obj)); Py_DECREF(obj); Py_DECREF(&PyType_Type); // I.e., callable - #line 3971 "Python/generated_cases.c.h" + #line 3973 "Python/generated_cases.c.h" STACK_SHRINK(oparg); STACK_SHRINK(1); stack_pointer[-1] = res; @@ -3980,7 +3982,7 @@ PyObject *callable = stack_pointer[-(1 + oparg)]; PyObject *null = stack_pointer[-(2 + oparg)]; PyObject *res; - #line 2876 "Python/bytecodes.c" + #line 2878 "Python/bytecodes.c" assert(kwnames == NULL); assert(oparg == 1); DEOPT_IF(null != NULL, CALL); @@ -3991,7 +3993,7 @@ Py_DECREF(arg); Py_DECREF(&PyUnicode_Type); // I.e., callable if (res == NULL) { STACK_SHRINK(oparg); goto pop_2_error; } - #line 3995 "Python/generated_cases.c.h" + #line 3997 "Python/generated_cases.c.h" STACK_SHRINK(oparg); STACK_SHRINK(1); stack_pointer[-1] = res; @@ -4005,7 +4007,7 @@ PyObject *callable = stack_pointer[-(1 + oparg)]; PyObject *null = stack_pointer[-(2 + oparg)]; PyObject *res; - #line 2890 "Python/bytecodes.c" + #line 2892 "Python/bytecodes.c" assert(kwnames == NULL); assert(oparg == 1); DEOPT_IF(null != NULL, CALL); @@ -4016,7 +4018,7 @@ Py_DECREF(arg); Py_DECREF(&PyTuple_Type); // I.e., tuple if (res == NULL) { STACK_SHRINK(oparg); goto pop_2_error; } - #line 4020 "Python/generated_cases.c.h" + #line 4022 "Python/generated_cases.c.h" STACK_SHRINK(oparg); STACK_SHRINK(1); stack_pointer[-1] = res; @@ -4029,7 +4031,7 @@ PyObject **args = (stack_pointer - oparg); PyObject *callable = stack_pointer[-(1 + oparg)]; PyObject *null = stack_pointer[-(2 + oparg)]; - #line 2904 "Python/bytecodes.c" + #line 2906 "Python/bytecodes.c" /* This instruction does the following: * 1. Creates the object (by calling ``object.__new__``) * 2. Pushes a shim frame to the frame stack (to cleanup after ``__init__``) @@ -4079,12 +4081,12 @@ frame = cframe.current_frame = init_frame; CALL_STAT_INC(inlined_py_calls); goto start_frame; - #line 4083 "Python/generated_cases.c.h" + #line 4085 "Python/generated_cases.c.h" } TARGET(EXIT_INIT_CHECK) { PyObject *should_be_none = stack_pointer[-1]; - #line 2956 "Python/bytecodes.c" + #line 2958 "Python/bytecodes.c" assert(STACK_LEVEL() == 2); if (should_be_none != Py_None) { PyErr_Format(PyExc_TypeError, @@ -4092,7 +4094,7 @@ Py_TYPE(should_be_none)->tp_name); goto error; } - #line 4096 "Python/generated_cases.c.h" + #line 4098 "Python/generated_cases.c.h" STACK_SHRINK(1); DISPATCH(); } @@ -4102,7 +4104,7 @@ PyObject *callable = stack_pointer[-(1 + oparg)]; PyObject *method = stack_pointer[-(2 + oparg)]; PyObject *res; - #line 2966 "Python/bytecodes.c" + #line 2968 "Python/bytecodes.c" int is_meth = method != NULL; int total_args = oparg; if (is_meth) { @@ -4124,7 +4126,7 @@ } Py_DECREF(tp); if (res == NULL) { STACK_SHRINK(oparg); goto pop_2_error; } - #line 4128 "Python/generated_cases.c.h" + #line 4130 "Python/generated_cases.c.h" STACK_SHRINK(oparg); STACK_SHRINK(1); stack_pointer[-1] = res; @@ -4138,7 +4140,7 @@ PyObject *callable = stack_pointer[-(1 + oparg)]; PyObject *method = stack_pointer[-(2 + oparg)]; PyObject *res; - #line 2991 "Python/bytecodes.c" + #line 2993 "Python/bytecodes.c" /* Builtin METH_O functions */ assert(kwnames == NULL); int is_meth = method != NULL; @@ -4166,7 +4168,7 @@ Py_DECREF(arg); Py_DECREF(callable); if (res == NULL) { STACK_SHRINK(oparg); goto pop_2_error; } - #line 4170 "Python/generated_cases.c.h" + #line 4172 "Python/generated_cases.c.h" STACK_SHRINK(oparg); STACK_SHRINK(1); stack_pointer[-1] = res; @@ -4180,7 +4182,7 @@ PyObject *callable = stack_pointer[-(1 + oparg)]; PyObject *method = stack_pointer[-(2 + oparg)]; PyObject *res; - #line 3022 "Python/bytecodes.c" + #line 3024 "Python/bytecodes.c" /* Builtin METH_FASTCALL functions, without keywords */ assert(kwnames == NULL); int is_meth = method != NULL; @@ -4212,7 +4214,7 @@ 'invalid'). In those cases an exception is set, so we must handle it. */ - #line 4216 "Python/generated_cases.c.h" + #line 4218 "Python/generated_cases.c.h" STACK_SHRINK(oparg); STACK_SHRINK(1); stack_pointer[-1] = res; @@ -4226,7 +4228,7 @@ PyObject *callable = stack_pointer[-(1 + oparg)]; PyObject *method = stack_pointer[-(2 + oparg)]; PyObject *res; - #line 3057 "Python/bytecodes.c" + #line 3059 "Python/bytecodes.c" /* Builtin METH_FASTCALL | METH_KEYWORDS functions */ int is_meth = method != NULL; int total_args = oparg; @@ -4258,7 +4260,7 @@ } Py_DECREF(callable); if (res == NULL) { STACK_SHRINK(oparg); goto pop_2_error; } - #line 4262 "Python/generated_cases.c.h" + #line 4264 "Python/generated_cases.c.h" STACK_SHRINK(oparg); STACK_SHRINK(1); stack_pointer[-1] = res; @@ -4272,7 +4274,7 @@ PyObject *callable = stack_pointer[-(1 + oparg)]; PyObject *method = stack_pointer[-(2 + oparg)]; PyObject *res; - #line 3092 "Python/bytecodes.c" + #line 3094 "Python/bytecodes.c" assert(kwnames == NULL); /* len(o) */ int is_meth = method != NULL; @@ -4297,7 +4299,7 @@ Py_DECREF(callable); Py_DECREF(arg); if (res == NULL) { STACK_SHRINK(oparg); goto pop_2_error; } - #line 4301 "Python/generated_cases.c.h" + #line 4303 "Python/generated_cases.c.h" STACK_SHRINK(oparg); STACK_SHRINK(1); stack_pointer[-1] = res; @@ -4310,7 +4312,7 @@ PyObject *callable = stack_pointer[-(1 + oparg)]; PyObject *method = stack_pointer[-(2 + oparg)]; PyObject *res; - #line 3119 "Python/bytecodes.c" + #line 3121 "Python/bytecodes.c" assert(kwnames == NULL); /* isinstance(o, o2) */ int is_meth = method != NULL; @@ -4337,7 +4339,7 @@ Py_DECREF(cls); Py_DECREF(callable); if (res == NULL) { STACK_SHRINK(oparg); goto pop_2_error; } - #line 4341 "Python/generated_cases.c.h" + #line 4343 "Python/generated_cases.c.h" STACK_SHRINK(oparg); STACK_SHRINK(1); stack_pointer[-1] = res; @@ -4349,7 +4351,7 @@ PyObject **args = (stack_pointer - oparg); PyObject *self = stack_pointer[-(1 + oparg)]; PyObject *method = stack_pointer[-(2 + oparg)]; - #line 3149 "Python/bytecodes.c" + #line 3151 "Python/bytecodes.c" assert(kwnames == NULL); assert(oparg == 1); assert(method != NULL); @@ -4367,14 +4369,14 @@ SKIP_OVER(INLINE_CACHE_ENTRIES_CALL + 1); assert(next_instr[-1].op.code == POP_TOP); DISPATCH(); - #line 4371 "Python/generated_cases.c.h" + #line 4373 "Python/generated_cases.c.h" } TARGET(CALL_NO_KW_METHOD_DESCRIPTOR_O) { PyObject **args = (stack_pointer - oparg); PyObject *method = stack_pointer[-(2 + oparg)]; PyObject *res; - #line 3169 "Python/bytecodes.c" + #line 3171 "Python/bytecodes.c" assert(kwnames == NULL); int is_meth = method != NULL; int total_args = oparg; @@ -4405,7 +4407,7 @@ Py_DECREF(arg); Py_DECREF(callable); if (res == NULL) { STACK_SHRINK(oparg); goto pop_2_error; } - #line 4409 "Python/generated_cases.c.h" + #line 4411 "Python/generated_cases.c.h" STACK_SHRINK(oparg); STACK_SHRINK(1); stack_pointer[-1] = res; @@ -4418,7 +4420,7 @@ PyObject **args = (stack_pointer - oparg); PyObject *method = stack_pointer[-(2 + oparg)]; PyObject *res; - #line 3203 "Python/bytecodes.c" + #line 3205 "Python/bytecodes.c" int is_meth = method != NULL; int total_args = oparg; if (is_meth) { @@ -4447,7 +4449,7 @@ } Py_DECREF(callable); if (res == NULL) { STACK_SHRINK(oparg); goto pop_2_error; } - #line 4451 "Python/generated_cases.c.h" + #line 4453 "Python/generated_cases.c.h" STACK_SHRINK(oparg); STACK_SHRINK(1); stack_pointer[-1] = res; @@ -4460,7 +4462,7 @@ PyObject **args = (stack_pointer - oparg); PyObject *method = stack_pointer[-(2 + oparg)]; PyObject *res; - #line 3235 "Python/bytecodes.c" + #line 3237 "Python/bytecodes.c" assert(kwnames == NULL); assert(oparg == 0 || oparg == 1); int is_meth = method != NULL; @@ -4489,7 +4491,7 @@ Py_DECREF(self); Py_DECREF(callable); if (res == NULL) { STACK_SHRINK(oparg); goto pop_2_error; } - #line 4493 "Python/generated_cases.c.h" + #line 4495 "Python/generated_cases.c.h" STACK_SHRINK(oparg); STACK_SHRINK(1); stack_pointer[-1] = res; @@ -4502,7 +4504,7 @@ PyObject **args = (stack_pointer - oparg); PyObject *method = stack_pointer[-(2 + oparg)]; PyObject *res; - #line 3267 "Python/bytecodes.c" + #line 3269 "Python/bytecodes.c" assert(kwnames == NULL); int is_meth = method != NULL; int total_args = oparg; @@ -4530,7 +4532,7 @@ } Py_DECREF(callable); if (res == NULL) { STACK_SHRINK(oparg); goto pop_2_error; } - #line 4534 "Python/generated_cases.c.h" + #line 4536 "Python/generated_cases.c.h" STACK_SHRINK(oparg); STACK_SHRINK(1); stack_pointer[-1] = res; @@ -4540,9 +4542,9 @@ } TARGET(INSTRUMENTED_CALL_FUNCTION_EX) { - #line 3298 "Python/bytecodes.c" + #line 3300 "Python/bytecodes.c" GO_TO_INSTRUCTION(CALL_FUNCTION_EX); - #line 4546 "Python/generated_cases.c.h" + #line 4548 "Python/generated_cases.c.h" } TARGET(CALL_FUNCTION_EX) { @@ -4551,7 +4553,7 @@ PyObject *callargs = stack_pointer[-(1 + ((oparg & 1) ? 1 : 0))]; PyObject *func = stack_pointer[-(2 + ((oparg & 1) ? 1 : 0))]; PyObject *result; - #line 3302 "Python/bytecodes.c" + #line 3304 "Python/bytecodes.c" // DICT_MERGE is called before this opcode if there are kwargs. // It converts all dict subtypes in kwargs into regular dicts. assert(kwargs == NULL || PyDict_CheckExact(kwargs)); @@ -4613,14 +4615,14 @@ } result = PyObject_Call(func, callargs, kwargs); } - #line 4617 "Python/generated_cases.c.h" + #line 4619 "Python/generated_cases.c.h" Py_DECREF(func); Py_DECREF(callargs); Py_XDECREF(kwargs); - #line 3364 "Python/bytecodes.c" + #line 3366 "Python/bytecodes.c" assert(PEEK(3 + (oparg & 1)) == NULL); if (result == NULL) { STACK_SHRINK(((oparg & 1) ? 1 : 0)); goto pop_3_error; } - #line 4624 "Python/generated_cases.c.h" + #line 4626 "Python/generated_cases.c.h" STACK_SHRINK(((oparg & 1) ? 1 : 0)); STACK_SHRINK(2); stack_pointer[-1] = result; @@ -4631,7 +4633,7 @@ TARGET(MAKE_FUNCTION) { PyObject *codeobj = stack_pointer[-1]; PyObject *func; - #line 3370 "Python/bytecodes.c" + #line 3372 "Python/bytecodes.c" PyFunctionObject *func_obj = (PyFunctionObject *) PyFunction_New(codeobj, GLOBALS()); @@ -4643,7 +4645,7 @@ func_obj->func_version = ((PyCodeObject *)codeobj)->co_version; func = (PyObject *)func_obj; - #line 4647 "Python/generated_cases.c.h" + #line 4649 "Python/generated_cases.c.h" stack_pointer[-1] = func; DISPATCH(); } @@ -4651,7 +4653,7 @@ TARGET(SET_FUNCTION_ATTRIBUTE) { PyObject *func = stack_pointer[-1]; PyObject *attr = stack_pointer[-2]; - #line 3384 "Python/bytecodes.c" + #line 3386 "Python/bytecodes.c" assert(PyFunction_Check(func)); PyFunctionObject *func_obj = (PyFunctionObject *)func; switch(oparg) { @@ -4676,14 +4678,14 @@ default: Py_UNREACHABLE(); } - #line 4680 "Python/generated_cases.c.h" + #line 4682 "Python/generated_cases.c.h" STACK_SHRINK(1); stack_pointer[-1] = func; DISPATCH(); } TARGET(RETURN_GENERATOR) { - #line 3411 "Python/bytecodes.c" + #line 3413 "Python/bytecodes.c" assert(PyFunction_Check(frame->f_funcobj)); PyFunctionObject *func = (PyFunctionObject *)frame->f_funcobj; PyGenObject *gen = (PyGenObject *)_Py_MakeCoro(func); @@ -4704,7 +4706,7 @@ frame = cframe.current_frame = prev; _PyFrame_StackPush(frame, (PyObject *)gen); goto resume_frame; - #line 4708 "Python/generated_cases.c.h" + #line 4710 "Python/generated_cases.c.h" } TARGET(BUILD_SLICE) { @@ -4712,15 +4714,15 @@ PyObject *stop = stack_pointer[-(1 + ((oparg == 3) ? 1 : 0))]; PyObject *start = stack_pointer[-(2 + ((oparg == 3) ? 1 : 0))]; PyObject *slice; - #line 3434 "Python/bytecodes.c" + #line 3436 "Python/bytecodes.c" slice = PySlice_New(start, stop, step); - #line 4718 "Python/generated_cases.c.h" + #line 4720 "Python/generated_cases.c.h" Py_DECREF(start); Py_DECREF(stop); Py_XDECREF(step); - #line 3436 "Python/bytecodes.c" + #line 3438 "Python/bytecodes.c" if (slice == NULL) { STACK_SHRINK(((oparg == 3) ? 1 : 0)); goto pop_2_error; } - #line 4724 "Python/generated_cases.c.h" + #line 4726 "Python/generated_cases.c.h" STACK_SHRINK(((oparg == 3) ? 1 : 0)); STACK_SHRINK(1); stack_pointer[-1] = slice; @@ -4730,14 +4732,14 @@ TARGET(CONVERT_VALUE) { PyObject *value = stack_pointer[-1]; PyObject *result; - #line 3440 "Python/bytecodes.c" + #line 3442 "Python/bytecodes.c" convertion_func_ptr conv_fn; assert(oparg >= FVC_STR && oparg <= FVC_ASCII); conv_fn = CONVERSION_FUNCTIONS[oparg]; result = conv_fn(value); Py_DECREF(value); if (result == NULL) goto pop_1_error; - #line 4741 "Python/generated_cases.c.h" + #line 4743 "Python/generated_cases.c.h" stack_pointer[-1] = result; DISPATCH(); } @@ -4745,7 +4747,7 @@ TARGET(FORMAT_SIMPLE) { PyObject *value = stack_pointer[-1]; PyObject *res; - #line 3449 "Python/bytecodes.c" + #line 3451 "Python/bytecodes.c" /* If value is a unicode object, then we know the result * of format(value) is value itself. */ if (!PyUnicode_CheckExact(value)) { @@ -4756,7 +4758,7 @@ else { res = value; } - #line 4760 "Python/generated_cases.c.h" + #line 4762 "Python/generated_cases.c.h" stack_pointer[-1] = res; DISPATCH(); } @@ -4765,12 +4767,12 @@ PyObject *fmt_spec = stack_pointer[-1]; PyObject *value = stack_pointer[-2]; PyObject *res; - #line 3462 "Python/bytecodes.c" + #line 3464 "Python/bytecodes.c" res = PyObject_Format(value, fmt_spec); Py_DECREF(value); Py_DECREF(fmt_spec); if (res == NULL) goto pop_2_error; - #line 4774 "Python/generated_cases.c.h" + #line 4776 "Python/generated_cases.c.h" STACK_SHRINK(1); stack_pointer[-1] = res; DISPATCH(); @@ -4779,10 +4781,10 @@ TARGET(COPY) { PyObject *bottom = stack_pointer[-(1 + (oparg-1))]; PyObject *top; - #line 3469 "Python/bytecodes.c" + #line 3471 "Python/bytecodes.c" assert(oparg > 0); top = Py_NewRef(bottom); - #line 4786 "Python/generated_cases.c.h" + #line 4788 "Python/generated_cases.c.h" STACK_GROW(1); stack_pointer[-1] = top; DISPATCH(); @@ -4794,7 +4796,7 @@ PyObject *rhs = stack_pointer[-1]; PyObject *lhs = stack_pointer[-2]; PyObject *res; - #line 3474 "Python/bytecodes.c" + #line 3476 "Python/bytecodes.c" #if ENABLE_SPECIALIZATION _PyBinaryOpCache *cache = (_PyBinaryOpCache *)next_instr; if (ADAPTIVE_COUNTER_IS_ZERO(cache->counter)) { @@ -4809,12 +4811,12 @@ assert((unsigned)oparg < Py_ARRAY_LENGTH(binary_ops)); assert(binary_ops[oparg]); res = binary_ops[oparg](lhs, rhs); - #line 4813 "Python/generated_cases.c.h" + #line 4815 "Python/generated_cases.c.h" Py_DECREF(lhs); Py_DECREF(rhs); - #line 3489 "Python/bytecodes.c" + #line 3491 "Python/bytecodes.c" if (res == NULL) goto pop_2_error; - #line 4818 "Python/generated_cases.c.h" + #line 4820 "Python/generated_cases.c.h" STACK_SHRINK(1); stack_pointer[-1] = res; next_instr += 1; @@ -4824,16 +4826,16 @@ TARGET(SWAP) { PyObject *top = stack_pointer[-1]; PyObject *bottom = stack_pointer[-(2 + (oparg-2))]; - #line 3494 "Python/bytecodes.c" + #line 3496 "Python/bytecodes.c" assert(oparg >= 2); - #line 4830 "Python/generated_cases.c.h" + #line 4832 "Python/generated_cases.c.h" stack_pointer[-1] = bottom; stack_pointer[-(2 + (oparg-2))] = top; DISPATCH(); } TARGET(INSTRUMENTED_INSTRUCTION) { - #line 3498 "Python/bytecodes.c" + #line 3500 "Python/bytecodes.c" int next_opcode = _Py_call_instrumentation_instruction( tstate, frame, next_instr-1); if (next_opcode < 0) goto error; @@ -4845,26 +4847,26 @@ assert(next_opcode > 0 && next_opcode < 256); opcode = next_opcode; DISPATCH_GOTO(); - #line 4849 "Python/generated_cases.c.h" + #line 4851 "Python/generated_cases.c.h" } TARGET(INSTRUMENTED_JUMP_FORWARD) { - #line 3512 "Python/bytecodes.c" + #line 3514 "Python/bytecodes.c" INSTRUMENTED_JUMP(next_instr-1, next_instr+oparg, PY_MONITORING_EVENT_JUMP); - #line 4855 "Python/generated_cases.c.h" + #line 4857 "Python/generated_cases.c.h" DISPATCH(); } TARGET(INSTRUMENTED_JUMP_BACKWARD) { - #line 3516 "Python/bytecodes.c" + #line 3518 "Python/bytecodes.c" CHECK_EVAL_BREAKER(); INSTRUMENTED_JUMP(next_instr-1, next_instr+1-oparg, PY_MONITORING_EVENT_JUMP); - #line 4863 "Python/generated_cases.c.h" + #line 4865 "Python/generated_cases.c.h" DISPATCH(); } TARGET(INSTRUMENTED_POP_JUMP_IF_TRUE) { - #line 3521 "Python/bytecodes.c" + #line 3523 "Python/bytecodes.c" PyObject *cond = POP(); int err = PyObject_IsTrue(cond); Py_DECREF(cond); @@ -4873,12 +4875,12 @@ assert(err == 0 || err == 1); int offset = err*oparg; INSTRUMENTED_JUMP(here, next_instr + offset, PY_MONITORING_EVENT_BRANCH); - #line 4877 "Python/generated_cases.c.h" + #line 4879 "Python/generated_cases.c.h" DISPATCH(); } TARGET(INSTRUMENTED_POP_JUMP_IF_FALSE) { - #line 3532 "Python/bytecodes.c" + #line 3534 "Python/bytecodes.c" PyObject *cond = POP(); int err = PyObject_IsTrue(cond); Py_DECREF(cond); @@ -4887,12 +4889,12 @@ assert(err == 0 || err == 1); int offset = (1-err)*oparg; INSTRUMENTED_JUMP(here, next_instr + offset, PY_MONITORING_EVENT_BRANCH); - #line 4891 "Python/generated_cases.c.h" + #line 4893 "Python/generated_cases.c.h" DISPATCH(); } TARGET(INSTRUMENTED_POP_JUMP_IF_NONE) { - #line 3543 "Python/bytecodes.c" + #line 3545 "Python/bytecodes.c" PyObject *value = POP(); _Py_CODEUNIT *here = next_instr-1; int offset; @@ -4904,12 +4906,12 @@ offset = 0; } INSTRUMENTED_JUMP(here, next_instr + offset, PY_MONITORING_EVENT_BRANCH); - #line 4908 "Python/generated_cases.c.h" + #line 4910 "Python/generated_cases.c.h" DISPATCH(); } TARGET(INSTRUMENTED_POP_JUMP_IF_NOT_NONE) { - #line 3557 "Python/bytecodes.c" + #line 3559 "Python/bytecodes.c" PyObject *value = POP(); _Py_CODEUNIT *here = next_instr-1; int offset; @@ -4921,30 +4923,30 @@ offset = oparg; } INSTRUMENTED_JUMP(here, next_instr + offset, PY_MONITORING_EVENT_BRANCH); - #line 4925 "Python/generated_cases.c.h" + #line 4927 "Python/generated_cases.c.h" DISPATCH(); } TARGET(EXTENDED_ARG) { - #line 3571 "Python/bytecodes.c" + #line 3573 "Python/bytecodes.c" assert(oparg); opcode = next_instr->op.code; oparg = oparg << 8 | next_instr->op.arg; PRE_DISPATCH_GOTO(); DISPATCH_GOTO(); - #line 4936 "Python/generated_cases.c.h" + #line 4938 "Python/generated_cases.c.h" } TARGET(CACHE) { - #line 3579 "Python/bytecodes.c" + #line 3581 "Python/bytecodes.c" assert(0 && "Executing a cache."); Py_UNREACHABLE(); - #line 4943 "Python/generated_cases.c.h" + #line 4945 "Python/generated_cases.c.h" } TARGET(RESERVED) { - #line 3584 "Python/bytecodes.c" + #line 3586 "Python/bytecodes.c" assert(0 && "Executing RESERVED instruction."); Py_UNREACHABLE(); - #line 4950 "Python/generated_cases.c.h" + #line 4952 "Python/generated_cases.c.h" } diff --git a/Python/opcode_metadata.h b/Python/opcode_metadata.h index 4e31a5e69614bb..05d8e1d52e8de0 100644 --- a/Python/opcode_metadata.h +++ b/Python/opcode_metadata.h @@ -1048,7 +1048,7 @@ const struct opcode_metadata _PyOpcode_opcode_metadata[512] = { [JUMP_BACKWARD] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_JUMP_FLAG }, [JUMP] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_JUMP_FLAG }, [JUMP_NO_INTERRUPT] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_JUMP_FLAG }, - [ENTER_EXECUTOR] = { true, INSTR_FMT_IB, HAS_ARG_FLAG }, + [ENTER_EXECUTOR] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_JUMP_FLAG }, [POP_JUMP_IF_FALSE] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_JUMP_FLAG }, [POP_JUMP_IF_TRUE] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_JUMP_FLAG }, [POP_JUMP_IF_NOT_NONE] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_JUMP_FLAG }, From f4d88647eaea97b47d45f807949f23514b9aa243 Mon Sep 17 00:00:00 2001 From: Mark Shannon Date: Wed, 21 Jun 2023 09:57:41 +0100 Subject: [PATCH 3/4] Remove label --- Python/ceval.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/Python/ceval.c b/Python/ceval.c index 3e0dcf8c8629b9..6cea48d4324673 100644 --- a/Python/ceval.c +++ b/Python/ceval.c @@ -763,8 +763,6 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int DISPATCH(); -handle_eval_breaker: - /* Do periodic things, like check for signals and async I/0. * We need to do reasonably frequently, but not too frequently. * All loops should include a check of the eval breaker. From 94947b983439f837fca80191021410be4feb923f Mon Sep 17 00:00:00 2001 From: Mark Shannon Date: Mon, 3 Jul 2023 13:57:55 +0100 Subject: [PATCH 4/4] Address review comments --- Include/internal/pycore_ceval.h | 2 + Python/bytecodes.c | 6 ++- Python/ceval.c | 68 +-------------------------------- Python/ceval_gil.c | 61 ++++++++++++++++++++++++++++- 4 files changed, 66 insertions(+), 71 deletions(-) diff --git a/Include/internal/pycore_ceval.h b/Include/internal/pycore_ceval.h index 9e9b523e7c2222..46bc18cff86d5a 100644 --- a/Include/internal/pycore_ceval.h +++ b/Include/internal/pycore_ceval.h @@ -152,6 +152,8 @@ extern struct _PyInterpreterFrame* _PyEval_GetFrame(void); extern PyObject* _Py_MakeCoro(PyFunctionObject *func); +/* Handle signals, pending calls, GIL drop request + and asynchronous exception */ extern int _Py_HandlePending(PyThreadState *tstate); diff --git a/Python/bytecodes.c b/Python/bytecodes.c index 7eb4cd66da8146..f16d86c1332101 100644 --- a/Python/bytecodes.c +++ b/Python/bytecodes.c @@ -2175,10 +2175,12 @@ dummy_func( inst(ENTER_EXECUTOR, (--)) { CHECK_EVAL_BREAKER(); - JUMPBY(1-oparg); - frame->prev_instr = next_instr - 1; + PyCodeObject *code = _PyFrame_GetCode(frame); _PyExecutorObject *executor = (_PyExecutorObject *)code->co_executors->executors[oparg&255]; + int original_oparg = executor->vm_data.oparg | (oparg & 0xfffff00); + JUMPBY(1-original_oparg); + frame->prev_instr = next_instr - 1; Py_INCREF(executor); frame = executor->execute(executor, frame, stack_pointer); if (frame == NULL) { diff --git a/Python/ceval.c b/Python/ceval.c index 6cea48d4324673..51c3acfa599fcf 100644 --- a/Python/ceval.c +++ b/Python/ceval.c @@ -763,66 +763,6 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int DISPATCH(); - /* Do periodic things, like check for signals and async I/0. - * We need to do reasonably frequently, but not too frequently. - * All loops should include a check of the eval breaker. - * We also check on return from any builtin function. - * - * ## More Details ### - * - * The eval loop (this function) normally executes the instructions - * of a code object sequentially. However, the runtime supports a - * number of out-of-band execution scenarios that may pause that - * sequential execution long enough to do that out-of-band work - * in the current thread using the current PyThreadState. - * - * The scenarios include: - * - * - cyclic garbage collection - * - GIL drop requests - * - "async" exceptions - * - "pending calls" (some only in the main thread) - * - signal handling (only in the main thread) - * - * When the need for one of the above is detected, the eval loop - * pauses long enough to handle the detected case. Then, if doing - * so didn't trigger an exception, the eval loop resumes executing - * the sequential instructions. - * - * To make this work, the eval loop periodically checks if any - * of the above needs to happen. The individual checks can be - * expensive if computed each time, so a while back we switched - * to using pre-computed, per-interpreter variables for the checks, - * and later consolidated that to a single "eval breaker" variable - * (now a PyInterpreterState field). - * - * For the longest time, the eval breaker check would happen - * frequently, every 5 or so times through the loop, regardless - * of what instruction ran last or what would run next. Then, in - * early 2021 (gh-18334, commit 4958f5d), we switched to checking - * the eval breaker less frequently, by hard-coding the check to - * specific places in the eval loop (e.g. certain instructions). - * The intent then was to check after returning from calls - * and on the back edges of loops. - * - * In addition to being more efficient, that approach keeps - * the eval loop from running arbitrary code between instructions - * that don't handle that well. (See gh-74174.) - * - * Currently, the eval breaker check happens here at the - * "handle_eval_breaker" label. Some instructions come here - * explicitly (goto) and some indirectly. Notably, the check - * happens on back edges in the control flow graph, which - * pretty much applies to all loops and most calls. - * (See bytecodes.c for exact information.) - * - * One consequence of this approach is that it might not be obvious - * how to force any specific thread to pick up the eval breaker, - * or for any specific thread to not pick it up. Mostly this - * involves judicious uses of locks and careful ordering of code, - * while avoiding code that might trigger the eval breaker - * until so desired. - */ if (_Py_HandlePending(tstate) != 0) { goto error; } @@ -2794,13 +2734,7 @@ _PyUopExecute(_PyExecutorObject *executor, _PyInterpreterFrame *frame, PyObject PyThreadState *tstate = _PyThreadState_GET(); _PyUOpExecutorObject *self = (_PyUOpExecutorObject *)executor; - // Equivalent to CHECK_EVAL_BREAKER() - _Py_CHECK_EMSCRIPTEN_SIGNALS_PERIODICALLY(); - if (_Py_atomic_load_relaxed_int32(&tstate->interp->ceval.eval_breaker)) { - if (_Py_HandlePending(tstate) != 0) { - goto error; - } - } + CHECK_EVAL_BREAKER(); OBJECT_STAT_INC(optimization_traces_executed); _Py_CODEUNIT *ip_offset = (_Py_CODEUNIT *)_PyFrame_GetCode(frame)->co_code_adaptive - 1; diff --git a/Python/ceval_gil.c b/Python/ceval_gil.c index bb1279f46cf9f7..caf506122fba86 100644 --- a/Python/ceval_gil.c +++ b/Python/ceval_gil.c @@ -1052,8 +1052,65 @@ _PyEval_FiniState(struct _ceval_state *ceval) } } -/* Handle signals, pending calls, GIL drop request - and asynchronous exception */ + +/* Do periodic things, like check for signals and async I/0. +* We need to do reasonably frequently, but not too frequently. +* All loops should include a check of the eval breaker. +* We also check on return from any builtin function. +* +* ## More Details ### +* +* The eval loop (this function) normally executes the instructions +* of a code object sequentially. However, the runtime supports a +* number of out-of-band execution scenarios that may pause that +* sequential execution long enough to do that out-of-band work +* in the current thread using the current PyThreadState. +* +* The scenarios include: +* +* - cyclic garbage collection +* - GIL drop requests +* - "async" exceptions +* - "pending calls" (some only in the main thread) +* - signal handling (only in the main thread) +* +* When the need for one of the above is detected, the eval loop +* pauses long enough to handle the detected case. Then, if doing +* so didn't trigger an exception, the eval loop resumes executing +* the sequential instructions. +* +* To make this work, the eval loop periodically checks if any +* of the above needs to happen. The individual checks can be +* expensive if computed each time, so a while back we switched +* to using pre-computed, per-interpreter variables for the checks, +* and later consolidated that to a single "eval breaker" variable +* (now a PyInterpreterState field). +* +* For the longest time, the eval breaker check would happen +* frequently, every 5 or so times through the loop, regardless +* of what instruction ran last or what would run next. Then, in +* early 2021 (gh-18334, commit 4958f5d), we switched to checking +* the eval breaker less frequently, by hard-coding the check to +* specific places in the eval loop (e.g. certain instructions). +* The intent then was to check after returning from calls +* and on the back edges of loops. +* +* In addition to being more efficient, that approach keeps +* the eval loop from running arbitrary code between instructions +* that don't handle that well. (See gh-74174.) +* +* Currently, the eval breaker check happens on back edges in +* the control flow graph, which pretty much applies to all loops, +* and most calls. +* (See bytecodes.c for exact information.) +* +* One consequence of this approach is that it might not be obvious +* how to force any specific thread to pick up the eval breaker, +* or for any specific thread to not pick it up. Mostly this +* involves judicious uses of locks and careful ordering of code, +* while avoiding code that might trigger the eval breaker +* until so desired. +*/ int _Py_HandlePending(PyThreadState *tstate) {