refactor(tvix/eval): add macros for generating Value casters
The casting methods of `Value` are pretty verbose, and actually incorrect before this commit as they did not account for inner thunk values. To address this, we first attempt to make them correct by introducing a standard macro to generate them and traverse the inner thunk(s) if necessary. This is likely to be a performance hit as it will now involve more cloning of values. We can do multiple things to alleviate this, but should do some measurements first. Change-Id: If315d6e2afe7b69db727df535bc6cbfb89a691aa Reviewed-on: https://cl.tvl.fyi/c/depot/+/6412 Reviewed-by: sterni <sternenseemann@systemli.org> Tested-by: BuildkiteCI
This commit is contained in:
parent
0d7ad5e6d1
commit
6b3c3c9826
3 changed files with 56 additions and 76 deletions
|
|
@ -259,7 +259,7 @@ impl VM {
|
|||
}
|
||||
|
||||
OpCode::OpAttrsSelect => {
|
||||
let key = fallible!(self, self.pop().to_string());
|
||||
let key = fallible!(self, self.pop().to_str());
|
||||
let attrs = fallible!(self, self.pop().to_attrs());
|
||||
|
||||
match attrs.select(key.as_str()) {
|
||||
|
|
@ -274,7 +274,7 @@ impl VM {
|
|||
}
|
||||
|
||||
OpCode::OpAttrsTrySelect => {
|
||||
let key = fallible!(self, self.pop().to_string());
|
||||
let key = fallible!(self, self.pop().to_str());
|
||||
let value = match self.pop() {
|
||||
Value::Attrs(attrs) => match attrs.select(key.as_str()) {
|
||||
Some(value) => value.clone(),
|
||||
|
|
@ -288,7 +288,7 @@ impl VM {
|
|||
}
|
||||
|
||||
OpCode::OpAttrsIsSet => {
|
||||
let key = fallible!(self, self.pop().to_string());
|
||||
let key = fallible!(self, self.pop().to_str());
|
||||
let result = match self.pop() {
|
||||
Value::Attrs(attrs) => attrs.contains(key.as_str()),
|
||||
|
||||
|
|
@ -379,13 +379,13 @@ impl VM {
|
|||
}
|
||||
|
||||
OpCode::OpResolveWith => {
|
||||
let ident = fallible!(self, self.pop().to_string());
|
||||
let ident = fallible!(self, self.pop().to_str());
|
||||
let value = self.resolve_with(ident.as_str())?;
|
||||
self.push(value)
|
||||
}
|
||||
|
||||
OpCode::OpResolveWithOrUpvalue(idx) => {
|
||||
let ident = fallible!(self, self.pop().to_string());
|
||||
let ident = fallible!(self, self.pop().to_str());
|
||||
match self.resolve_with(ident.as_str()) {
|
||||
// Variable found in local `with`-stack.
|
||||
Ok(value) => self.push(value),
|
||||
|
|
@ -529,7 +529,7 @@ impl VM {
|
|||
let mut path = Vec::with_capacity(count);
|
||||
|
||||
for _ in 0..count {
|
||||
path.push(fallible!(self, self.pop().to_string()));
|
||||
path.push(fallible!(self, self.pop().to_str()));
|
||||
}
|
||||
|
||||
self.push(Value::AttrPath(path));
|
||||
|
|
@ -553,7 +553,7 @@ impl VM {
|
|||
let mut out = String::new();
|
||||
|
||||
for _ in 0..count {
|
||||
out.push_str(fallible!(self, self.pop().to_string()).as_str());
|
||||
out.push_str(fallible!(self, self.pop().to_str()).as_str());
|
||||
}
|
||||
|
||||
self.push(Value::String(out.into()));
|
||||
|
|
@ -562,7 +562,7 @@ impl VM {
|
|||
|
||||
fn resolve_dynamic_upvalue(&mut self, ident_idx: ConstantIdx) -> EvalResult<Value> {
|
||||
let chunk = self.chunk();
|
||||
let ident = fallible!(self, chunk.constant(ident_idx).as_str()).to_string();
|
||||
let ident = fallible!(self, chunk.constant(ident_idx).to_str());
|
||||
|
||||
// Peek at the current instruction (note: IP has already
|
||||
// advanced!) to see if it is actually data indicating a
|
||||
|
|
@ -577,7 +577,7 @@ impl VM {
|
|||
_ => None,
|
||||
};
|
||||
|
||||
match self.resolve_with(&ident) {
|
||||
match self.resolve_with(ident.as_str()) {
|
||||
Ok(v) => Ok(v),
|
||||
|
||||
Err(Error {
|
||||
|
|
@ -595,7 +595,7 @@ impl VM {
|
|||
/// Resolve a dynamic identifier through the with-stack at runtime.
|
||||
fn resolve_with(&self, ident: &str) -> EvalResult<Value> {
|
||||
for idx in self.with_stack.iter().rev() {
|
||||
let with = fallible!(self, self.stack[*idx].as_attrs());
|
||||
let with = fallible!(self, self.stack[*idx].to_attrs());
|
||||
match with.select(ident) {
|
||||
None => continue,
|
||||
Some(val) => return Ok(val.clone()),
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue