71 lines
2.2 KiB
Rust
71 lines
2.2 KiB
Rust
use fix_builtins::PrimOpPhase;
|
|
use fix_error::Error;
|
|
use gc_arena::Mutation;
|
|
use num_enum::TryFromPrimitive;
|
|
|
|
use crate::bytecode_reader::BytecodeReader;
|
|
use crate::value::Value;
|
|
use crate::{CallFrame, Step, Vm, VmRuntimeCtx};
|
|
|
|
mod attrs;
|
|
mod control;
|
|
mod conv;
|
|
mod io;
|
|
mod list;
|
|
mod path;
|
|
mod regex;
|
|
mod version;
|
|
|
|
impl<'gc> Vm<'gc> {
|
|
#[allow(clippy::too_many_lines)]
|
|
pub(crate) fn op_dispatch_primop(
|
|
&mut self,
|
|
ctx: &mut impl VmRuntimeCtx,
|
|
reader: &mut BytecodeReader<'_>,
|
|
mc: &Mutation<'gc>,
|
|
) -> Step {
|
|
use PrimOpPhase::*;
|
|
let phase_disc = reader.read_u8();
|
|
let Ok(phase) = PrimOpPhase::try_from_primitive(phase_disc) else {
|
|
return self.finish_err(Error::eval_error("invalid primop phase"));
|
|
};
|
|
match phase {
|
|
Abort => self.primop_abort(ctx, reader, mc),
|
|
|
|
DeepSeq => self.primop_deep_seq_force_top(reader, mc),
|
|
DeepSeqPush => self.primop_deep_seq_push(reader, mc),
|
|
DeepSeqLoop => self.primop_deep_seq_loop(reader, mc),
|
|
Seq => self.primop_seq(reader, mc),
|
|
|
|
FilterForceList => self.primop_filter_force_list(reader, mc),
|
|
FilterCallPred => self.primop_filter_call_pred(reader, mc),
|
|
FilterCheck => self.primop_filter_check(reader, mc),
|
|
|
|
ForceResultShallow => self.primop_force_result_shallow(ctx, reader, mc),
|
|
ForceResultShallowPush => self.primop_force_result_shallow_push(ctx, reader, mc),
|
|
ForceResultShallowLoop => self.primop_force_result_shallow_loop(reader, mc),
|
|
ForceResultDeepFinish => self.primop_force_result_deep_finish(ctx, reader, mc),
|
|
|
|
CallPattern => self.primop_call_pattern(ctx, reader, mc),
|
|
|
|
phase => todo!("primop phase {phase:?}"),
|
|
}
|
|
}
|
|
|
|
fn return_from_primop(&mut self, val: Value<'gc>, reader: &mut BytecodeReader<'_>) -> Step {
|
|
self.push(val);
|
|
let Some(CallFrame {
|
|
pc: ret_pc,
|
|
thunk: _,
|
|
env,
|
|
}) = self.call_stack.pop()
|
|
else {
|
|
unreachable!()
|
|
};
|
|
reader.set_pc(ret_pc);
|
|
self.call_depth -= 1;
|
|
self.env = env;
|
|
Step::Continue(())
|
|
}
|
|
}
|