refactor: merge GcRoot & Vm

This commit is contained in:
2026-04-19 13:07:07 +08:00
parent df9664f5c4
commit 74866ec1d3
2 changed files with 40 additions and 43 deletions
+39 -41
View File
@@ -112,27 +112,25 @@ impl<T: VmContext> VmContextExt for T {
} }
} }
#[allow(dead_code)]
pub struct Vm<C: VmContext> {
arena: Arena<Rootable![GcRoot<'_>]>,
error_context: Vec<ErrorFrame>,
ctx: C,
pc: usize,
force_mode: ForceMode,
}
#[derive(Collect)] #[derive(Collect)]
#[collect(no_drop)] #[collect(no_drop)]
struct GcRoot<'gc> { pub struct Vm<'gc> {
stack: Vec<Value<'gc>>, stack: Vec<Value<'gc>>,
call_stack: Vec<CallFrame<'gc>>, call_stack: Vec<CallFrame<'gc>>,
call_depth: usize, call_depth: usize,
#[collect(require_static)]
error_context: Vec<ErrorFrame>,
env: GcEnv<'gc>,
with_env: Option<Gc<'gc, WithEnv<'gc>>>, with_env: Option<Gc<'gc, WithEnv<'gc>>>,
import_cache: HashMap<PathBuf, Value<'gc>>,
builtins: Value<'gc>, builtins: Value<'gc>,
empty_list: Value<'gc>, empty_list: Value<'gc>,
empty_attrs: Value<'gc>, empty_attrs: Value<'gc>,
import_cache: HashMap<PathBuf, Value<'gc>>,
env: GcEnv<'gc>, force_mode: ForceMode,
} }
fn init_builtins<'gc>(mc: &Mutation<'gc>, ctx: &mut impl VmContext) -> Value<'gc> { 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)); 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"); let sym = ctx.intern_string("builtins");
entries.push((sym, Value::new_gc(self_ref_thunk))); 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) Value::new_gc(builtins_set)
} }
impl<'gc> GcRoot<'gc> { impl<'gc> Vm<'gc> {
fn new(mc: &Mutation<'gc>, ctx: &mut impl VmContext) -> Self { fn new(force_mode: ForceMode, mc: &Mutation<'gc>, ctx: &mut impl VmContext) -> Self {
let builtins = init_builtins(mc, ctx); let builtins = init_builtins(mc, ctx);
GcRoot { Vm {
stack: Vec::with_capacity(8192), stack: Vec::with_capacity(8192),
call_stack: Vec::with_capacity(1024), call_stack: Vec::with_capacity(1024),
call_depth: 0, call_depth: 0,
error_context: Vec::with_capacity(1024),
env: Gc::new(mc, RefLock::new(Env::empty())),
with_env: None, with_env: None,
import_cache: HashMap::new(),
builtins, builtins,
empty_list: Value::new_gc(Gc::new(mc, List::default())), empty_list: Value::new_gc(Gc::new(mc, List::default())),
empty_attrs: Value::new_gc(Gc::new(mc, AttrSet::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 { 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 { match *self {
OperandData::Const(sv) => sv.into(), OperandData::Const(sv) => sv.into(),
OperandData::Local { layer, idx } => { OperandData::Local { layer, idx } => {
@@ -313,36 +317,30 @@ macro_rules! try_vm {
($self:ident; $expr:expr) => { ($self:ident; $expr:expr) => {
match $expr { match $expr {
Ok(v) => v, Ok(v) => v,
Err(e) => return GcRoot::handle_vm_error($self, e), Err(e) => return Vm::handle_vm_error($self, e),
} }
}; };
} }
impl<C: VmContext> Vm<C> { impl Vm<'_> {
pub fn new(mut ctx: C, ip: InstructionPtr, force_mode: ForceMode) -> Self { pub fn run<C: VmContext>(
Self { mut ctx: C,
arena: Arena::new(|mc| GcRoot::new(mc, &mut ctx)), ip: InstructionPtr,
ctx, force_mode: ForceMode,
force_mode, ) -> Result<fix_common::Value> {
pc: ip.0, let mut arena: Arena<Rootable![Vm<'_>]> =
error_context: Vec::new(), Arena::new(|mc| Vm::new(force_mode, mc, &mut ctx));
}
}
pub fn run(mut self) -> Result<fix_common::Value> {
const COLLECTOR_GRANULARITY: f64 = 1024.0; const COLLECTOR_GRANULARITY: f64 = 1024.0;
let mut pc = self.pc; let mut pc = ip.0;
loop { loop {
match self match arena.mutate_root(|mc, root| root.execute_batch(&mut ctx, &mut pc, mc)) {
.arena
.mutate_root(|mc, root| root.execute_batch(&mut self.ctx, &mut pc, mc))
{
Action::Continue => { Action::Continue => {
if self.arena.metrics().allocation_debt() > COLLECTOR_GRANULARITY { if arena.metrics().allocation_debt() > COLLECTOR_GRANULARITY {
if self.arena.collection_phase() == CollectionPhase::Sweeping { if arena.collection_phase() == CollectionPhase::Sweeping {
self.arena.collect_debt(); arena.collect_debt();
} else if let Some(marked) = self.arena.mark_debt() { } else if let Some(marked) = arena.mark_debt() {
marked.start_sweeping(); marked.start_sweeping();
} }
} }
@@ -353,7 +351,7 @@ impl<C: VmContext> Vm<C> {
} }
} }
impl<'gc> GcRoot<'gc> { impl<'gc> Vm<'gc> {
#[inline(always)] #[inline(always)]
fn execute_batch( fn execute_batch(
&mut self, &mut self,
+1 -2
View File
@@ -87,8 +87,7 @@ impl Evaluator {
) -> Result<fix_common::Value> { ) -> Result<fix_common::Value> {
let root = self.downgrade(source, extra_scope)?; let root = self.downgrade(source, extra_scope)?;
let ip = fix_codegen::compile_bytecode(root.as_ref(), self); let ip = fix_codegen::compile_bytecode(root.as_ref(), self);
let vm = Vm::new(self, ip, force_mode); Vm::run(self, ip, force_mode)
vm.run()
} }
pub fn add_binding( pub fn add_binding(