There's a variety of places where we walk over an array of instructions, using some variant of
for (int i = 0; i < num_instructions;) {
int opcode = instructions[i].op.code;
// <decode EXTENDED_ARG>
opcode = _PyOpcode_Deopt[opcode]; // or _Py_GetBaseOpcode(code, i)
// <handle opcode>
i += 1 + _PyOpcode_Caches[opcode]; // or _PyInstruction_GetLength(code, i)
}
All these make the mistake that if opcode is ENTER_EXECUTOR, it may obscure an underlying JUMP_BACKWARD instruction, which has a cache entry.
I fixed this in gh-107256 for _PyInstruction_GetLength() and it was first reported in gh-107082, but there are a number of other occurrences. Basically every time we consult _PyOpcode_Caches we should ensure that the index is not ENTER_EXECUTOR.
CC: @markshannon
Places where I found this:
There are possibly others.
Linked PRs
There's a variety of places where we walk over an array of instructions, using some variant of
All these make the mistake that if
opcodeisENTER_EXECUTOR, it may obscure an underlyingJUMP_BACKWARDinstruction, which has a cache entry.I fixed this in gh-107256 for
_PyInstruction_GetLength()and it was first reported in gh-107082, but there are a number of other occurrences. Basically every time we consult_PyOpcode_Cacheswe should ensure that the index is notENTER_EXECUTOR.CC: @markshannon
Places where I found this:
_Py_GetBaseOpcode[should not be "fixed", it would break callers that need the oparg]There are possibly others.
Linked PRs