bpo-46841: Don't scan backwards in bytecode (GH-31901)

This commit is contained in:
Mark Shannon 2022-03-16 00:08:37 +00:00 committed by GitHub
parent a4674f0194
commit 49e1e1e1bd
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 12 additions and 15 deletions

View File

@ -359,9 +359,12 @@ _PyGen_yf(PyGenObject *gen)
assert(code[0] != SEND); assert(code[0] != SEND);
return NULL; return NULL;
} }
int opcode = code[(frame->f_lasti+1)*sizeof(_Py_CODEUNIT)];
if (code[(frame->f_lasti-1)*sizeof(_Py_CODEUNIT)] != SEND || frame->stacktop < 0) int oparg = code[(frame->f_lasti+1)*sizeof(_Py_CODEUNIT)+1];
if (opcode != RESUME || oparg < 2) {
/* Not in a yield from */
return NULL; return NULL;
}
yf = _PyFrame_StackPeek(frame); yf = _PyFrame_StackPeek(frame);
Py_INCREF(yf); Py_INCREF(yf);
} }

View File

@ -1565,16 +1565,6 @@ trace_function_exit(PyThreadState *tstate, _PyInterpreterFrame *frame, PyObject
return 0; return 0;
} }
static int
skip_backwards_over_extended_args(PyCodeObject *code, int offset)
{
_Py_CODEUNIT *instrs = (_Py_CODEUNIT *)PyBytes_AS_STRING(code->co_code);
while (offset > 0 && _Py_OPCODE(instrs[offset-1]) == EXTENDED_ARG) {
offset--;
}
return offset;
}
static _PyInterpreterFrame * static _PyInterpreterFrame *
pop_frame(PyThreadState *tstate, _PyInterpreterFrame *frame) pop_frame(PyThreadState *tstate, _PyInterpreterFrame *frame)
{ {
@ -5445,7 +5435,7 @@ handle_eval_breaker:
#endif #endif
{ {
if (tstate->tracing == 0) { if (tstate->tracing == 0) {
int instr_prev = skip_backwards_over_extended_args(frame->f_code, frame->f_lasti); int instr_prev = frame->f_lasti;
frame->f_lasti = INSTR_OFFSET(); frame->f_lasti = INSTR_OFFSET();
TRACING_NEXTOPARG(); TRACING_NEXTOPARG();
if (opcode == RESUME) { if (opcode == RESUME) {
@ -6737,9 +6727,13 @@ maybe_call_line_trace(Py_tracefunc func, PyObject *obj,
then call the trace function if we're tracing source lines. then call the trace function if we're tracing source lines.
*/ */
initialize_trace_info(&tstate->trace_info, frame); initialize_trace_info(&tstate->trace_info, frame);
_Py_CODEUNIT prev = ((_Py_CODEUNIT *)PyBytes_AS_STRING(frame->f_code->co_code))[instr_prev]; int entry_point = 0;
_Py_CODEUNIT *code = (_Py_CODEUNIT *)PyBytes_AS_STRING(frame->f_code->co_code);
while (_Py_OPCODE(code[entry_point]) != RESUME) {
entry_point++;
}
int lastline; int lastline;
if (_Py_OPCODE(prev) == RESUME && _Py_OPARG(prev) == 0) { if (instr_prev <= entry_point) {
lastline = -1; lastline = -1;
} }
else { else {