better force eval ergonomic
This commit is contained in:
@@ -3,7 +3,7 @@ use gc_arena::Gc;
|
||||
use smallvec::SmallVec;
|
||||
|
||||
use crate::{
|
||||
AttrKeyData, AttrSet, BytecodeReader, List, NixString, OperandData, Step, Value,
|
||||
AttrKeyData, AttrSet, BytecodeReader, List, NixString, OperandData, Step, StrictValue, Value,
|
||||
};
|
||||
|
||||
impl<'gc> crate::Vm<'gc> {
|
||||
@@ -57,18 +57,11 @@ impl<'gc> crate::Vm<'gc> {
|
||||
let _span_id = reader.read_u32();
|
||||
let key = reader.read_string_id();
|
||||
|
||||
self.try_force(0, reader, mc)?;
|
||||
|
||||
let attrs = self.peek(0).restrict().expect("forced");
|
||||
let Some(attrset) = attrs.as_gc::<AttrSet>() else {
|
||||
return self.finish_err(Error::eval_error(
|
||||
"value is not a set while a set was expected",
|
||||
));
|
||||
};
|
||||
let attrset = self.try_force::<Gc<AttrSet>>(reader, mc)?;
|
||||
|
||||
match attrset.lookup(key) {
|
||||
Some(v) => {
|
||||
self.replace(0, v);
|
||||
self.push(v);
|
||||
}
|
||||
None => loop {
|
||||
let byte = reader.bytecode()[reader.pc()];
|
||||
@@ -78,7 +71,6 @@ impl<'gc> crate::Vm<'gc> {
|
||||
reader.set_pc(reader.pc() + 1 + 4);
|
||||
} else if byte == fix_codegen::Op::JumpIfSelectSucceeded as u8 {
|
||||
reader.set_pc(reader.pc() + 1 + 4);
|
||||
let _ = self.pop();
|
||||
break;
|
||||
} else {
|
||||
let name = ctx.resolve_string(key);
|
||||
@@ -99,12 +91,8 @@ impl<'gc> crate::Vm<'gc> {
|
||||
) -> Step {
|
||||
let _span_id = reader.read_u32();
|
||||
|
||||
self.try_force(0, reader, mc)?;
|
||||
self.try_force(1, reader, mc)?;
|
||||
let (attrset, key_val) = self.try_force::<(Gc<AttrSet>, StrictValue)>(reader, mc)?;
|
||||
|
||||
let key_val = self.stack[self.stack.len() - 1]
|
||||
.restrict()
|
||||
.expect("dynamic key must be forced");
|
||||
let key_sid = if let Some(sid) = key_val.as_inline::<crate::StringId>() {
|
||||
sid
|
||||
} else if let Some(ns) = key_val.as_gc::<NixString>() {
|
||||
@@ -113,16 +101,8 @@ impl<'gc> crate::Vm<'gc> {
|
||||
return self.finish_err(Error::eval_error("dynamic select key must be a string"));
|
||||
};
|
||||
|
||||
let attrset_val = self.stack[self.stack.len() - 2].restrict().expect("forced");
|
||||
let Some(attrset) = attrset_val.as_gc::<AttrSet>() else {
|
||||
return self.finish_err(Error::eval_error(
|
||||
"value is not a set while a set was expected",
|
||||
));
|
||||
};
|
||||
|
||||
match attrset.lookup(key_sid) {
|
||||
Some(v) => {
|
||||
self.stack.truncate(self.stack.len() - 2);
|
||||
self.push(v);
|
||||
}
|
||||
None => {
|
||||
|
||||
Reference in New Issue
Block a user