DictUpdate instruction

This commit is contained in:
Jeong YunWon committed 2025-08-08 23:53:40 +09:00
1 parent 33ea50c2e9
commit d56fcd0774
3 files changed
+29 -13

No files matched your search

+1 -1
View File
@@ -4398,7 +4398,7 @@ impl Compiler {
for item in unpacked {
self.compile_expression(&item.value)?;
emit!(self, Instruction::DictUpdate);
emit!(self, Instruction::DictUpdate { index: 1 });
}
Ok(())
+5 -3
View File
@@ -667,7 +667,9 @@ pub enum Instruction {
BuildMapForCall {
size: Arg<u32>,
},
DictUpdate,
DictUpdate {
index: Arg<u32>,
},
BuildSlice {
/// whether build a slice with a third step argument
step: Arg<bool>,
@@ -1397,7 +1399,7 @@ impl Instruction {
let nargs = size.get(arg);
-(nargs as i32) + 1
}
DictUpdate => -1,
DictUpdate { .. } => -1,
BuildSlice { step } => -2 - (step.get(arg) as i32) + 1,
ListAppend { .. } | SetAdd { .. } => -1,
MapAdd { .. } => -2,
@@ -1586,7 +1588,7 @@ impl Instruction {
BuildSetFromTuples { size } => w!(BuildSetFromTuples, size),
BuildMap { size } => w!(BuildMap, size),
BuildMapForCall { size } => w!(BuildMapForCall, size),
DictUpdate => w!(DictUpdate),
DictUpdate { index } => w!(DictUpdate, index),
BuildSlice { step } => w!(BuildSlice, step),
ListAppend { i } => w!(ListAppend, i),
SetAdd { i } => w!(SetAdd, i),
+23 -9
View File
@@ -800,26 +800,40 @@ impl ExecutingFrame<'_> {
bytecode::Instruction::BuildMapForCall { size } => {
self.execute_build_map_for_call(vm, size.get(arg))
}
bytecode::Instruction::DictUpdate => {
let other = self.pop_value();
let dict = self
.top_value()
.downcast_ref::<PyDict>()
.expect("exact dict expected");
bytecode::Instruction::DictUpdate { index } => {
// Stack before: [..., dict, ..., source] (source at TOS)
// Stack after: [..., dict, ...] (source consumed)
// The dict to update is at position TOS-i (before popping source)
let idx = index.get(arg);
// Pop the source from TOS
let source = self.pop_value();
// Get the dict to update (it's now at TOS-(i-1) after popping source)
let dict = if idx <= 1 {
// DICT_UPDATE 0 or 1: dict is at TOS (after popping source)
self.top_value()
} else {
// DICT_UPDATE n: dict is at TOS-(n-1)
self.nth_value(idx - 1)
};
let dict = dict.downcast_ref::<PyDict>().expect("exact dict expected");
// For dictionary unpacking {**x}, x must be a mapping
// Check if the object has the mapping protocol (keys method)
if vm
.get_method(other.clone(), vm.ctx.intern_str("keys"))
.get_method(source.clone(), vm.ctx.intern_str("keys"))
.is_none()
{
return Err(vm.new_type_error(format!(
"'{}' object is not a mapping",
other.class().name()
source.class().name()
)));
}
dict.merge_object(other, vm)?;
dict.merge_object(source, vm)?;
Ok(None)
}
bytecode::Instruction::BuildSlice { step } => {