implement dynamic key; implement __curPos; other small changes
This commit is contained in:
@@ -5,8 +5,7 @@ use smallvec::SmallVec;
|
||||
|
||||
use crate::value::NixType;
|
||||
use crate::{
|
||||
AttrKeyData, AttrSet, BytecodeReader, List, OperandData, Step, StrictValue, Value,
|
||||
VmRuntimeCtx, VmRuntimeCtxExt,
|
||||
AttrSet, BytecodeReader, List, Step, StrictValue, Value, VmRuntimeCtx, VmRuntimeCtxExt,
|
||||
};
|
||||
|
||||
impl<'gc> crate::Vm<'gc> {
|
||||
@@ -17,25 +16,43 @@ impl<'gc> crate::Vm<'gc> {
|
||||
reader: &mut BytecodeReader<'_>,
|
||||
mc: &gc_arena::Mutation<'gc>,
|
||||
) -> Step {
|
||||
let count = reader.read_u32() as usize;
|
||||
let mut entries: SmallVec<[AttrEntry; 4]> = SmallVec::with_capacity(count);
|
||||
for _ in 0..count {
|
||||
let key = reader.read_attr_key_data();
|
||||
let val = reader.read_operand_data(ctx);
|
||||
let _span_id = reader.read_u32();
|
||||
entries.push(AttrEntry { key, val });
|
||||
let static_count = reader.read_u32() as usize;
|
||||
let dynamic_count = reader.read_u32() as usize;
|
||||
|
||||
for i in 0..dynamic_count {
|
||||
let depth = dynamic_count - 1 - i;
|
||||
self.force_slot_to_pc(depth, reader, mc, reader.inst_start_pc())?;
|
||||
}
|
||||
let mut kv: SmallVec<[(crate::StringId, Value); 4]> = SmallVec::with_capacity(count);
|
||||
for entry in &entries {
|
||||
let key_sid = match &entry.key {
|
||||
AttrKeyData::Static(sid) => *sid,
|
||||
AttrKeyData::Dynamic => {
|
||||
todo!()
|
||||
}
|
||||
|
||||
let mut dyn_keys: SmallVec<[crate::StringId; 2]> = SmallVec::with_capacity(dynamic_count);
|
||||
for i in 0..dynamic_count {
|
||||
let depth = dynamic_count - 1 - i;
|
||||
let key_val = self.peek_forced(depth);
|
||||
let key_sid = match ctx.get_string_id(key_val) {
|
||||
Ok(id) => id,
|
||||
Err(got) => return self.finish_type_err(NixType::String, got),
|
||||
};
|
||||
let val = entry.val.resolve(mc, self);
|
||||
kv.push((key_sid, val));
|
||||
dyn_keys.push(key_sid);
|
||||
}
|
||||
|
||||
self.stack.truncate(self.stack.len() - dynamic_count);
|
||||
|
||||
let mut kv: SmallVec<[(crate::StringId, Value); 4]> =
|
||||
SmallVec::with_capacity(static_count + dynamic_count);
|
||||
|
||||
for _ in 0..static_count {
|
||||
let key = reader.read_string_id();
|
||||
let val = reader.read_operand_data(ctx).resolve(mc, self);
|
||||
let _span_id = reader.read_u32();
|
||||
kv.push((key, val));
|
||||
}
|
||||
|
||||
for i in 0..dynamic_count {
|
||||
let val = reader.read_operand_data(ctx).resolve(mc, self);
|
||||
let _span_id = reader.read_u32();
|
||||
kv.push((dyn_keys[i], val));
|
||||
}
|
||||
|
||||
kv.sort_by_key(|(k, _)| *k);
|
||||
let attrs = Gc::new(mc, AttrSet::from_sorted_unchecked(kv));
|
||||
self.push(Value::new_gc(attrs));
|
||||
@@ -312,8 +329,3 @@ impl<'gc> crate::Vm<'gc> {
|
||||
Step::Continue(())
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) struct AttrEntry {
|
||||
pub(crate) key: AttrKeyData,
|
||||
pub(crate) val: OperandData,
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user