summaryrefslogtreecommitdiffstats
path: root/Python/bytecodes.c
diff options
context:
space:
mode:
authorMark Shannon <mark@hotpy.org>2023-04-13 15:19:07 (GMT)
committerGitHub <noreply@github.com>2023-04-13 15:19:07 (GMT)
commitefb8a2553c88a295514be228c44fb99ef035e3fa (patch)
treed8318deba8f8d98ce99751dcfabec6f44b5d053e /Python/bytecodes.c
parent4307feaddc76b9e93cd38e325a1f0ee59d593093 (diff)
downloadcpython-efb8a2553c88a295514be228c44fb99ef035e3fa.zip
cpython-efb8a2553c88a295514be228c44fb99ef035e3fa.tar.gz
cpython-efb8a2553c88a295514be228c44fb99ef035e3fa.tar.bz2
GH-103488: Use return-offset, not yield-offset. (GH-103502)
* Use return-offset, not yield-offset, so that instruction pointer is correct when sending to a generator or coroutine.
Diffstat (limited to 'Python/bytecodes.c')
-rw-r--r--Python/bytecodes.c28
1 files changed, 18 insertions, 10 deletions
diff --git a/Python/bytecodes.c b/Python/bytecodes.c
index 5c6398a..7af96b4 100644
--- a/Python/bytecodes.c
+++ b/Python/bytecodes.c
@@ -506,6 +506,7 @@ dummy_func(
new_frame->localsplus[0] = container;
new_frame->localsplus[1] = sub;
JUMPBY(INLINE_CACHE_ENTRIES_BINARY_SUBSCR);
+ frame->return_offset = 0;
DISPATCH_INLINED(new_frame);
}
@@ -637,6 +638,7 @@ dummy_func(
_PyInterpreterFrame *dying = frame;
frame = cframe.current_frame = dying->previous;
_PyEvalFrameClearAndPop(tstate, dying);
+ frame->prev_instr += frame->return_offset;
_PyFrame_StackPush(frame, retval);
goto resume_frame;
}
@@ -655,6 +657,7 @@ dummy_func(
_PyInterpreterFrame *dying = frame;
frame = cframe.current_frame = dying->previous;
_PyEvalFrameClearAndPop(tstate, dying);
+ frame->prev_instr += frame->return_offset;
_PyFrame_StackPush(frame, retval);
goto resume_frame;
}
@@ -670,6 +673,7 @@ dummy_func(
_PyInterpreterFrame *dying = frame;
frame = cframe.current_frame = dying->previous;
_PyEvalFrameClearAndPop(tstate, dying);
+ frame->prev_instr += frame->return_offset;
_PyFrame_StackPush(frame, retval);
goto resume_frame;
}
@@ -689,6 +693,7 @@ dummy_func(
_PyInterpreterFrame *dying = frame;
frame = cframe.current_frame = dying->previous;
_PyEvalFrameClearAndPop(tstate, dying);
+ frame->prev_instr += frame->return_offset;
_PyFrame_StackPush(frame, retval);
goto resume_frame;
}
@@ -823,13 +828,13 @@ dummy_func(
{
PyGenObject *gen = (PyGenObject *)receiver;
_PyInterpreterFrame *gen_frame = (_PyInterpreterFrame *)gen->gi_iframe;
- frame->yield_offset = oparg;
+ frame->return_offset = oparg;
STACK_SHRINK(1);
_PyFrame_StackPush(gen_frame, v);
gen->gi_frame_state = FRAME_EXECUTING;
gen->gi_exc_state.previous_item = tstate->exc_info;
tstate->exc_info = &gen->gi_exc_state;
- JUMPBY(INLINE_CACHE_ENTRIES_SEND + oparg);
+ JUMPBY(INLINE_CACHE_ENTRIES_SEND);
DISPATCH_INLINED(gen_frame);
}
if (Py_IsNone(v) && PyIter_Check(receiver)) {
@@ -861,13 +866,13 @@ dummy_func(
DEOPT_IF(gen->gi_frame_state >= FRAME_EXECUTING, SEND);
STAT_INC(SEND, hit);
_PyInterpreterFrame *gen_frame = (_PyInterpreterFrame *)gen->gi_iframe;
- frame->yield_offset = oparg;
+ frame->return_offset = oparg;
STACK_SHRINK(1);
_PyFrame_StackPush(gen_frame, v);
gen->gi_frame_state = FRAME_EXECUTING;
gen->gi_exc_state.previous_item = tstate->exc_info;
tstate->exc_info = &gen->gi_exc_state;
- JUMPBY(INLINE_CACHE_ENTRIES_SEND + oparg);
+ JUMPBY(INLINE_CACHE_ENTRIES_SEND);
DISPATCH_INLINED(gen_frame);
}
@@ -886,7 +891,6 @@ dummy_func(
_PyInterpreterFrame *gen_frame = frame;
frame = cframe.current_frame = frame->previous;
gen_frame->previous = NULL;
- frame->prev_instr -= frame->yield_offset;
_PyFrame_StackPush(frame, retval);
goto resume_frame;
}
@@ -905,7 +909,6 @@ dummy_func(
_PyInterpreterFrame *gen_frame = frame;
frame = cframe.current_frame = frame->previous;
gen_frame->previous = NULL;
- frame->prev_instr -= frame->yield_offset;
_PyFrame_StackPush(frame, retval);
goto resume_frame;
}
@@ -1724,6 +1727,7 @@ dummy_func(
STACK_SHRINK(shrink_stack);
new_frame->localsplus[0] = owner;
JUMPBY(INLINE_CACHE_ENTRIES_LOAD_ATTR);
+ frame->return_offset = 0;
DISPATCH_INLINED(new_frame);
}
@@ -1751,6 +1755,7 @@ dummy_func(
new_frame->localsplus[0] = owner;
new_frame->localsplus[1] = Py_NewRef(name);
JUMPBY(INLINE_CACHE_ENTRIES_LOAD_ATTR);
+ frame->return_offset = 0;
DISPATCH_INLINED(new_frame);
}
@@ -2259,14 +2264,14 @@ dummy_func(
DEOPT_IF(gen->gi_frame_state >= FRAME_EXECUTING, FOR_ITER);
STAT_INC(FOR_ITER, hit);
_PyInterpreterFrame *gen_frame = (_PyInterpreterFrame *)gen->gi_iframe;
- frame->yield_offset = oparg;
+ frame->return_offset = oparg;
_PyFrame_StackPush(gen_frame, Py_NewRef(Py_None));
gen->gi_frame_state = FRAME_EXECUTING;
gen->gi_exc_state.previous_item = tstate->exc_info;
tstate->exc_info = &gen->gi_exc_state;
- JUMPBY(INLINE_CACHE_ENTRIES_FOR_ITER + oparg);
- assert(next_instr->op.code == END_FOR ||
- next_instr->op.code == INSTRUMENTED_END_FOR);
+ JUMPBY(INLINE_CACHE_ENTRIES_FOR_ITER);
+ assert(next_instr[oparg].op.code == END_FOR ||
+ next_instr[oparg].op.code == INSTRUMENTED_END_FOR);
DISPATCH_INLINED(gen_frame);
}
@@ -2521,6 +2526,7 @@ dummy_func(
goto error;
}
JUMPBY(INLINE_CACHE_ENTRIES_CALL);
+ frame->return_offset = 0;
DISPATCH_INLINED(new_frame);
}
/* Callable is not a normal Python function */
@@ -2594,6 +2600,7 @@ dummy_func(
// Manipulate stack directly since we leave using DISPATCH_INLINED().
STACK_SHRINK(oparg + 2);
JUMPBY(INLINE_CACHE_ENTRIES_CALL);
+ frame->return_offset = 0;
DISPATCH_INLINED(new_frame);
}
@@ -2631,6 +2638,7 @@ dummy_func(
// Manipulate stack and cache directly since we leave using DISPATCH_INLINED().
STACK_SHRINK(oparg + 2);
JUMPBY(INLINE_CACHE_ENTRIES_CALL);
+ frame->return_offset = 0;
DISPATCH_INLINED(new_frame);
}