diff --git a/fix-vm/src/lib.rs b/fix-vm/src/lib.rs index 36ebe40..4930ed1 100644 --- a/fix-vm/src/lib.rs +++ b/fix-vm/src/lib.rs @@ -112,27 +112,25 @@ impl VmContextExt for T { } } -#[allow(dead_code)] -pub struct Vm { - arena: Arena]>, - error_context: Vec, - ctx: C, - pc: usize, - force_mode: ForceMode, -} - #[derive(Collect)] #[collect(no_drop)] -struct GcRoot<'gc> { +pub struct Vm<'gc> { stack: Vec>, call_stack: Vec>, call_depth: usize, + #[collect(require_static)] + error_context: Vec, + + env: GcEnv<'gc>, with_env: Option>>, + + import_cache: HashMap>, + builtins: Value<'gc>, empty_list: Value<'gc>, empty_attrs: Value<'gc>, - import_cache: HashMap>, - env: GcEnv<'gc>, + + force_mode: ForceMode, } fn init_builtins<'gc>(mc: &Mutation<'gc>, ctx: &mut impl VmContext) -> Value<'gc> { @@ -179,7 +177,7 @@ fn init_builtins<'gc>(mc: &Mutation<'gc>, ctx: &mut impl VmContext) -> Value<'gc entries.push((name, val)); } - let self_ref_thunk: Gc<'gc, Thunk<'gc>> = Gc::new(mc, RefLock::new(ThunkState::Blackhole)); + let self_ref_thunk = Gc::new(mc, RefLock::new(ThunkState::Blackhole)); let sym = ctx.intern_string("builtins"); entries.push((sym, Value::new_gc(self_ref_thunk))); @@ -189,19 +187,25 @@ fn init_builtins<'gc>(mc: &Mutation<'gc>, ctx: &mut impl VmContext) -> Value<'gc Value::new_gc(builtins_set) } -impl<'gc> GcRoot<'gc> { - fn new(mc: &Mutation<'gc>, ctx: &mut impl VmContext) -> Self { +impl<'gc> Vm<'gc> { + fn new(force_mode: ForceMode, mc: &Mutation<'gc>, ctx: &mut impl VmContext) -> Self { let builtins = init_builtins(mc, ctx); - GcRoot { + Vm { stack: Vec::with_capacity(8192), call_stack: Vec::with_capacity(1024), call_depth: 0, + error_context: Vec::with_capacity(1024), + + env: Gc::new(mc, RefLock::new(Env::empty())), with_env: None, + + import_cache: HashMap::new(), + builtins, empty_list: Value::new_gc(Gc::new(mc, List::default())), empty_attrs: Value::new_gc(Gc::new(mc, AttrSet::default())), - import_cache: HashMap::new(), - env: Gc::new(mc, RefLock::new(Env::empty())), + + force_mode, } } @@ -277,7 +281,7 @@ enum OperandData { } impl OperandData { - fn resolve<'gc>(&self, mc: &Mutation<'gc>, root: &GcRoot<'gc>) -> Value<'gc> { + fn resolve<'gc>(&self, mc: &Mutation<'gc>, root: &Vm<'gc>) -> Value<'gc> { match *self { OperandData::Const(sv) => sv.into(), OperandData::Local { layer, idx } => { @@ -313,36 +317,30 @@ macro_rules! try_vm { ($self:ident; $expr:expr) => { match $expr { Ok(v) => v, - Err(e) => return GcRoot::handle_vm_error($self, e), + Err(e) => return Vm::handle_vm_error($self, e), } }; } -impl Vm { - pub fn new(mut ctx: C, ip: InstructionPtr, force_mode: ForceMode) -> Self { - Self { - arena: Arena::new(|mc| GcRoot::new(mc, &mut ctx)), - ctx, - force_mode, - pc: ip.0, - error_context: Vec::new(), - } - } +impl Vm<'_> { + pub fn run( + mut ctx: C, + ip: InstructionPtr, + force_mode: ForceMode, + ) -> Result { + let mut arena: Arena]> = + Arena::new(|mc| Vm::new(force_mode, mc, &mut ctx)); - pub fn run(mut self) -> Result { const COLLECTOR_GRANULARITY: f64 = 1024.0; - let mut pc = self.pc; + let mut pc = ip.0; loop { - match self - .arena - .mutate_root(|mc, root| root.execute_batch(&mut self.ctx, &mut pc, mc)) - { + match arena.mutate_root(|mc, root| root.execute_batch(&mut ctx, &mut pc, mc)) { Action::Continue => { - if self.arena.metrics().allocation_debt() > COLLECTOR_GRANULARITY { - if self.arena.collection_phase() == CollectionPhase::Sweeping { - self.arena.collect_debt(); - } else if let Some(marked) = self.arena.mark_debt() { + if arena.metrics().allocation_debt() > COLLECTOR_GRANULARITY { + if arena.collection_phase() == CollectionPhase::Sweeping { + arena.collect_debt(); + } else if let Some(marked) = arena.mark_debt() { marked.start_sweeping(); } } @@ -353,7 +351,7 @@ impl Vm { } } -impl<'gc> GcRoot<'gc> { +impl<'gc> Vm<'gc> { #[inline(always)] fn execute_batch( &mut self, diff --git a/fix/src/lib.rs b/fix/src/lib.rs index ce6bb2e..446bafa 100644 --- a/fix/src/lib.rs +++ b/fix/src/lib.rs @@ -87,8 +87,7 @@ impl Evaluator { ) -> Result { let root = self.downgrade(source, extra_scope)?; let ip = fix_codegen::compile_bytecode(root.as_ref(), self); - let vm = Vm::new(self, ip, force_mode); - vm.run() + Vm::run(self, ip, force_mode) } pub fn add_binding(