}
tier2 op(_ERROR_POP_N, (target/2 --)) {
- assert(target != 0);
assert(oparg == 0);
- frame->instr_ptr = _PyFrame_GetBytecode(frame) + target;
+ _Py_CODEUNIT *current_instr = _PyFrame_GetBytecode(frame) + target;
+ _Py_CODEUNIT *next_instr = current_instr + 1 + _PyOpcode_Caches[_PyOpcode_Deopt[current_instr->op.code]];
+ // gh-140104: The exception handler expects frame->instr_ptr to be pointing to next_instr, not this_instr!
+ frame->instr_ptr = next_instr;
SYNC_SP();
GOTO_TIER_ONE(NULL, 0);
}
case _ERROR_POP_N: {
oparg = CURRENT_OPARG();
uint32_t target = (uint32_t)CURRENT_OPERAND0();
- assert(target != 0);
assert(oparg == 0);
- frame->instr_ptr = _PyFrame_GetBytecode(frame) + target;
+ _Py_CODEUNIT *current_instr = _PyFrame_GetBytecode(frame) + target;
+ _Py_CODEUNIT *next_instr = current_instr + 1 + _PyOpcode_Caches[_PyOpcode_Deopt[current_instr->op.code]];
+ frame->instr_ptr = next_instr;
GOTO_TIER_ONE(NULL, 0);
break;
}
DPRINTF(2, "%d: %s(%d)\n", target, _PyOpcode_OpName[opcode], oparg);
- if ((uint16_t)oparg != (uint64_t)oparg) {
+ // TODO support EXTENDED_ARG
+ if (oparg > 255) {
goto unsupported;
}
- // One for possible _DEOPT, one because _CHECK_VALIDITY itself might _DEOPT
- max_length -= 2;
if (opcode == EXTENDED_ARG) {
return 1;
return 1;
}
+ // One for possible _DEOPT, one because _CHECK_VALIDITY itself might _DEOPT
+ max_length -= 2;
+
if (opcode == ENTER_EXECUTOR) {
ADD_TO_TRACE(_CHECK_VALIDITY, 0, 0, target);
ADD_TO_TRACE(_SET_IP, 0, (uintptr_t)target_instr, target);