Description
EXTENDED_ARG_QUICK
is a problematic opcode, and I think we should expose it less than we currently do. It is the only "quickened" opcode emitted by the compiler and found in code.co_code
, which requires us to jump through strange hoops in several places (I'm looking at you, _PyOpcode_Original
). Even weirder, it traces as EXTENDED_ARG
at runtime.
- it's not documented anywhere in the
dis
documentation - it's not even a "real" opcode exposed by any of the helpers in the
opcode
module (which still defines a misleadingly uselessEXTENDED_ARG
constant) - it's less than
HAVE_ARGUMENT
, even though it (obviously) uses its argument - it's not understood by things like
stack_effect
Yet consumers of the bytecode must handle it correctly. We've already seen several bugs in CPython where we wrongly thought that we were handling extended arguments, and code that's been unchanged for years silently stopped working correctly. Let's avoid putting user code through the same pain.
I propose that we only emit the normal EXTENDED_ARG
in the compiler, like we always have, and use _PyOpcode_Deopt
everywhere that _PyOpcode_Original
is being used now. We'll quicken EXTENDED_ARG
to EXTENDED_ARG_QUICK
just like all of the other *_QUICK
opcode variants. No need to change the magic number or anything, since old code will continue to work fine. Although EXTENDED_ARG
is in theory a tiny bit slower (it deopts the next opcode using _PyOpcode_Deopt
), I doubt this is actually measurable.
Thoughts? I really think we should try to do this in 3.11, since it's a relatively simple change.