Skip to content

Commit 4fbdd32

Browse files
committed
new instructions?
1 parent 4d5e9c7 commit 4fbdd32

File tree

2 files changed

+60
-18
lines changed

2 files changed

+60
-18
lines changed

compiler/core/src/bytecode.rs

Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -456,6 +456,8 @@ pub enum Instruction {
456456
DeleteGlobal(Arg<NameIdx>),
457457
DeleteDeref(Arg<NameIdx>),
458458
LoadClosure(Arg<NameIdx>),
459+
MakeCell(Arg<NameIdx>),
460+
CopyFreeVars(Arg<u32>),
459461
Subscript,
460462
StoreSubscript,
461463
DeleteSubscript,
@@ -1263,11 +1265,18 @@ impl Instruction {
12631265
ImportName { .. } | ImportNameless => -1,
12641266
ImportStar => -1,
12651267
ImportFrom { .. } => 1,
1266-
LoadFast(_) | LoadNameAny(_) | LoadGlobal(_) | LoadDeref(_) | LoadClassDeref(_) | LoadFromDictOrDeref(_) => 1,
1268+
LoadFast(_)
1269+
| LoadNameAny(_)
1270+
| LoadGlobal(_)
1271+
| LoadDeref(_)
1272+
| LoadClassDeref(_)
1273+
| LoadFromDictOrDeref(_) => 1,
12671274
StoreFast(_) | StoreLocal(_) | StoreGlobal(_) | StoreDeref(_) => -1,
12681275
StoreFastLoadFast { .. } => 0, // Stores then loads, net effect 0
12691276
DeleteFast(_) | DeleteLocal(_) | DeleteGlobal(_) | DeleteDeref(_) => 0,
12701277
LoadClosure(_) => 1,
1278+
MakeCell(_) => 0,
1279+
CopyFreeVars(n) => 0, // Copies from closure to locals, no stack effect
12711280
Subscript => -1,
12721281
StoreSubscript => -3,
12731282
DeleteSubscript => -2,
@@ -1470,9 +1479,17 @@ impl Instruction {
14701479
LoadClassDeref(idx) => w!(LoadClassDeref, cell_name = idx),
14711480
LoadFromDictOrDeref(idx) => w!(LoadFromDictOrDeref, name = idx),
14721481
StoreFast(idx) => w!(StoreFast, varname = idx),
1473-
StoreFastLoadFast { store_idx, load_idx } => {
1482+
StoreFastLoadFast {
1483+
store_idx,
1484+
load_idx,
1485+
} => {
14741486
write!(f, "StoreFastLoadFast(")?;
1475-
write!(f, "store={}, load={})", store_idx.get(arg), load_idx.get(arg))
1487+
write!(
1488+
f,
1489+
"store={}, load={})",
1490+
store_idx.get(arg),
1491+
load_idx.get(arg)
1492+
)
14761493
}
14771494
StoreLocal(idx) => w!(StoreLocal, name = idx),
14781495
StoreGlobal(idx) => w!(StoreGlobal, name = idx),
@@ -1578,6 +1595,8 @@ impl Instruction {
15781595
TypeAlias => w!(TypeAlias),
15791596
ParamSpec => w!(ParamSpec),
15801597
TypeVarTuple => w!(TypeVarTuple),
1598+
MakeCell(idx) => w!(MakeCell, cell_name = idx),
1599+
CopyFreeVars(count) => w!(CopyFreeVars, count),
15811600
}
15821601
}
15831602
}

vm/src/frame.rs

Lines changed: 38 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -630,23 +630,21 @@ impl ExecutingFrame<'_> {
630630
self.fastlocals.lock()[idx.get(arg) as usize] = Some(value);
631631
Ok(None)
632632
}
633-
bytecode::Instruction::StoreFastLoadFast { store_idx, load_idx } => {
633+
bytecode::Instruction::StoreFastLoadFast {
634+
store_idx,
635+
load_idx,
636+
} => {
634637
let value = self.pop_value();
635-
// Store the value
636-
self.fastlocals.lock()[store_idx.get(arg) as usize] = Some(value.clone());
637-
// Then load from a different fast local
638-
let loaded = self.fastlocals.lock()[load_idx.get(arg) as usize]
638+
639+
// Store the value at store_idx
640+
let mut fastlocals = self.fastlocals.lock();
641+
fastlocals[store_idx.get(arg) as usize] = Some(value);
642+
643+
// Load from load_idx (which might be the same as store_idx)
644+
let loaded = fastlocals[load_idx.get(arg) as usize]
639645
.clone()
640-
.ok_or_else(|| {
641-
let varname = self.code.varnames[load_idx.get(arg) as usize];
642-
vm.new_exception(
643-
vm.ctx.exceptions.unbound_local_error.to_owned(),
644-
vec![vm
645-
.ctx
646-
.new_str(format!("local variable '{varname}' referenced before assignment"))
647-
.into()],
648-
)
649-
})?;
646+
.expect("must exist");
647+
drop(fastlocals); // Release the lock before pushing
650648
self.push_value(loaded);
651649
Ok(None)
652650
}
@@ -715,6 +713,31 @@ impl ExecutingFrame<'_> {
715713
self.push_value(value.into());
716714
Ok(None)
717715
}
716+
bytecode::Instruction::MakeCell(i) => {
717+
// Create a new cell for the given name
718+
let idx = i.get(arg) as usize;
719+
if idx < self.cells_frees.len() {
720+
// Cell already exists, skip
721+
} else {
722+
// This is a simplified implementation
723+
// In CPython, MAKE_CELL creates cells for variables that will be used in closures
724+
}
725+
Ok(None)
726+
}
727+
bytecode::Instruction::CopyFreeVars(n) => {
728+
// Copy free variables from the closure to fast locals
729+
let n = n.get(arg) as usize;
730+
// In CPython, this copies free variables from the function's closure
731+
// to the frame's fast locals at the beginning of the code object
732+
let mut fastlocals = self.fastlocals.lock();
733+
for i in 0..n.min(self.cells_frees.len()) {
734+
let value = self.cells_frees[i].get();
735+
if i < fastlocals.len() {
736+
fastlocals[i] = value;
737+
}
738+
}
739+
Ok(None)
740+
}
718741
bytecode::Instruction::Subscript => self.execute_subscript(vm),
719742
bytecode::Instruction::StoreSubscript => self.execute_store_subscript(vm),
720743
bytecode::Instruction::DeleteSubscript => self.execute_delete_subscript(vm),

0 commit comments

Comments
 (0)