Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Next Next commit
Remove Instruction::Duplicate2?
  • Loading branch information
ShaharNaveh committed Nov 28, 2025
commit 8c7674cabbc05a9414c58570a663f4ba6a4caba9
27 changes: 14 additions & 13 deletions crates/codegen/src/compile.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1063,7 +1063,7 @@ impl Compiler {

if let Stmt::Expr(StmtExpr { value, .. }) = &last {
self.compile_expression(value)?;
emit!(self, Instruction::Duplicate);
emit!(self, Instruction::CopyItem { index: 1_u32 });
emit!(self, Instruction::PrintExpr);
} else {
self.compile_statement(last)?;
Expand Down Expand Up @@ -1094,7 +1094,7 @@ impl Compiler {
Stmt::FunctionDef(_) | Stmt::ClassDef(_) => {
let pop_instructions = self.current_block().instructions.pop();
let store_inst = compiler_unwrap_option(self, pop_instructions); // pop Instruction::Store
emit!(self, Instruction::Duplicate);
emit!(self, Instruction::CopyItem { index: 1_u32 });
self.current_block().instructions.push(store_inst);
}
_ => self.emit_load_const(ConstantData::None),
Expand Down Expand Up @@ -1656,7 +1656,7 @@ impl Compiler {

for (i, target) in targets.iter().enumerate() {
if i + 1 != targets.len() {
emit!(self, Instruction::Duplicate);
emit!(self, Instruction::CopyItem { index: 1_u32 });
}
self.compile_store(target)?;
}
Expand Down Expand Up @@ -1917,7 +1917,7 @@ impl Compiler {
);
}

emit!(self, Instruction::Duplicate);
emit!(self, Instruction::CopyItem { index: 1_u32 });
self.store_name(name.as_ref())?;
}
TypeParam::ParamSpec(TypeParamParamSpec { name, default, .. }) => {
Expand All @@ -1943,7 +1943,7 @@ impl Compiler {
);
}

emit!(self, Instruction::Duplicate);
emit!(self, Instruction::CopyItem { index: 1_u32 });
self.store_name(name.as_ref())?;
}
TypeParam::TypeVarTuple(TypeParamTypeVarTuple { name, default, .. }) => {
Expand All @@ -1970,7 +1970,7 @@ impl Compiler {
);
}

emit!(self, Instruction::Duplicate);
emit!(self, Instruction::CopyItem { index: 1_u32 });
self.store_name(name.as_ref())?;
}
};
Expand Down Expand Up @@ -2030,7 +2030,7 @@ impl Compiler {
// check if this handler can handle the exception:
if let Some(exc_type) = type_ {
// Duplicate exception for test:
emit!(self, Instruction::Duplicate);
emit!(self, Instruction::CopyItem { index: 1_u32 });

// Check exception type:
self.compile_expression(exc_type)?;
Expand Down Expand Up @@ -2251,7 +2251,7 @@ impl Compiler {

// Handle docstring if present
if let Some(doc) = doc_str {
emit!(self, Instruction::Duplicate);
emit!(self, Instruction::CopyItem { index: 1_u32 });
self.emit_load_const(ConstantData::Str {
value: doc.to_string().into(),
});
Expand Down Expand Up @@ -2726,7 +2726,7 @@ impl Compiler {

if let Some(classcell_idx) = classcell_idx {
emit!(self, Instruction::LoadClosure(classcell_idx.to_u32()));
emit!(self, Instruction::Duplicate);
emit!(self, Instruction::CopyItem { index: 1_u32 });
let classcell = self.name("__classcell__");
emit!(self, Instruction::StoreLocal(classcell));
} else {
Expand Down Expand Up @@ -4121,7 +4121,7 @@ impl Compiler {
for (op, val) in mid_ops.iter().zip(mid_exprs) {
self.compile_expression(val)?;
// store rhs for the next comparison in chain
emit!(self, Instruction::Duplicate);
emit!(self, Instruction::CopyItem { index: 1_u32 });
emit!(self, Instruction::Rotate3);

compile_cmpop(self, op);
Expand Down Expand Up @@ -4322,15 +4322,16 @@ impl Compiler {
// But we can't use compile_subscript directly because we need DUP_TOP2
self.compile_expression(value)?;
self.compile_expression(slice)?;
emit!(self, Instruction::Duplicate2);
emit!(self, Instruction::CopyItem { index: 2_u32 });
emit!(self, Instruction::CopyItem { index: 2_u32 });
emit!(self, Instruction::Subscript);
AugAssignKind::Subscript
}
Expr::Attribute(ExprAttribute { value, attr, .. }) => {
let attr = attr.as_str();
self.check_forbidden_name(attr, NameUsage::Store)?;
self.compile_expression(value)?;
emit!(self, Instruction::Duplicate);
emit!(self, Instruction::CopyItem { index: 1_u32 });
let idx = self.name(attr);
emit!(self, Instruction::LoadAttr { idx });
AugAssignKind::Attr { idx }
Expand Down Expand Up @@ -4896,7 +4897,7 @@ impl Compiler {
range: _,
}) => {
self.compile_expression(value)?;
emit!(self, Instruction::Duplicate);
emit!(self, Instruction::CopyItem { index: 1_u32 });
self.compile_store(target)?;
}
Expr::FString(fstring) => {
Expand Down
6 changes: 0 additions & 6 deletions crates/compiler-core/src/bytecode.rs
Original file line number Diff line number Diff line change
Expand Up @@ -616,8 +616,6 @@ pub enum Instruction {
ToBool,
Rotate2,
Rotate3,
Duplicate,
Duplicate2,
GetIter,
GetLen,
CallIntrinsic1 {
Expand Down Expand Up @@ -1476,8 +1474,6 @@ impl Instruction {
Swap { .. } => 0,
ToBool => 0,
Rotate2 | Rotate3 => 0,
Duplicate => 1,
Duplicate2 => 2,
GetIter => 0,
GetLen => 1,
CallIntrinsic1 { .. } => 0, // Takes 1, pushes 1
Expand Down Expand Up @@ -1680,8 +1676,6 @@ impl Instruction {
ToBool => w!(ToBool),
Rotate2 => w!(Rotate2),
Rotate3 => w!(Rotate3),
Duplicate => w!(Duplicate),
Duplicate2 => w!(Duplicate2),
GetIter => w!(GetIter),
// GET_LEN
GetLen => w!(GetLen),
Expand Down
29 changes: 9 additions & 20 deletions crates/vm/src/frame.rs
Original file line number Diff line number Diff line change
Expand Up @@ -719,27 +719,16 @@ impl ExecutingFrame<'_> {
self.state.stack.swap(i, j);
Ok(None)
}
// bytecode::Instruction::ToBool => {
// dbg!("Shouldn't be called outside of match statements for now")
// let value = self.pop_value();
// // call __bool__
// let result = value.try_to_bool(vm)?;
// self.push_value(vm.ctx.new_bool(result).into());
// Ok(None)
// }
bytecode::Instruction::Duplicate => {
// Duplicate top of stack
let value = self.top_value();
self.push_value(value.to_owned());
Ok(None)
}
bytecode::Instruction::Duplicate2 => {
// Duplicate top 2 of stack
let len = self.state.stack.len();
self.push_value(self.state.stack[len - 2].clone());
self.push_value(self.state.stack[len - 1].clone());
Ok(None)
/*
bytecode::Instruction::ToBool => {
dbg!("Shouldn't be called outside of match statements for now")
let value = self.pop_value();
// call __bool__
let result = value.try_to_bool(vm)?;
self.push_value(vm.ctx.new_bool(result).into());
Ok(None)
}
*/
// splitting the instructions like this offloads the cost of "dynamic" dispatch (on the
// amount to rotate) to the opcode dispatcher, and generates optimized code for the
// concrete cases we actually have
Expand Down