summaryrefslogtreecommitdiff
path: root/Python/bytecodes.c
diff options
context:
space:
mode:
authorMark Shannon <mark@hotpy.org>2023-02-22 11:11:57 +0000
committerGitHub <noreply@github.com>2023-02-22 11:11:57 +0000
commit7c106a443f8cf1111947a425eed11ecf9e615ce3 (patch)
tree37ef7da55ba40c546b530c9dcbf70877d5736ff9 /Python/bytecodes.c
parent8d46c7ed5e83e22d55fe4f4e6e873d87f340c1dc (diff)
downloadcpython-git-7c106a443f8cf1111947a425eed11ecf9e615ce3.tar.gz
GH-100982: Restrict `FOR_ITER_RANGE` to a single instruction to allow instrumentation. (GH-101985)
Diffstat (limited to 'Python/bytecodes.c')
-rw-r--r--Python/bytecodes.c24
1 files changed, 8 insertions, 16 deletions
diff --git a/Python/bytecodes.c b/Python/bytecodes.c
index c5959f2f99..ad68c794fe 100644
--- a/Python/bytecodes.c
+++ b/Python/bytecodes.c
@@ -2178,35 +2178,27 @@ dummy_func(
// Common case: no jump, leave it to the code generator
}
- // This is slightly different, when the loop isn't terminated we
- // jump over the immediately following STORE_FAST instruction.
- inst(FOR_ITER_RANGE, (unused/1, iter -- iter, unused)) {
+ inst(FOR_ITER_RANGE, (unused/1, iter -- iter, next)) {
assert(cframe.use_tracing == 0);
_PyRangeIterObject *r = (_PyRangeIterObject *)iter;
DEOPT_IF(Py_TYPE(r) != &PyRangeIter_Type, FOR_ITER);
STAT_INC(FOR_ITER, hit);
- _Py_CODEUNIT next = next_instr[INLINE_CACHE_ENTRIES_FOR_ITER];
- assert(_PyOpcode_Deopt[next.op.code] == STORE_FAST);
if (r->len <= 0) {
STACK_SHRINK(1);
Py_DECREF(r);
// Jump over END_FOR instruction.
JUMPBY(INLINE_CACHE_ENTRIES_FOR_ITER + oparg + 1);
+ DISPATCH();
}
- else {
- long value = r->start;
- r->start = value + r->step;
- r->len--;
- if (_PyLong_AssignValue(&GETLOCAL(next.op.arg), value) < 0) {
- goto error;
- }
- // The STORE_FAST is already done.
- JUMPBY(INLINE_CACHE_ENTRIES_FOR_ITER + 1);
+ long value = r->start;
+ r->start = value + r->step;
+ r->len--;
+ next = PyLong_FromLong(value);
+ if (next == NULL) {
+ goto error;
}
- DISPATCH();
}
- // This is *not* a super-instruction, unique in the family.
inst(FOR_ITER_GEN, (unused/1, iter -- iter, unused)) {
assert(cframe.use_tracing == 0);
PyGenObject *gen = (PyGenObject *)iter;