Files
nix-js/fix-vm/src/instructions/misc.rs
T

92 lines
2.8 KiB
Rust

use fix_builtins::BuiltinId;
use fix_common::StringId;
use num_enum::TryFromPrimitive;
use crate::value::{NixString, StrictValue};
use crate::{BytecodeReader, PrimOp, Step, Value, VmRuntimeCtx};
impl<'gc> crate::Vm<'gc> {
#[inline(always)]
pub(crate) fn op_load_builtins(&mut self) -> Step {
self.push(self.builtins);
Step::Continue(())
}
#[inline(always)]
pub(crate) fn op_load_builtin(&mut self, reader: &mut BytecodeReader<'_>) -> Step {
let Ok(id) = BuiltinId::try_from_primitive(reader.read_u8())
.map_err(|err| panic!("unknown builtin id: {}", err.number));
self.push(Value::new_inline(PrimOp {
id,
arity: fix_builtins::BUILTINS[id as usize].1,
dispatch_ip: id.entry_phase().ip(),
}));
Step::Continue(())
}
#[inline(always)]
pub(crate) fn op_load_repl_binding(&mut self, reader: &mut BytecodeReader<'_>) -> Step {
let _name = reader.read_string_id();
todo!("LoadReplBinding");
}
#[inline(always)]
pub(crate) fn op_load_scoped_binding(&mut self, reader: &mut BytecodeReader<'_>) -> Step {
let _name = reader.read_string_id();
todo!("LoadScopedBinding");
}
#[inline(always)]
pub(crate) fn op_coerce_to_string(
&mut self,
reader: &mut BytecodeReader<'_>,
mc: &gc_arena::Mutation<'gc>,
) -> Step {
let val = self.force_and_retry::<StrictValue>(reader, mc)?;
if val.is::<StringId>() || val.is::<NixString>() {
self.push(val.relax());
} else {
todo!("coerce other types to string: {:?}", val.ty());
}
Step::Continue(())
}
#[inline(always)]
pub(crate) fn op_concat_strings(
&mut self,
ctx: &mut impl VmRuntimeCtx,
reader: &mut BytecodeReader<'_>,
_mc: &gc_arena::Mutation<'gc>,
) -> Step {
use crate::VmRuntimeCtxExt;
let count = reader.read_u16() as usize;
let _force_string = reader.read_u8() != 0;
let mut total_len = 0;
for i in 0..count {
let val = self.peek_forced(count - 1 - i);
let s = ctx.get_string(val).expect("coerced");
total_len += s.len();
}
let mut result = String::with_capacity(total_len);
for i in 0..count {
let val = self.peek_forced(count - 1 - i);
let s = ctx.get_string(val).expect("coerced");
result.push_str(s);
}
self.stack.truncate(self.stack.len() - count);
let sid = ctx.intern_string(result);
self.push(Value::new_inline(sid));
Step::Continue(())
}
#[inline(always)]
pub(crate) fn op_resolve_path(&mut self, _ctx: &mut impl VmRuntimeCtx) -> Step {
todo!("implement ResolvePath");
}
}