[3.14] gh-134889: Fix handling of a few opcodes when optimizing LOAD_FAST (#134958) (#135187)

We were incorrectly handling a few opcodes that leave their operands on the stack. Treat all of these conservatively; assume that they always leave operands on the stack.

(cherry picked from commit 6b77af257c)
This commit is contained in:
mpage 2025-06-05 13:06:51 -07:00 committed by GitHub
parent 945af60f04
commit be2f32e60f
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 117 additions and 2 deletions

View file

@ -2862,8 +2862,10 @@ optimize_load_fast(cfg_builder *g)
// how many inputs should be left on the stack.
// Opcodes that consume no inputs
case FORMAT_SIMPLE:
case GET_ANEXT:
case GET_LEN:
case GET_YIELD_FROM_ITER:
case IMPORT_FROM:
case MATCH_KEYS:
case MATCH_MAPPING:
@ -2898,6 +2900,16 @@ optimize_load_fast(cfg_builder *g)
break;
}
case END_SEND:
case SET_FUNCTION_ATTRIBUTE: {
assert(_PyOpcode_num_popped(opcode, oparg) == 2);
assert(_PyOpcode_num_pushed(opcode, oparg) == 1);
ref tos = ref_stack_pop(&refs);
ref_stack_pop(&refs);
PUSH_REF(tos.instr, tos.local);
break;
}
// Opcodes that consume some inputs and push new values
case CHECK_EXC_MATCH: {
ref_stack_pop(&refs);
@ -2927,6 +2939,14 @@ optimize_load_fast(cfg_builder *g)
break;
}
case LOAD_SPECIAL:
case PUSH_EXC_INFO: {
ref tos = ref_stack_pop(&refs);
PUSH_REF(i, NOT_LOCAL);
PUSH_REF(tos.instr, tos.local);
break;
}
case SEND: {
load_fast_push_block(&sp, instr->i_target, refs.size);
ref_stack_pop(&refs);