fix: null dynamic attrs

This commit is contained in:
2026-05-05 00:28:38 +08:00
parent 4aff27142c
commit 49392f66f8
4 changed files with 13 additions and 14 deletions
+7 -4
View File
@@ -24,12 +24,13 @@ impl<'gc> crate::Vm<'gc> {
self.force_slot_to_pc(depth, reader, mc, reader.inst_start_pc())?; self.force_slot_to_pc(depth, reader, mc, reader.inst_start_pc())?;
} }
let mut dyn_keys: SmallVec<[crate::StringId; 2]> = SmallVec::with_capacity(dynamic_count); let mut dyn_keys: SmallVec<[_; 2]> = SmallVec::with_capacity(dynamic_count);
for i in 0..dynamic_count { for i in 0..dynamic_count {
let depth = dynamic_count - 1 - i; let depth = dynamic_count - 1 - i;
let key_val = self.peek_forced(depth); let key_val = self.peek_forced(depth);
let key_sid = match ctx.get_string_id(key_val) { let key_sid = match ctx.get_string_id(key_val) {
Ok(id) => id, Ok(id) => Some(id),
Err(NixType::Null) => None,
Err(got) => return self.finish_type_err(NixType::String, got), Err(got) => return self.finish_type_err(NixType::String, got),
}; };
dyn_keys.push(key_sid); dyn_keys.push(key_sid);
@@ -47,10 +48,12 @@ impl<'gc> crate::Vm<'gc> {
kv.push((key, val)); kv.push((key, val));
} }
for i in 0..dynamic_count { for key in dyn_keys {
let val = reader.read_operand_data(ctx).resolve(mc, self); let val = reader.read_operand_data(ctx).resolve(mc, self);
let _span_id = reader.read_u32(); let _span_id = reader.read_u32();
kv.push((dyn_keys[i], val)); if let Some(key) = key {
kv.push((key, val))
}
} }
kv.sort_by_key(|(k, _)| *k); kv.sort_by_key(|(k, _)| *k);
+1 -4
View File
@@ -4,12 +4,11 @@ use gc_arena::{Gc, Mutation, RefLock};
use smallvec::SmallVec; use smallvec::SmallVec;
use crate::value::*; use crate::value::*;
use crate::{BytecodeReader, NixNum, Step, Vm, VmRuntimeCtx, VmRuntimeCtxExt}; use crate::{BytecodeReader, Step, Vm, VmRuntimeCtx, VmRuntimeCtxExt};
impl<'gc> Vm<'gc> { impl<'gc> Vm<'gc> {
pub(crate) fn primop_seq( pub(crate) fn primop_seq(
&mut self, &mut self,
ctx: &mut impl VmRuntimeCtx,
reader: &mut BytecodeReader<'_>, reader: &mut BytecodeReader<'_>,
mc: &Mutation<'gc>, mc: &Mutation<'gc>,
) -> Step { ) -> Step {
@@ -37,7 +36,6 @@ impl<'gc> Vm<'gc> {
pub(crate) fn primop_deep_seq_force_top( pub(crate) fn primop_deep_seq_force_top(
&mut self, &mut self,
ctx: &mut impl VmRuntimeCtx,
reader: &mut BytecodeReader<'_>, reader: &mut BytecodeReader<'_>,
mc: &Mutation<'gc>, mc: &Mutation<'gc>,
) -> Step { ) -> Step {
@@ -86,7 +84,6 @@ impl<'gc> Vm<'gc> {
pub(crate) fn primop_deep_seq_push( pub(crate) fn primop_deep_seq_push(
&mut self, &mut self,
ctx: &mut impl VmRuntimeCtx,
reader: &mut BytecodeReader<'_>, reader: &mut BytecodeReader<'_>,
mc: &Mutation<'gc>, mc: &Mutation<'gc>,
) -> Step { ) -> Step {
+1 -2
View File
@@ -3,7 +3,7 @@ use gc_arena::Mutation;
use crate::bytecode_reader::BytecodeReader; use crate::bytecode_reader::BytecodeReader;
use crate::value::*; use crate::value::*;
use crate::{Step, Vm, VmRuntimeCtx}; use crate::{Step, Vm};
impl<'gc> Vm<'gc> { impl<'gc> Vm<'gc> {
pub(crate) fn primop_filter_force_list( pub(crate) fn primop_filter_force_list(
@@ -44,7 +44,6 @@ impl<'gc> Vm<'gc> {
pub(crate) fn primop_filter_check( pub(crate) fn primop_filter_check(
&mut self, &mut self,
ctx: &mut impl VmRuntimeCtx,
reader: &mut BytecodeReader<'_>, reader: &mut BytecodeReader<'_>,
mc: &Mutation<'gc>, mc: &Mutation<'gc>,
) -> Step { ) -> Step {
+4 -4
View File
@@ -32,14 +32,14 @@ impl<'gc> Vm<'gc> {
match phase { match phase {
Abort => self.primop_abort(ctx, reader, mc), Abort => self.primop_abort(ctx, reader, mc),
DeepSeq => self.primop_deep_seq_force_top(ctx, reader, mc), DeepSeq => self.primop_deep_seq_force_top(reader, mc),
DeepSeqPush => self.primop_deep_seq_push(ctx, reader, mc), DeepSeqPush => self.primop_deep_seq_push(reader, mc),
DeepSeqLoop => self.primop_deep_seq_loop(reader, mc), DeepSeqLoop => self.primop_deep_seq_loop(reader, mc),
Seq => self.primop_seq(ctx, reader, mc), Seq => self.primop_seq(reader, mc),
FilterForceList => self.primop_filter_force_list(reader, mc), FilterForceList => self.primop_filter_force_list(reader, mc),
FilterCallPred => self.primop_filter_call_pred(reader, mc), FilterCallPred => self.primop_filter_call_pred(reader, mc),
FilterCheck => self.primop_filter_check(ctx, reader, mc), FilterCheck => self.primop_filter_check(reader, mc),
ForceResultShallow => self.primop_force_result_shallow(ctx, reader, mc), ForceResultShallow => self.primop_force_result_shallow(ctx, reader, mc),
ForceResultShallowPush => self.primop_force_result_shallow_push(ctx, reader, mc), ForceResultShallowPush => self.primop_force_result_shallow_push(ctx, reader, mc),