Skip to content

Commit 4d5e9c7

Browse files
committed
new instructions
1 parent 7c40889 commit 4d5e9c7

File tree

2 files changed

+51
-1
lines changed

2 files changed

+51
-1
lines changed

compiler/core/src/bytecode.rs

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -442,7 +442,12 @@ pub enum Instruction {
442442
LoadGlobal(Arg<NameIdx>),
443443
LoadDeref(Arg<NameIdx>),
444444
LoadClassDeref(Arg<NameIdx>),
445+
LoadFromDictOrDeref(Arg<NameIdx>),
445446
StoreFast(Arg<NameIdx>),
447+
StoreFastLoadFast {
448+
store_idx: Arg<NameIdx>,
449+
load_idx: Arg<NameIdx>,
450+
},
446451
StoreLocal(Arg<NameIdx>),
447452
StoreGlobal(Arg<NameIdx>),
448453
StoreDeref(Arg<NameIdx>),
@@ -1258,8 +1263,9 @@ impl Instruction {
12581263
ImportName { .. } | ImportNameless => -1,
12591264
ImportStar => -1,
12601265
ImportFrom { .. } => 1,
1261-
LoadFast(_) | LoadNameAny(_) | LoadGlobal(_) | LoadDeref(_) | LoadClassDeref(_) => 1,
1266+
LoadFast(_) | LoadNameAny(_) | LoadGlobal(_) | LoadDeref(_) | LoadClassDeref(_) | LoadFromDictOrDeref(_) => 1,
12621267
StoreFast(_) | StoreLocal(_) | StoreGlobal(_) | StoreDeref(_) => -1,
1268+
StoreFastLoadFast { .. } => 0, // Stores then loads, net effect 0
12631269
DeleteFast(_) | DeleteLocal(_) | DeleteGlobal(_) | DeleteDeref(_) => 0,
12641270
LoadClosure(_) => 1,
12651271
Subscript => -1,
@@ -1462,7 +1468,12 @@ impl Instruction {
14621468
LoadGlobal(idx) => w!(LoadGlobal, name = idx),
14631469
LoadDeref(idx) => w!(LoadDeref, cell_name = idx),
14641470
LoadClassDeref(idx) => w!(LoadClassDeref, cell_name = idx),
1471+
LoadFromDictOrDeref(idx) => w!(LoadFromDictOrDeref, name = idx),
14651472
StoreFast(idx) => w!(StoreFast, varname = idx),
1473+
StoreFastLoadFast { store_idx, load_idx } => {
1474+
write!(f, "StoreFastLoadFast(")?;
1475+
write!(f, "store={}, load={})", store_idx.get(arg), load_idx.get(arg))
1476+
}
14661477
StoreLocal(idx) => w!(StoreLocal, name = idx),
14671478
StoreGlobal(idx) => w!(StoreGlobal, name = idx),
14681479
StoreDeref(idx) => w!(StoreDeref, cell_name = idx),

vm/src/frame.rs

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -606,11 +606,50 @@ impl ExecutingFrame<'_> {
606606
});
607607
Ok(None)
608608
}
609+
bytecode::Instruction::LoadFromDictOrDeref(idx) => {
610+
let name = self.code.names[idx.get(arg) as usize];
611+
let dict = self.locals.as_object();
612+
let value = match dict.get_item(name, vm) {
613+
Ok(value) => value,
614+
Err(_) => {
615+
// Try to load from deref if not in dict
616+
let i = self.code.cellvars.iter().position(|n| n == &name)
617+
.or_else(|| self.code.freevars.iter().position(|n| n == &name)
618+
.map(|i| i + self.code.cellvars.len()))
619+
.ok_or_else(|| vm.new_name_error(format!("name '{}' is not defined", name), name.to_owned()))?;
620+
self.cells_frees[i]
621+
.get()
622+
.ok_or_else(|| self.unbound_cell_exception(i, vm))?
623+
}
624+
};
625+
self.push_value(value);
626+
Ok(None)
627+
}
609628
bytecode::Instruction::StoreFast(idx) => {
610629
let value = self.pop_value();
611630
self.fastlocals.lock()[idx.get(arg) as usize] = Some(value);
612631
Ok(None)
613632
}
633+
bytecode::Instruction::StoreFastLoadFast { store_idx, load_idx } => {
634+
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]
639+
.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+
})?;
650+
self.push_value(loaded);
651+
Ok(None)
652+
}
614653
bytecode::Instruction::StoreLocal(idx) => {
615654
let name = self.code.names[idx.get(arg) as usize];
616655
let value = self.pop_value();

0 commit comments

Comments
 (0)