diff options
author | Mark Shannon <mark@hotpy.org> | 2023-02-22 11:11:57 +0000 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-02-22 11:11:57 +0000 |
commit | 7c106a443f8cf1111947a425eed11ecf9e615ce3 (patch) | |
tree | 37ef7da55ba40c546b530c9dcbf70877d5736ff9 /Python/bytecodes.c | |
parent | 8d46c7ed5e83e22d55fe4f4e6e873d87f340c1dc (diff) | |
download | cpython-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.c | 24 |
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; |