Skip to content
Prev Previous commit
Next Next commit
Restore PopJumpIf instructions
  • Loading branch information
ShaharNaveh committed Dec 26, 2025
commit 48f377228a4c4ff94d2448c32a97d3769d1fed69
21 changes: 21 additions & 0 deletions crates/compiler-core/src/bytecode.rs
Original file line number Diff line number Diff line change
Expand Up @@ -736,10 +736,20 @@ pub enum Instruction {
},
/// Performs `is` comparison, or `is not` if `invert` is 1.
IsOp(Arg<Invert>),
/// Peek at the top of the stack, and jump if this value is false.
/// Otherwise, pop top of stack.
JumpIfFalseOrPop {
target: Arg<Label>,
},
/// Performs exception matching for except.
/// Tests whether the STACK[-2] is an exception matching STACK[-1].
/// Pops STACK[-1] and pushes the boolean result of the test.
JumpIfNotExcMatch(Arg<Label>),
/// Peek at the top of the stack, and jump if this value is true.
/// Otherwise, pop top of stack.
JumpIfTrueOrPop {
target: Arg<Label>,
},
Jump {
target: Arg<Label>,
},
Expand Down Expand Up @@ -1611,6 +1621,8 @@ impl Instruction {
| JumpIfNotExcMatch(l)
| PopJumpIfTrue { target: l }
| PopJumpIfFalse { target: l }
| JumpIfTrueOrPop { target: l }
| JumpIfFalseOrPop { target: l }
| ForIter { target: l }
| SetupFinally { handler: l }
| SetupExcept { handler: l }
Expand Down Expand Up @@ -1688,6 +1700,13 @@ impl Instruction {
Break { .. } => 0,
Jump { .. } => 0,
PopJumpIfTrue { .. } | PopJumpIfFalse { .. } => -1,
JumpIfTrueOrPop { .. } | JumpIfFalseOrPop { .. } => {
if jump {
0
} else {
-1
}
}
MakeFunction => {
// CPython 3.13 style: MakeFunction only pops code object
-1 + 1 // pop code, push function
Expand Down Expand Up @@ -1895,7 +1914,9 @@ impl Instruction {
ImportFrom { idx } => w!(IMPORT_FROM, name = idx),
ImportName { idx } => w!(IMPORT_NAME, name = idx),
IsOp(inv) => w!(IS_OP, ?inv),
JumpIfFalseOrPop { target } => w!(JUMP_IF_FALSE_OR_POP, target),
JumpIfNotExcMatch(target) => w!(JUMP_IF_NOT_EXC_MATCH, target),
JumpIfTrueOrPop { target } => w!(JUMP_IF_TRUE_OR_POP, target),
Jump { target } => w!(JUMP, target),
ListAppend { i } => w!(LIST_APPEND, i),
LoadAttr { idx } => w!(LOAD_ATTR, name = idx),
Expand Down
23 changes: 23 additions & 0 deletions crates/vm/src/frame.rs
Original file line number Diff line number Diff line change
Expand Up @@ -981,6 +981,9 @@ impl ExecutingFrame<'_> {
self.push_value(vm.ctx.new_bool(value).into());
Ok(None)
}
bytecode::Instruction::JumpIfFalseOrPop { target } => {
self.jump_if_or_pop(vm, target.get(arg), false)
}
bytecode::Instruction::JumpIfNotExcMatch(target) => {
let b = self.pop_value();
let a = self.pop_value();
Expand All @@ -1004,6 +1007,9 @@ impl ExecutingFrame<'_> {
self.push_value(vm.ctx.new_bool(value).into());
self.pop_jump_if(vm, target.get(arg), false)
}
bytecode::Instruction::JumpIfTrueOrPop { target } => {
self.jump_if_or_pop(vm, target.get(arg), true)
}
bytecode::Instruction::Jump { target } => {
self.jump(target.get(arg));
Ok(None)
Expand Down Expand Up @@ -2041,6 +2047,23 @@ impl ExecutingFrame<'_> {
Ok(None)
}

#[inline]
fn jump_if_or_pop(
&mut self,
vm: &VirtualMachine,
target: bytecode::Label,
flag: bool,
) -> FrameResult {
let obj = self.top_value();
let value = obj.to_owned().try_to_bool(vm)?;
if value == flag {
self.jump(target);
} else {
self.pop_value();
}
Ok(None)
}

/// The top of stack contains the iterator, lets push it forward
fn execute_for_iter(&mut self, vm: &VirtualMachine, target: bytecode::Label) -> FrameResult {
let top_of_stack = PyIter::new(self.top_value());
Expand Down