mirror of
https://github.com/python/cpython.git
synced 2025-07-09 20:35:26 +00:00
GH-100982: Restrict FOR_ITER_RANGE
to a single instruction to allow instrumentation. (GH-101985)
This commit is contained in:
parent
8d46c7ed5e
commit
7c106a443f
4 changed files with 22 additions and 30 deletions
|
@ -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;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue