refactor: split VmContext
This commit is contained in:
@@ -3,7 +3,7 @@ use fix_common::StringId;
|
|||||||
use num_enum::TryFromPrimitive;
|
use num_enum::TryFromPrimitive;
|
||||||
use string_interner::Symbol as _;
|
use string_interner::Symbol as _;
|
||||||
|
|
||||||
use crate::OperandData;
|
use crate::{OperandData, VmRuntimeCtx};
|
||||||
|
|
||||||
pub(crate) struct BytecodeReader<'a> {
|
pub(crate) struct BytecodeReader<'a> {
|
||||||
bytecode: &'a [u8],
|
bytecode: &'a [u8],
|
||||||
@@ -94,7 +94,7 @@ impl<'a> BytecodeReader<'a> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub(crate) fn read_operand_data<C: crate::VmContext>(&mut self, ctx: &C) -> OperandData {
|
pub(crate) fn read_operand_data<C: VmRuntimeCtx>(&mut self, ctx: &C) -> OperandData {
|
||||||
let tag = self.read_u8();
|
let tag = self.read_u8();
|
||||||
let Ok(ty) = OperandType::try_from_primitive(tag)
|
let Ok(ty) = OperandType::try_from_primitive(tag)
|
||||||
.map_err(|err| panic!("unknown operand tag: {:#04x}", err.number));
|
.map_err(|err| panic!("unknown operand tag: {:#04x}", err.number));
|
||||||
@@ -117,10 +117,7 @@ impl<'a> BytecodeReader<'a> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub(crate) fn read_attr_key_data<C: crate::VmContext>(
|
pub(crate) fn read_attr_key_data<C: VmRuntimeCtx>(&mut self, ctx: &C) -> crate::AttrKeyData {
|
||||||
&mut self,
|
|
||||||
ctx: &C,
|
|
||||||
) -> crate::AttrKeyData {
|
|
||||||
use fix_codegen::AttrKeyType;
|
use fix_codegen::AttrKeyType;
|
||||||
let tag = self.read_u8();
|
let tag = self.read_u8();
|
||||||
let ty = AttrKeyType::try_from_primitive(tag)
|
let ty = AttrKeyType::try_from_primitive(tag)
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
use gc_arena::Mutation;
|
use gc_arena::Mutation;
|
||||||
|
|
||||||
use crate::{Break, BytecodeReader, Step, Vm, VmContext};
|
use crate::{Break, BytecodeReader, Step, Vm, VmRuntimeCtx};
|
||||||
|
|
||||||
pub(crate) enum TailResult {
|
pub(crate) enum TailResult {
|
||||||
YieldFuel(u32),
|
YieldFuel(u32),
|
||||||
@@ -19,9 +19,9 @@ pub(crate) type OpFn<'gc, C> = extern "rust-preserve-none" fn(
|
|||||||
u32,
|
u32,
|
||||||
) -> TailResult;
|
) -> TailResult;
|
||||||
|
|
||||||
pub(crate) struct DispatchTable<'gc, C: VmContext>(pub(crate) [OpFn<'gc, C>; 256]);
|
pub(crate) struct DispatchTable<'gc, C: VmRuntimeCtx>(pub(crate) [OpFn<'gc, C>; 256]);
|
||||||
|
|
||||||
extern "rust-preserve-none" fn op_illegal<'gc, C: VmContext>(
|
extern "rust-preserve-none" fn op_illegal<'gc, C: VmRuntimeCtx>(
|
||||||
_vm: &mut Vm<'gc>,
|
_vm: &mut Vm<'gc>,
|
||||||
_mc: &Mutation<'gc>,
|
_mc: &Mutation<'gc>,
|
||||||
_ctx: &mut C,
|
_ctx: &mut C,
|
||||||
@@ -50,7 +50,7 @@ macro_rules! tail_dispatch_after {
|
|||||||
|
|
||||||
macro_rules! tail_fn {
|
macro_rules! tail_fn {
|
||||||
($name:ident, ()) => {
|
($name:ident, ()) => {
|
||||||
extern "rust-preserve-none" fn $name<'gc, C: VmContext>(
|
extern "rust-preserve-none" fn $name<'gc, C: VmRuntimeCtx>(
|
||||||
vm: &mut Vm<'gc>,
|
vm: &mut Vm<'gc>,
|
||||||
mc: &Mutation<'gc>,
|
mc: &Mutation<'gc>,
|
||||||
ctx: &mut C,
|
ctx: &mut C,
|
||||||
@@ -64,7 +64,7 @@ macro_rules! tail_fn {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
($name:ident, (reader)) => {
|
($name:ident, (reader)) => {
|
||||||
extern "rust-preserve-none" fn $name<'gc, C: VmContext>(
|
extern "rust-preserve-none" fn $name<'gc, C: VmRuntimeCtx>(
|
||||||
vm: &mut Vm<'gc>,
|
vm: &mut Vm<'gc>,
|
||||||
mc: &Mutation<'gc>,
|
mc: &Mutation<'gc>,
|
||||||
ctx: &mut C,
|
ctx: &mut C,
|
||||||
@@ -79,7 +79,7 @@ macro_rules! tail_fn {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
($name:ident, (reader, mc)) => {
|
($name:ident, (reader, mc)) => {
|
||||||
extern "rust-preserve-none" fn $name<'gc, C: VmContext>(
|
extern "rust-preserve-none" fn $name<'gc, C: VmRuntimeCtx>(
|
||||||
vm: &mut Vm<'gc>,
|
vm: &mut Vm<'gc>,
|
||||||
mc: &Mutation<'gc>,
|
mc: &Mutation<'gc>,
|
||||||
ctx: &mut C,
|
ctx: &mut C,
|
||||||
@@ -94,7 +94,7 @@ macro_rules! tail_fn {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
($name:ident, (ctx, reader, mc)) => {
|
($name:ident, (ctx, reader, mc)) => {
|
||||||
extern "rust-preserve-none" fn $name<'gc, C: VmContext>(
|
extern "rust-preserve-none" fn $name<'gc, C: VmRuntimeCtx>(
|
||||||
vm: &mut Vm<'gc>,
|
vm: &mut Vm<'gc>,
|
||||||
mc: &Mutation<'gc>,
|
mc: &Mutation<'gc>,
|
||||||
ctx: &mut C,
|
ctx: &mut C,
|
||||||
@@ -109,7 +109,7 @@ macro_rules! tail_fn {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
($name:ident, (ctx)) => {
|
($name:ident, (ctx)) => {
|
||||||
extern "rust-preserve-none" fn $name<'gc, C: VmContext>(
|
extern "rust-preserve-none" fn $name<'gc, C: VmRuntimeCtx>(
|
||||||
vm: &mut Vm<'gc>,
|
vm: &mut Vm<'gc>,
|
||||||
mc: &Mutation<'gc>,
|
mc: &Mutation<'gc>,
|
||||||
ctx: &mut C,
|
ctx: &mut C,
|
||||||
@@ -198,7 +198,7 @@ tail_fn!(op_load_scoped_binding, (reader));
|
|||||||
|
|
||||||
macro_rules! table {
|
macro_rules! table {
|
||||||
($($variant:ident => $fn:ident),* $(,)?) => {
|
($($variant:ident => $fn:ident),* $(,)?) => {
|
||||||
impl<'gc, C: VmContext> DispatchTable<'gc, C> {
|
impl<'gc, C: VmRuntimeCtx> DispatchTable<'gc, C> {
|
||||||
pub(crate) const NEW: Self = {
|
pub(crate) const NEW: Self = {
|
||||||
let mut arr: [OpFn<'gc, C>; 256] = [op_illegal; 256];
|
let mut arr: [OpFn<'gc, C>; 256] = [op_illegal; 256];
|
||||||
$( arr[fix_codegen::Op::$variant as usize] = $fn; )*
|
$( arr[fix_codegen::Op::$variant as usize] = $fn; )*
|
||||||
@@ -291,7 +291,7 @@ table! {
|
|||||||
Illegal => op_illegal,
|
Illegal => op_illegal,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn run_tailcall<'gc, C: VmContext>(
|
pub(crate) fn run_tailcall<'gc, C: VmRuntimeCtx>(
|
||||||
vm: &mut Vm<'gc>,
|
vm: &mut Vm<'gc>,
|
||||||
mc: &Mutation<'gc>,
|
mc: &Mutation<'gc>,
|
||||||
ctx: &mut C,
|
ctx: &mut C,
|
||||||
|
|||||||
@@ -3,13 +3,13 @@ use std::cmp::Ordering;
|
|||||||
use gc_arena::{Gc, Mutation};
|
use gc_arena::{Gc, Mutation};
|
||||||
|
|
||||||
use crate::value::*;
|
use crate::value::*;
|
||||||
use crate::{BytecodeReader, NixNum, Step, VmContextExt, VmError};
|
use crate::{BytecodeReader, NixNum, Step, VmError, VmRuntimeCtx, VmRuntimeCtxExt as _};
|
||||||
|
|
||||||
impl<'gc> crate::Vm<'gc> {
|
impl<'gc> crate::Vm<'gc> {
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub(crate) fn op_add(
|
pub(crate) fn op_add(
|
||||||
&mut self,
|
&mut self,
|
||||||
ctx: &mut impl crate::VmContext,
|
ctx: &mut impl VmRuntimeCtx,
|
||||||
reader: &mut BytecodeReader<'_>,
|
reader: &mut BytecodeReader<'_>,
|
||||||
mc: &Mutation<'gc>,
|
mc: &Mutation<'gc>,
|
||||||
) -> Step {
|
) -> Step {
|
||||||
@@ -82,7 +82,7 @@ impl<'gc> crate::Vm<'gc> {
|
|||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub(crate) fn op_eq(
|
pub(crate) fn op_eq(
|
||||||
&mut self,
|
&mut self,
|
||||||
ctx: &mut impl crate::VmContext,
|
ctx: &mut impl VmRuntimeCtx,
|
||||||
reader: &mut BytecodeReader<'_>,
|
reader: &mut BytecodeReader<'_>,
|
||||||
mc: &Mutation<'gc>,
|
mc: &Mutation<'gc>,
|
||||||
) -> Step {
|
) -> Step {
|
||||||
@@ -98,7 +98,7 @@ impl<'gc> crate::Vm<'gc> {
|
|||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub(crate) fn op_neq(
|
pub(crate) fn op_neq(
|
||||||
&mut self,
|
&mut self,
|
||||||
ctx: &mut impl crate::VmContext,
|
ctx: &mut impl VmRuntimeCtx,
|
||||||
reader: &mut BytecodeReader<'_>,
|
reader: &mut BytecodeReader<'_>,
|
||||||
mc: &Mutation<'gc>,
|
mc: &Mutation<'gc>,
|
||||||
) -> Step {
|
) -> Step {
|
||||||
@@ -114,7 +114,7 @@ impl<'gc> crate::Vm<'gc> {
|
|||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub(crate) fn op_lt(
|
pub(crate) fn op_lt(
|
||||||
&mut self,
|
&mut self,
|
||||||
ctx: &mut impl crate::VmContext,
|
ctx: &mut impl VmRuntimeCtx,
|
||||||
reader: &mut BytecodeReader<'_>,
|
reader: &mut BytecodeReader<'_>,
|
||||||
mc: &Mutation<'gc>,
|
mc: &Mutation<'gc>,
|
||||||
) -> Step {
|
) -> Step {
|
||||||
@@ -124,7 +124,7 @@ impl<'gc> crate::Vm<'gc> {
|
|||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub(crate) fn op_gt(
|
pub(crate) fn op_gt(
|
||||||
&mut self,
|
&mut self,
|
||||||
ctx: &mut impl crate::VmContext,
|
ctx: &mut impl VmRuntimeCtx,
|
||||||
reader: &mut BytecodeReader<'_>,
|
reader: &mut BytecodeReader<'_>,
|
||||||
mc: &Mutation<'gc>,
|
mc: &Mutation<'gc>,
|
||||||
) -> Step {
|
) -> Step {
|
||||||
@@ -134,7 +134,7 @@ impl<'gc> crate::Vm<'gc> {
|
|||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub(crate) fn op_leq(
|
pub(crate) fn op_leq(
|
||||||
&mut self,
|
&mut self,
|
||||||
ctx: &mut impl crate::VmContext,
|
ctx: &mut impl VmRuntimeCtx,
|
||||||
reader: &mut BytecodeReader<'_>,
|
reader: &mut BytecodeReader<'_>,
|
||||||
mc: &Mutation<'gc>,
|
mc: &Mutation<'gc>,
|
||||||
) -> Step {
|
) -> Step {
|
||||||
@@ -144,7 +144,7 @@ impl<'gc> crate::Vm<'gc> {
|
|||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub(crate) fn op_geq(
|
pub(crate) fn op_geq(
|
||||||
&mut self,
|
&mut self,
|
||||||
ctx: &mut impl crate::VmContext,
|
ctx: &mut impl VmRuntimeCtx,
|
||||||
reader: &mut BytecodeReader<'_>,
|
reader: &mut BytecodeReader<'_>,
|
||||||
mc: &Mutation<'gc>,
|
mc: &Mutation<'gc>,
|
||||||
) -> Step {
|
) -> Step {
|
||||||
@@ -153,7 +153,7 @@ impl<'gc> crate::Vm<'gc> {
|
|||||||
|
|
||||||
fn compare_values(
|
fn compare_values(
|
||||||
&mut self,
|
&mut self,
|
||||||
ctx: &impl crate::VmContext,
|
ctx: &impl VmRuntimeCtx,
|
||||||
reader: &mut BytecodeReader<'_>,
|
reader: &mut BytecodeReader<'_>,
|
||||||
mc: &Mutation<'gc>,
|
mc: &Mutation<'gc>,
|
||||||
pred: fn(Ordering) -> bool,
|
pred: fn(Ordering) -> bool,
|
||||||
@@ -202,7 +202,7 @@ impl<'gc> crate::Vm<'gc> {
|
|||||||
|
|
||||||
pub(crate) fn values_equal(
|
pub(crate) fn values_equal(
|
||||||
&mut self,
|
&mut self,
|
||||||
ctx: &impl crate::VmContext,
|
ctx: &impl VmRuntimeCtx,
|
||||||
lhs: StrictValue<'gc>,
|
lhs: StrictValue<'gc>,
|
||||||
rhs: StrictValue<'gc>,
|
rhs: StrictValue<'gc>,
|
||||||
) -> crate::VmResult<bool> {
|
) -> crate::VmResult<bool> {
|
||||||
@@ -257,7 +257,7 @@ impl<'gc> crate::Vm<'gc> {
|
|||||||
|
|
||||||
fn compare_values_inner(
|
fn compare_values_inner(
|
||||||
&mut self,
|
&mut self,
|
||||||
ctx: &impl crate::VmContext,
|
ctx: &impl VmRuntimeCtx,
|
||||||
pred: fn(Ordering) -> bool,
|
pred: fn(Ordering) -> bool,
|
||||||
lhs: StrictValue<'gc>,
|
lhs: StrictValue<'gc>,
|
||||||
rhs: StrictValue<'gc>,
|
rhs: StrictValue<'gc>,
|
||||||
@@ -276,10 +276,7 @@ impl<'gc> crate::Vm<'gc> {
|
|||||||
self.push(Value::new_inline(pred(ord)));
|
self.push(Value::new_inline(pred(ord)));
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
if let (Some(a), Some(b)) = (
|
if let (Some(a), Some(b)) = (ctx.get_string(lhs), ctx.get_string(rhs)) {
|
||||||
VmContextExt::get_string(ctx, lhs),
|
|
||||||
VmContextExt::get_string(ctx, rhs),
|
|
||||||
) {
|
|
||||||
self.push(Value::new_inline(pred(a.cmp(b))));
|
self.push(Value::new_inline(pred(a.cmp(b))));
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
use fix_builtins::BuiltinId;
|
use fix_builtins::BuiltinId;
|
||||||
use num_enum::TryFromPrimitive;
|
use num_enum::TryFromPrimitive;
|
||||||
|
|
||||||
use crate::{BytecodeReader, PrimOp, Step, Value};
|
use crate::{BytecodeReader, PrimOp, Step, Value, VmRuntimeCtx};
|
||||||
|
|
||||||
impl<'gc> crate::Vm<'gc> {
|
impl<'gc> crate::Vm<'gc> {
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
@@ -42,7 +42,7 @@ impl<'gc> crate::Vm<'gc> {
|
|||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub(crate) fn op_concat_strings(
|
pub(crate) fn op_concat_strings(
|
||||||
&mut self,
|
&mut self,
|
||||||
ctx: &mut impl crate::VmContext,
|
ctx: &mut impl VmRuntimeCtx,
|
||||||
reader: &mut BytecodeReader<'_>,
|
reader: &mut BytecodeReader<'_>,
|
||||||
_mc: &gc_arena::Mutation<'gc>,
|
_mc: &gc_arena::Mutation<'gc>,
|
||||||
) -> Step {
|
) -> Step {
|
||||||
@@ -57,7 +57,7 @@ impl<'gc> crate::Vm<'gc> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub(crate) fn op_resolve_path(&mut self, _ctx: &mut impl crate::VmContext) -> Step {
|
pub(crate) fn op_resolve_path(&mut self, _ctx: &mut impl VmRuntimeCtx) -> Step {
|
||||||
todo!("implement ResolvePath");
|
todo!("implement ResolvePath");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,13 +2,15 @@ use fix_error::Error;
|
|||||||
use gc_arena::{Gc, Mutation, RefLock};
|
use gc_arena::{Gc, Mutation, RefLock};
|
||||||
|
|
||||||
use crate::value::*;
|
use crate::value::*;
|
||||||
use crate::{BytecodeReader, CallFrame, Closure, Env, Step, ThunkState, VmContextExt};
|
use crate::{
|
||||||
|
BytecodeReader, CallFrame, Closure, Env, Step, ThunkState, VmRuntimeCtx, VmRuntimeCtxExt,
|
||||||
|
};
|
||||||
|
|
||||||
impl<'gc> crate::Vm<'gc> {
|
impl<'gc> crate::Vm<'gc> {
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub(crate) fn op_call(
|
pub(crate) fn op_call(
|
||||||
&mut self,
|
&mut self,
|
||||||
ctx: &mut impl crate::VmContext,
|
ctx: &mut impl VmRuntimeCtx,
|
||||||
reader: &mut BytecodeReader<'_>,
|
reader: &mut BytecodeReader<'_>,
|
||||||
mc: &Mutation<'gc>,
|
mc: &Mutation<'gc>,
|
||||||
) -> Step {
|
) -> Step {
|
||||||
@@ -45,14 +47,14 @@ impl<'gc> crate::Vm<'gc> {
|
|||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub(crate) fn op_return(
|
pub(crate) fn op_return(
|
||||||
&mut self,
|
&mut self,
|
||||||
ctx: &mut impl crate::VmContext,
|
ctx: &mut impl VmRuntimeCtx,
|
||||||
reader: &mut BytecodeReader<'_>,
|
reader: &mut BytecodeReader<'_>,
|
||||||
mc: &Mutation<'gc>,
|
mc: &Mutation<'gc>,
|
||||||
) -> Step {
|
) -> Step {
|
||||||
self.handle_return(reader, ctx, mc)
|
self.handle_return(reader, ctx, mc)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn handle_return<C: crate::VmContext>(
|
pub(crate) fn handle_return<C: VmRuntimeCtx>(
|
||||||
&mut self,
|
&mut self,
|
||||||
reader: &mut BytecodeReader<'_>,
|
reader: &mut BytecodeReader<'_>,
|
||||||
ctx: &C,
|
ctx: &C,
|
||||||
|
|||||||
@@ -5,14 +5,15 @@ use smallvec::SmallVec;
|
|||||||
|
|
||||||
use crate::value::NixType;
|
use crate::value::NixType;
|
||||||
use crate::{
|
use crate::{
|
||||||
AttrKeyData, AttrSet, BytecodeReader, List, OperandData, Step, StrictValue, Value, VmContextExt,
|
AttrKeyData, AttrSet, BytecodeReader, List, OperandData, Step, StrictValue, Value,
|
||||||
|
VmRuntimeCtx, VmRuntimeCtxExt,
|
||||||
};
|
};
|
||||||
|
|
||||||
impl<'gc> crate::Vm<'gc> {
|
impl<'gc> crate::Vm<'gc> {
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub(crate) fn op_make_attrs(
|
pub(crate) fn op_make_attrs(
|
||||||
&mut self,
|
&mut self,
|
||||||
ctx: &mut impl crate::VmContext,
|
ctx: &mut impl VmRuntimeCtx,
|
||||||
reader: &mut BytecodeReader<'_>,
|
reader: &mut BytecodeReader<'_>,
|
||||||
mc: &gc_arena::Mutation<'gc>,
|
mc: &gc_arena::Mutation<'gc>,
|
||||||
) -> Step {
|
) -> Step {
|
||||||
@@ -52,7 +53,7 @@ impl<'gc> crate::Vm<'gc> {
|
|||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub(crate) fn op_select_static(
|
pub(crate) fn op_select_static(
|
||||||
&mut self,
|
&mut self,
|
||||||
ctx: &mut impl crate::VmContext,
|
ctx: &mut impl VmRuntimeCtx,
|
||||||
reader: &mut BytecodeReader<'_>,
|
reader: &mut BytecodeReader<'_>,
|
||||||
mc: &gc_arena::Mutation<'gc>,
|
mc: &gc_arena::Mutation<'gc>,
|
||||||
) -> Step {
|
) -> Step {
|
||||||
@@ -73,7 +74,7 @@ impl<'gc> crate::Vm<'gc> {
|
|||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub(crate) fn op_select_dynamic(
|
pub(crate) fn op_select_dynamic(
|
||||||
&mut self,
|
&mut self,
|
||||||
ctx: &mut impl crate::VmContext,
|
ctx: &mut impl VmRuntimeCtx,
|
||||||
reader: &mut BytecodeReader<'_>,
|
reader: &mut BytecodeReader<'_>,
|
||||||
mc: &gc_arena::Mutation<'gc>,
|
mc: &gc_arena::Mutation<'gc>,
|
||||||
) -> Step {
|
) -> Step {
|
||||||
@@ -102,7 +103,7 @@ impl<'gc> crate::Vm<'gc> {
|
|||||||
fn select_skip(
|
fn select_skip(
|
||||||
&mut self,
|
&mut self,
|
||||||
key: StringId,
|
key: StringId,
|
||||||
ctx: &mut impl crate::VmContext,
|
ctx: &mut impl VmRuntimeCtx,
|
||||||
reader: &mut BytecodeReader<'_>,
|
reader: &mut BytecodeReader<'_>,
|
||||||
) -> Step {
|
) -> Step {
|
||||||
use fix_codegen::Op::*;
|
use fix_codegen::Op::*;
|
||||||
@@ -168,7 +169,7 @@ impl<'gc> crate::Vm<'gc> {
|
|||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub(crate) fn op_has_attr_path_static(
|
pub(crate) fn op_has_attr_path_static(
|
||||||
&mut self,
|
&mut self,
|
||||||
_ctx: &mut impl crate::VmContext,
|
_ctx: &mut impl VmRuntimeCtx,
|
||||||
reader: &mut BytecodeReader<'_>,
|
reader: &mut BytecodeReader<'_>,
|
||||||
mc: &gc_arena::Mutation<'gc>,
|
mc: &gc_arena::Mutation<'gc>,
|
||||||
) -> Step {
|
) -> Step {
|
||||||
@@ -192,7 +193,7 @@ impl<'gc> crate::Vm<'gc> {
|
|||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub(crate) fn op_has_attr_path_dynamic(
|
pub(crate) fn op_has_attr_path_dynamic(
|
||||||
&mut self,
|
&mut self,
|
||||||
ctx: &mut impl crate::VmContext,
|
ctx: &mut impl VmRuntimeCtx,
|
||||||
reader: &mut BytecodeReader<'_>,
|
reader: &mut BytecodeReader<'_>,
|
||||||
mc: &gc_arena::Mutation<'gc>,
|
mc: &gc_arena::Mutation<'gc>,
|
||||||
) -> Step {
|
) -> Step {
|
||||||
@@ -255,7 +256,7 @@ impl<'gc> crate::Vm<'gc> {
|
|||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub(crate) fn op_has_attr_dynamic(
|
pub(crate) fn op_has_attr_dynamic(
|
||||||
&mut self,
|
&mut self,
|
||||||
ctx: &mut impl crate::VmContext,
|
ctx: &mut impl VmRuntimeCtx,
|
||||||
reader: &mut BytecodeReader<'_>,
|
reader: &mut BytecodeReader<'_>,
|
||||||
mc: &gc_arena::Mutation<'gc>,
|
mc: &gc_arena::Mutation<'gc>,
|
||||||
) -> Step {
|
) -> Step {
|
||||||
@@ -288,7 +289,7 @@ impl<'gc> crate::Vm<'gc> {
|
|||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub(crate) fn op_make_list(
|
pub(crate) fn op_make_list(
|
||||||
&mut self,
|
&mut self,
|
||||||
ctx: &mut impl crate::VmContext,
|
ctx: &mut impl VmRuntimeCtx,
|
||||||
reader: &mut BytecodeReader<'_>,
|
reader: &mut BytecodeReader<'_>,
|
||||||
mc: &gc_arena::Mutation<'gc>,
|
mc: &gc_arena::Mutation<'gc>,
|
||||||
) -> Step {
|
) -> Step {
|
||||||
|
|||||||
@@ -3,13 +3,13 @@ use fix_error::Error;
|
|||||||
use gc_arena::Gc;
|
use gc_arena::Gc;
|
||||||
|
|
||||||
use crate::value::*;
|
use crate::value::*;
|
||||||
use crate::{BytecodeReader, CallFrame, Step, WithEnv};
|
use crate::{BytecodeReader, CallFrame, Step, VmRuntimeCtx, WithEnv};
|
||||||
|
|
||||||
impl<'gc> crate::Vm<'gc> {
|
impl<'gc> crate::Vm<'gc> {
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub(crate) fn op_push_with(
|
pub(crate) fn op_push_with(
|
||||||
&mut self,
|
&mut self,
|
||||||
ctx: &mut impl crate::VmContext,
|
ctx: &mut impl VmRuntimeCtx,
|
||||||
reader: &mut BytecodeReader<'_>,
|
reader: &mut BytecodeReader<'_>,
|
||||||
mc: &gc_arena::Mutation<'gc>,
|
mc: &gc_arena::Mutation<'gc>,
|
||||||
) -> Step {
|
) -> Step {
|
||||||
@@ -49,7 +49,7 @@ impl<'gc> crate::Vm<'gc> {
|
|||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub(crate) fn op_lookup_with(
|
pub(crate) fn op_lookup_with(
|
||||||
&mut self,
|
&mut self,
|
||||||
ctx: &mut impl crate::VmContext,
|
ctx: &mut impl VmRuntimeCtx,
|
||||||
reader: &mut BytecodeReader<'_>,
|
reader: &mut BytecodeReader<'_>,
|
||||||
mc: &gc_arena::Mutation<'gc>,
|
mc: &gc_arena::Mutation<'gc>,
|
||||||
) -> Step {
|
) -> Step {
|
||||||
|
|||||||
+27
-16
@@ -64,15 +64,26 @@ pub enum ForceMode {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub trait VmContext {
|
pub trait VmContext {
|
||||||
fn intern_string(&mut self, s: impl AsRef<str>) -> StringId;
|
fn split(&mut self) -> (&mut impl VmCode, &mut impl VmRuntimeCtx);
|
||||||
fn resolve_string(&self, id: StringId) -> &str;
|
|
||||||
fn bytecode(&self) -> &[u8];
|
|
||||||
fn get_const(&self, id: u32) -> StaticValue;
|
|
||||||
|
|
||||||
fn compile(&mut self, source: Source);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) trait VmContextExt: VmContext {
|
pub trait VmRuntimeCtx {
|
||||||
|
fn intern_string(&mut self, s: impl AsRef<str>) -> StringId;
|
||||||
|
fn resolve_string(&self, id: StringId) -> &str;
|
||||||
|
fn get_const(&self, id: u32) -> StaticValue;
|
||||||
|
fn add_const(&mut self, val: StaticValue) -> u32;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub trait VmCode {
|
||||||
|
fn bytecode(&self) -> &[u8];
|
||||||
|
fn compile(
|
||||||
|
&mut self,
|
||||||
|
source: Source,
|
||||||
|
ctx: &mut impl VmRuntimeCtx,
|
||||||
|
) -> fix_error::Result<InstructionPtr>;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) trait VmRuntimeCtxExt: VmRuntimeCtx {
|
||||||
fn get_string<'a, 'gc: 'a>(&'a self, val: StrictValue<'gc>) -> Option<&'a str>;
|
fn get_string<'a, 'gc: 'a>(&'a self, val: StrictValue<'gc>) -> Option<&'a str>;
|
||||||
fn get_string_id<'a, 'gc: 'a>(
|
fn get_string_id<'a, 'gc: 'a>(
|
||||||
&'a mut self,
|
&'a mut self,
|
||||||
@@ -81,7 +92,7 @@ pub(crate) trait VmContextExt: VmContext {
|
|||||||
fn convert_value(&self, val: Value) -> fix_common::Value;
|
fn convert_value(&self, val: Value) -> fix_common::Value;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: VmContext> VmContextExt for T {
|
impl<T: VmRuntimeCtx> VmRuntimeCtxExt for T {
|
||||||
fn get_string<'a, 'gc: 'a>(&'a self, val: StrictValue<'gc>) -> Option<&'a str> {
|
fn get_string<'a, 'gc: 'a>(&'a self, val: StrictValue<'gc>) -> Option<&'a str> {
|
||||||
if let Some(sid) = val.as_inline::<StringId>() {
|
if let Some(sid) = val.as_inline::<StringId>() {
|
||||||
Some(self.resolve_string(sid))
|
Some(self.resolve_string(sid))
|
||||||
@@ -213,7 +224,7 @@ pub(crate) enum AttrKeyData {
|
|||||||
Dynamic(OperandData),
|
Dynamic(OperandData),
|
||||||
}
|
}
|
||||||
|
|
||||||
fn init_builtins<'gc>(mc: &Mutation<'gc>, ctx: &mut impl VmContext) -> Value<'gc> {
|
fn init_builtins<'gc>(mc: &Mutation<'gc>, ctx: &mut impl VmRuntimeCtx) -> Value<'gc> {
|
||||||
let mut entries = SmallVec::with_capacity(BUILTINS.len());
|
let mut entries = SmallVec::with_capacity(BUILTINS.len());
|
||||||
|
|
||||||
for (idx, &(name, arity)) in BUILTINS.iter().enumerate() {
|
for (idx, &(name, arity)) in BUILTINS.iter().enumerate() {
|
||||||
@@ -268,7 +279,7 @@ fn init_builtins<'gc>(mc: &Mutation<'gc>, ctx: &mut impl VmContext) -> Value<'gc
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl<'gc> Vm<'gc> {
|
impl<'gc> Vm<'gc> {
|
||||||
fn new(force_mode: ForceMode, mc: &Mutation<'gc>, ctx: &mut impl VmContext) -> Self {
|
fn new(force_mode: ForceMode, mc: &Mutation<'gc>, ctx: &mut impl VmRuntimeCtx) -> Self {
|
||||||
let builtins = init_builtins(mc, ctx);
|
let builtins = init_builtins(mc, ctx);
|
||||||
Vm {
|
Vm {
|
||||||
stack: Vec::with_capacity(8192),
|
stack: Vec::with_capacity(8192),
|
||||||
@@ -448,15 +459,15 @@ impl Vm<'_> {
|
|||||||
ip: InstructionPtr,
|
ip: InstructionPtr,
|
||||||
force_mode: ForceMode,
|
force_mode: ForceMode,
|
||||||
) -> Result<fix_common::Value> {
|
) -> Result<fix_common::Value> {
|
||||||
let mut arena: Arena<Rootable![Vm<'_>]> =
|
let (code, runtime) = ctx.split();
|
||||||
Arena::new(|mc| Vm::new(force_mode, mc, ctx));
|
let mut arena: Arena<Rootable![Vm<'_>]> = Arena::new(|mc| Vm::new(force_mode, mc, runtime));
|
||||||
|
|
||||||
const COLLECTOR_GRANULARITY: f64 = 1024.0;
|
const COLLECTOR_GRANULARITY: f64 = 1024.0;
|
||||||
|
|
||||||
let mut pc = ip.0;
|
let mut pc = ip.0;
|
||||||
let bytecode: Vec<u8> = ctx.bytecode().to_vec();
|
|
||||||
loop {
|
loop {
|
||||||
match arena.mutate_root(|mc, root| root.dispatch_batch(&bytecode, ctx, pc, mc)) {
|
let bytecode = code.bytecode();
|
||||||
|
match arena.mutate_root(|mc, root| root.dispatch_batch(bytecode, runtime, pc, mc)) {
|
||||||
Action::Continue { pc: new_pc } => {
|
Action::Continue { pc: new_pc } => {
|
||||||
pc = new_pc;
|
pc = new_pc;
|
||||||
if arena.metrics().allocation_debt() > COLLECTOR_GRANULARITY {
|
if arena.metrics().allocation_debt() > COLLECTOR_GRANULARITY {
|
||||||
@@ -477,7 +488,7 @@ impl<'gc> Vm<'gc> {
|
|||||||
const DEFAULT_FUEL_AMOUNT: u32 = 1024;
|
const DEFAULT_FUEL_AMOUNT: u32 = 1024;
|
||||||
|
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn dispatch_batch<C: VmContext>(
|
fn dispatch_batch<C: VmRuntimeCtx>(
|
||||||
&mut self,
|
&mut self,
|
||||||
bytecode: &[u8],
|
bytecode: &[u8],
|
||||||
ctx: &mut C,
|
ctx: &mut C,
|
||||||
@@ -507,7 +518,7 @@ impl<'gc> Vm<'gc> {
|
|||||||
fn execute_batch(
|
fn execute_batch(
|
||||||
&mut self,
|
&mut self,
|
||||||
bytecode: &[u8],
|
bytecode: &[u8],
|
||||||
ctx: &mut impl VmContext,
|
ctx: &mut impl VmRuntimeCtx,
|
||||||
pc: usize,
|
pc: usize,
|
||||||
mc: &Mutation<'gc>,
|
mc: &Mutation<'gc>,
|
||||||
) -> Action {
|
) -> Action {
|
||||||
|
|||||||
+162
-142
@@ -8,33 +8,33 @@ use fix_common::{StringId, Symbol};
|
|||||||
use fix_error::{Error, Result, Source};
|
use fix_error::{Error, Result, Source};
|
||||||
use fix_ir::downgrade::{Downgrade as _, DowngradeContext};
|
use fix_ir::downgrade::{Downgrade as _, DowngradeContext};
|
||||||
use fix_ir::{Ir, IrRef, MaybeThunk, RawIrRef, ThunkId};
|
use fix_ir::{Ir, IrRef, MaybeThunk, RawIrRef, ThunkId};
|
||||||
use fix_vm::{ForceMode, StaticValue, Vm, VmContext};
|
use fix_vm::{ForceMode, StaticValue, Vm, VmCode, VmContext, VmRuntimeCtx};
|
||||||
use ghost_cell::{GhostCell, GhostToken};
|
use ghost_cell::{GhostCell, GhostToken};
|
||||||
use hashbrown::{HashMap, HashSet};
|
use hashbrown::{HashMap, HashSet};
|
||||||
use string_interner::{DefaultStringInterner, Symbol as _};
|
use string_interner::{DefaultStringInterner, Symbol as _};
|
||||||
|
|
||||||
// mod fetcher;
|
|
||||||
// mod nar;
|
|
||||||
// mod nix_utils;
|
|
||||||
// mod store;
|
|
||||||
// mod string_context;
|
|
||||||
mod derivation;
|
mod derivation;
|
||||||
pub mod logging;
|
pub mod logging;
|
||||||
|
|
||||||
#[global_allocator]
|
#[global_allocator]
|
||||||
static GLOBAL: mimalloc::MiMalloc = mimalloc::MiMalloc;
|
static GLOBAL: mimalloc::MiMalloc = mimalloc::MiMalloc;
|
||||||
|
|
||||||
|
pub struct RuntimeState {
|
||||||
|
pub strings: DefaultStringInterner,
|
||||||
|
pub constants: Constants,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct CodeState {
|
||||||
|
pub bytecode: Vec<u8>,
|
||||||
|
pub sources: Vec<Source>,
|
||||||
|
pub spans: Vec<(usize, rnix::TextRange)>,
|
||||||
|
pub thunk_count: usize,
|
||||||
|
pub global_env: HashMap<StringId, Ir<'static, RawIrRef<'static>>>,
|
||||||
|
}
|
||||||
|
|
||||||
pub struct Evaluator {
|
pub struct Evaluator {
|
||||||
bytecode: Vec<u8>,
|
pub runtime: RuntimeState,
|
||||||
constants: Constants,
|
pub code: CodeState,
|
||||||
strings: DefaultStringInterner,
|
|
||||||
|
|
||||||
sources: Vec<Source>,
|
|
||||||
spans: Vec<(usize, rnix::TextRange)>,
|
|
||||||
// FIXME: remove?
|
|
||||||
thunk_count: usize,
|
|
||||||
|
|
||||||
global_env: HashMap<StringId, Ir<'static, RawIrRef<'static>>>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for Evaluator {
|
impl Default for Evaluator {
|
||||||
@@ -48,14 +48,17 @@ impl Evaluator {
|
|||||||
let mut strings = DefaultStringInterner::new();
|
let mut strings = DefaultStringInterner::new();
|
||||||
let global_env = fix_ir::new_global_env(&mut strings);
|
let global_env = fix_ir::new_global_env(&mut strings);
|
||||||
Self {
|
Self {
|
||||||
|
runtime: RuntimeState {
|
||||||
|
strings,
|
||||||
|
constants: Constants::default(),
|
||||||
|
},
|
||||||
|
code: CodeState {
|
||||||
sources: Vec::new(),
|
sources: Vec::new(),
|
||||||
spans: Vec::new(),
|
spans: Vec::new(),
|
||||||
strings,
|
|
||||||
thunk_count: 0,
|
thunk_count: 0,
|
||||||
bytecode: Vec::new(),
|
bytecode: Vec::new(),
|
||||||
constants: Constants::default(),
|
|
||||||
|
|
||||||
global_env,
|
global_env,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -85,8 +88,13 @@ impl Evaluator {
|
|||||||
extra_scope: Option<Scope<'ctx>>,
|
extra_scope: Option<Scope<'ctx>>,
|
||||||
force_mode: ForceMode,
|
force_mode: ForceMode,
|
||||||
) -> Result<fix_common::Value> {
|
) -> Result<fix_common::Value> {
|
||||||
let root = self.downgrade(source, extra_scope)?;
|
let ip = {
|
||||||
let ip = fix_codegen::compile_bytecode(root.as_ref(), self);
|
let mut compiler = CompilerCtx {
|
||||||
|
code: &mut self.code,
|
||||||
|
runtime: &mut self.runtime,
|
||||||
|
};
|
||||||
|
compiler.compile_bytecode(source, extra_scope)?
|
||||||
|
};
|
||||||
Vm::run(self, ip, force_mode)
|
Vm::run(self, ip, force_mode)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -100,55 +108,81 @@ impl Evaluator {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn compile_bytecode(&mut self, source: Source) -> Result<InstructionPtr> {
|
pub fn compile_bytecode(&mut self, source: Source) -> Result<InstructionPtr> {
|
||||||
let root = self.downgrade(source, None)?;
|
let mut compiler = CompilerCtx {
|
||||||
let ip = fix_codegen::compile_bytecode(root.as_ref(), self);
|
code: &mut self.code,
|
||||||
Ok(ip)
|
runtime: &mut self.runtime,
|
||||||
|
};
|
||||||
|
compiler.compile_bytecode(source, None)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn disassemble_colored(&self, ip: InstructionPtr) -> String {
|
pub fn disassemble_colored(&self, ip: InstructionPtr) -> String {
|
||||||
Disassembler::new(ip, self).disassemble_colored()
|
Disassembler::new(ip, self).disassemble_colored()
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn downgrade_ctx<'a, 'bump, 'id>(
|
impl VmRuntimeCtx for RuntimeState {
|
||||||
&'a mut self,
|
fn intern_string(&mut self, s: impl AsRef<str>) -> StringId {
|
||||||
bump: &'bump Bump,
|
StringId(self.strings.get_or_intern(s))
|
||||||
token: GhostToken<'id>,
|
|
||||||
extra_scope: Option<Scope<'a>>,
|
|
||||||
) -> DowngradeCtx<'a, 'id, 'bump> {
|
|
||||||
let Self {
|
|
||||||
global_env,
|
|
||||||
sources,
|
|
||||||
thunk_count,
|
|
||||||
strings,
|
|
||||||
..
|
|
||||||
} = self;
|
|
||||||
DowngradeCtx {
|
|
||||||
bump,
|
|
||||||
token,
|
|
||||||
strings,
|
|
||||||
source: sources.last().expect("no current source").clone(),
|
|
||||||
scopes: [Scope::Global(global_env)]
|
|
||||||
.into_iter()
|
|
||||||
.chain(extra_scope)
|
|
||||||
.collect(),
|
|
||||||
with_scope_count: 0,
|
|
||||||
arg_count: 0,
|
|
||||||
thunk_count,
|
|
||||||
thunk_scopes: vec![ThunkScope::new_in(bump)],
|
|
||||||
}
|
}
|
||||||
|
fn resolve_string(&self, id: StringId) -> &str {
|
||||||
|
#[allow(clippy::unwrap_used)]
|
||||||
|
self.strings.resolve(id.0).unwrap()
|
||||||
}
|
}
|
||||||
|
fn get_const(&self, id: u32) -> StaticValue {
|
||||||
|
#[allow(clippy::unwrap_used)]
|
||||||
|
self.constants.get(id).unwrap()
|
||||||
|
}
|
||||||
|
fn add_const(&mut self, val: StaticValue) -> u32 {
|
||||||
|
self.constants.insert(val)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn downgrade<'a>(
|
impl VmCode for CodeState {
|
||||||
&'a mut self,
|
fn bytecode(&self) -> &[u8] {
|
||||||
|
&self.bytecode
|
||||||
|
}
|
||||||
|
fn compile(
|
||||||
|
&mut self,
|
||||||
source: Source,
|
source: Source,
|
||||||
extra_scope: Option<Scope<'a>>,
|
runtime: &mut impl VmRuntimeCtx,
|
||||||
) -> Result<OwnedIr> {
|
) -> Result<InstructionPtr> {
|
||||||
|
let mut compiler = CompilerCtx {
|
||||||
|
code: self,
|
||||||
|
runtime,
|
||||||
|
};
|
||||||
|
compiler.compile_bytecode(source, None)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl VmContext for Evaluator {
|
||||||
|
fn split(&mut self) -> (&mut impl VmCode, &mut impl VmRuntimeCtx) {
|
||||||
|
(&mut self.code, &mut self.runtime)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct CompilerCtx<'a, R: VmRuntimeCtx> {
|
||||||
|
code: &'a mut CodeState,
|
||||||
|
runtime: &'a mut R,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a, R: VmRuntimeCtx> CompilerCtx<'a, R> {
|
||||||
|
fn compile_bytecode(
|
||||||
|
&mut self,
|
||||||
|
source: Source,
|
||||||
|
extra_scope: Option<Scope>,
|
||||||
|
) -> Result<InstructionPtr> {
|
||||||
|
let root = self.downgrade(source, extra_scope)?;
|
||||||
|
let ip = fix_codegen::compile_bytecode(root.as_ref(), self);
|
||||||
|
Ok(ip)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn downgrade(&mut self, source: Source, extra_scope: Option<Scope>) -> Result<OwnedIr> {
|
||||||
tracing::debug!("Parsing Nix expression");
|
tracing::debug!("Parsing Nix expression");
|
||||||
|
|
||||||
self.sources.push(source.clone());
|
self.code.sources.push(source.clone());
|
||||||
|
|
||||||
let root = rnix::Root::parse(&source.src);
|
let root = rnix::Root::parse(&source.src);
|
||||||
handle_parse_error(root.errors(), source).map_or(Ok(()), Err)?;
|
handle_parse_error(root.errors(), source.clone()).map_or(Ok(()), Err)?;
|
||||||
|
|
||||||
tracing::debug!("Downgrading Nix expression");
|
tracing::debug!("Downgrading Nix expression");
|
||||||
let expr = root
|
let expr = root
|
||||||
@@ -157,38 +191,63 @@ impl Evaluator {
|
|||||||
.ok_or_else(|| Error::parse_error("unexpected EOF".into()))?;
|
.ok_or_else(|| Error::parse_error("unexpected EOF".into()))?;
|
||||||
let bump = Bump::new();
|
let bump = Bump::new();
|
||||||
GhostToken::new(|token| {
|
GhostToken::new(|token| {
|
||||||
let ir = self
|
let downgrade_ctx = DowngradeCtx::new(
|
||||||
.downgrade_ctx(&bump, token, extra_scope)
|
&bump,
|
||||||
.downgrade_toplevel(expr)?;
|
token,
|
||||||
|
self.runtime,
|
||||||
|
&self.code.global_env,
|
||||||
|
extra_scope,
|
||||||
|
&mut self.code.thunk_count,
|
||||||
|
source,
|
||||||
|
);
|
||||||
|
let ir = downgrade_ctx.downgrade_toplevel(expr)?;
|
||||||
let ir = unsafe { std::mem::transmute::<RawIrRef<'_>, RawIrRef<'static>>(ir) };
|
let ir = unsafe { std::mem::transmute::<RawIrRef<'_>, RawIrRef<'static>>(ir) };
|
||||||
Ok(OwnedIr { _bump: bump, ir })
|
Ok(OwnedIr { _bump: bump, ir })
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl VmContext for Evaluator {
|
impl<'a, R: VmRuntimeCtx> BytecodeContext for CompilerCtx<'a, R> {
|
||||||
fn intern_string(&mut self, s: impl AsRef<str>) -> StringId {
|
fn intern_string(&mut self, s: &str) -> StringId {
|
||||||
StringId(self.strings.get_or_intern(s))
|
self.runtime.intern_string(s)
|
||||||
}
|
|
||||||
fn resolve_string(&self, id: StringId) -> &str {
|
|
||||||
#[allow(clippy::unwrap_used)]
|
|
||||||
self.strings.resolve(id.0).unwrap()
|
|
||||||
}
|
|
||||||
fn bytecode(&self) -> &[u8] {
|
|
||||||
&self.bytecode
|
|
||||||
}
|
|
||||||
fn get_const(&self, id: u32) -> StaticValue {
|
|
||||||
#[allow(clippy::unwrap_used)]
|
|
||||||
self.constants.get(id).unwrap()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn compile(&mut self, _source: Source) {
|
fn register_span(&mut self, range: rnix::TextRange) -> u32 {
|
||||||
todo!();
|
let id = self.code.spans.len();
|
||||||
|
let source_id = self
|
||||||
|
.code
|
||||||
|
.sources
|
||||||
|
.len()
|
||||||
|
.checked_sub(1)
|
||||||
|
.expect("current_source not set");
|
||||||
|
self.code.spans.push((source_id, range));
|
||||||
|
id as u32
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_code(&self) -> &[u8] {
|
||||||
|
&self.code.bytecode
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_code_mut(&mut self) -> &mut Vec<u8> {
|
||||||
|
&mut self.code.bytecode
|
||||||
|
}
|
||||||
|
|
||||||
|
fn add_constant(&mut self, val: fix_codegen::Const) -> u32 {
|
||||||
|
use fix_codegen::Const::*;
|
||||||
|
let val = match val {
|
||||||
|
Smi(x) => StaticValue::new_inline(x),
|
||||||
|
Float(x) => StaticValue::new_float(x),
|
||||||
|
Bool(x) => StaticValue::new_inline(x),
|
||||||
|
String(x) => StaticValue::new_inline(x),
|
||||||
|
PrimOp { id, arity } => StaticValue::new_primop(id, arity),
|
||||||
|
Null => StaticValue::default(),
|
||||||
|
};
|
||||||
|
self.runtime.add_const(val)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
struct Constants {
|
pub struct Constants {
|
||||||
data: Vec<StaticValue>,
|
data: Vec<StaticValue>,
|
||||||
dedup: HashMap<u64, u32>,
|
dedup: HashMap<u64, u32>,
|
||||||
}
|
}
|
||||||
@@ -236,10 +295,10 @@ fn handle_parse_error<'a>(
|
|||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
|
||||||
struct DowngradeCtx<'ctx, 'id, 'ir> {
|
struct DowngradeCtx<'ctx, 'id, 'ir, R: VmRuntimeCtx> {
|
||||||
bump: &'ir Bump,
|
bump: &'ir Bump,
|
||||||
token: GhostToken<'id>,
|
token: GhostToken<'id>,
|
||||||
strings: &'ctx mut DefaultStringInterner,
|
runtime: &'ctx mut R,
|
||||||
source: Source,
|
source: Source,
|
||||||
scopes: Vec<Scope<'ctx>>,
|
scopes: Vec<Scope<'ctx>>,
|
||||||
with_scope_count: u32,
|
with_scope_count: u32,
|
||||||
@@ -262,11 +321,11 @@ fn should_thunk<'id>(ir: IrRef<'id, '_>, token: &GhostToken<'id>) -> bool {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'ctx, 'id, 'ir> DowngradeCtx<'ctx, 'id, 'ir> {
|
impl<'ctx, 'id, 'ir, R: VmRuntimeCtx> DowngradeCtx<'ctx, 'id, 'ir, R> {
|
||||||
fn new(
|
fn new(
|
||||||
bump: &'ir Bump,
|
bump: &'ir Bump,
|
||||||
token: GhostToken<'id>,
|
token: GhostToken<'id>,
|
||||||
symbols: &'ctx mut DefaultStringInterner,
|
runtime: &'ctx mut R,
|
||||||
global: &'ctx HashMap<StringId, Ir<'static, RawIrRef<'static>>>,
|
global: &'ctx HashMap<StringId, Ir<'static, RawIrRef<'static>>>,
|
||||||
extra_scope: Option<Scope<'ctx>>,
|
extra_scope: Option<Scope<'ctx>>,
|
||||||
thunk_count: &'ctx mut usize,
|
thunk_count: &'ctx mut usize,
|
||||||
@@ -275,7 +334,7 @@ impl<'ctx, 'id, 'ir> DowngradeCtx<'ctx, 'id, 'ir> {
|
|||||||
Self {
|
Self {
|
||||||
bump,
|
bump,
|
||||||
token,
|
token,
|
||||||
strings: symbols,
|
runtime,
|
||||||
source,
|
source,
|
||||||
scopes: std::iter::once(Scope::Global(global))
|
scopes: std::iter::once(Scope::Global(global))
|
||||||
.chain(extra_scope)
|
.chain(extra_scope)
|
||||||
@@ -288,7 +347,9 @@ impl<'ctx, 'id, 'ir> DowngradeCtx<'ctx, 'id, 'ir> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'ctx: 'ir, 'id, 'ir> DowngradeContext<'id, 'ir> for DowngradeCtx<'ctx, 'id, 'ir> {
|
impl<'ctx: 'ir, 'id, 'ir, R: VmRuntimeCtx> DowngradeContext<'id, 'ir>
|
||||||
|
for DowngradeCtx<'ctx, 'id, 'ir, R>
|
||||||
|
{
|
||||||
fn new_expr(&self, expr: Ir<'ir, IrRef<'id, 'ir>>) -> IrRef<'id, 'ir> {
|
fn new_expr(&self, expr: Ir<'ir, IrRef<'id, 'ir>>) -> IrRef<'id, 'ir> {
|
||||||
IrRef::new(self.bump.alloc(GhostCell::new(expr)))
|
IrRef::new(self.bump.alloc(GhostCell::new(expr)))
|
||||||
}
|
}
|
||||||
@@ -317,11 +378,11 @@ impl<'ctx: 'ir, 'id, 'ir> DowngradeContext<'id, 'ir> for DowngradeCtx<'ctx, 'id,
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn intern_string(&mut self, sym: impl AsRef<str>) -> StringId {
|
fn intern_string(&mut self, sym: impl AsRef<str>) -> StringId {
|
||||||
StringId(self.strings.get_or_intern(sym))
|
self.runtime.intern_string(sym)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn resolve_sym(&self, id: StringId) -> Symbol<'_> {
|
fn resolve_sym(&self, id: StringId) -> Symbol<'_> {
|
||||||
self.strings.resolve(id.0).expect("no symbol found").into()
|
self.runtime.resolve_string(id).into()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn lookup(&self, sym: StringId, span: rnix::TextRange) -> Result<MaybeThunk> {
|
fn lookup(&self, sym: StringId, span: rnix::TextRange) -> Result<MaybeThunk> {
|
||||||
@@ -383,9 +444,9 @@ impl<'ctx: 'ir, 'id, 'ir> DowngradeContext<'id, 'ir> for DowngradeCtx<'ctx, 'id,
|
|||||||
self.source.clone()
|
self.source.clone()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn with_let_scope<F, R>(&mut self, keys: &[StringId], f: F) -> Result<R>
|
fn with_let_scope<F, Ret>(&mut self, keys: &[StringId], f: F) -> Result<Ret>
|
||||||
where
|
where
|
||||||
F: FnOnce(&mut Self) -> Result<(bumpalo::collections::Vec<'ir, IrRef<'id, 'ir>>, R)>,
|
F: FnOnce(&mut Self) -> Result<(bumpalo::collections::Vec<'ir, IrRef<'id, 'ir>>, Ret)>,
|
||||||
{
|
{
|
||||||
let base = *self.thunk_count;
|
let base = *self.thunk_count;
|
||||||
*self.thunk_count = self
|
*self.thunk_count = self
|
||||||
@@ -407,9 +468,9 @@ impl<'ctx: 'ir, 'id, 'ir> DowngradeContext<'id, 'ir> for DowngradeCtx<'ctx, 'id,
|
|||||||
Ok(ret)
|
Ok(ret)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn with_param_scope<F, R>(&mut self, sym: StringId, f: F) -> R
|
fn with_param_scope<F, Ret>(&mut self, sym: StringId, f: F) -> Ret
|
||||||
where
|
where
|
||||||
F: FnOnce(&mut Self) -> R,
|
F: FnOnce(&mut Self) -> Ret,
|
||||||
{
|
{
|
||||||
self.scopes.push(Scope::Param {
|
self.scopes.push(Scope::Param {
|
||||||
sym,
|
sym,
|
||||||
@@ -419,9 +480,9 @@ impl<'ctx: 'ir, 'id, 'ir> DowngradeContext<'id, 'ir> for DowngradeCtx<'ctx, 'id,
|
|||||||
f(guard.as_ctx())
|
f(guard.as_ctx())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn with_with_scope<F, R>(&mut self, f: F) -> R
|
fn with_with_scope<F, Ret>(&mut self, f: F) -> Ret
|
||||||
where
|
where
|
||||||
F: FnOnce(&mut Self) -> R,
|
F: FnOnce(&mut Self) -> Ret,
|
||||||
{
|
{
|
||||||
self.with_scope_count += 1;
|
self.with_scope_count += 1;
|
||||||
let ret = f(self);
|
let ret = f(self);
|
||||||
@@ -429,15 +490,15 @@ impl<'ctx: 'ir, 'id, 'ir> DowngradeContext<'id, 'ir> for DowngradeCtx<'ctx, 'id,
|
|||||||
ret
|
ret
|
||||||
}
|
}
|
||||||
|
|
||||||
fn with_thunk_scope<F, R>(
|
fn with_thunk_scope<F, Ret>(
|
||||||
&mut self,
|
&mut self,
|
||||||
f: F,
|
f: F,
|
||||||
) -> (
|
) -> (
|
||||||
R,
|
Ret,
|
||||||
bumpalo::collections::Vec<'ir, (ThunkId, IrRef<'id, 'ir>)>,
|
bumpalo::collections::Vec<'ir, (ThunkId, IrRef<'id, 'ir>)>,
|
||||||
)
|
)
|
||||||
where
|
where
|
||||||
F: FnOnce(&mut Self) -> R,
|
F: FnOnce(&mut Self) -> Ret,
|
||||||
{
|
{
|
||||||
self.thunk_scopes.push(ThunkScope::new_in(self.bump));
|
self.thunk_scopes.push(ThunkScope::new_in(self.bump));
|
||||||
let ret = f(self);
|
let ret = f(self);
|
||||||
@@ -455,7 +516,7 @@ impl<'ctx: 'ir, 'id, 'ir> DowngradeContext<'id, 'ir> for DowngradeCtx<'ctx, 'id,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'id, 'ir, 'ctx: 'ir> DowngradeCtx<'ctx, 'id, 'ir> {
|
impl<'id, 'ir, 'ctx: 'ir, R: VmRuntimeCtx> DowngradeCtx<'ctx, 'id, 'ir, R> {
|
||||||
fn downgrade_toplevel(mut self, root: rnix::ast::Expr) -> Result<RawIrRef<'ir>> {
|
fn downgrade_toplevel(mut self, root: rnix::ast::Expr) -> Result<RawIrRef<'ir>> {
|
||||||
let body = root.downgrade(&mut self)?;
|
let body = root.downgrade(&mut self)?;
|
||||||
let thunks = self
|
let thunks = self
|
||||||
@@ -496,18 +557,18 @@ enum Scope<'ctx> {
|
|||||||
Param { sym: StringId, abs_layer: usize },
|
Param { sym: StringId, abs_layer: usize },
|
||||||
}
|
}
|
||||||
|
|
||||||
struct ScopeGuard<'a, 'ctx, 'id, 'ir> {
|
struct ScopeGuard<'a, 'ctx, 'id, 'ir, R: VmRuntimeCtx> {
|
||||||
ctx: &'a mut DowngradeCtx<'ctx, 'id, 'ir>,
|
ctx: &'a mut DowngradeCtx<'ctx, 'id, 'ir, R>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Drop for ScopeGuard<'_, '_, '_, '_> {
|
impl<'a, 'ctx, 'id, 'ir, R: VmRuntimeCtx> Drop for ScopeGuard<'a, 'ctx, 'id, 'ir, R> {
|
||||||
fn drop(&mut self) {
|
fn drop(&mut self) {
|
||||||
self.ctx.scopes.pop();
|
self.ctx.scopes.pop();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'id, 'ir, 'ctx> ScopeGuard<'_, 'ctx, 'id, 'ir> {
|
impl<'a, 'ctx, 'id, 'ir, R: VmRuntimeCtx> ScopeGuard<'a, 'ctx, 'id, 'ir, R> {
|
||||||
fn as_ctx(&mut self) -> &mut DowngradeCtx<'ctx, 'id, 'ir> {
|
fn as_ctx(&mut self) -> &mut DowngradeCtx<'ctx, 'id, 'ir, R> {
|
||||||
self.ctx
|
self.ctx
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -518,9 +579,6 @@ struct OwnedIr {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl OwnedIr {
|
impl OwnedIr {
|
||||||
/// # Safety
|
|
||||||
///
|
|
||||||
/// `ir` must be allocated from `bump`.
|
|
||||||
unsafe fn new(ir: RawIrRef<'_>, bump: Bump) -> Self {
|
unsafe fn new(ir: RawIrRef<'_>, bump: Bump) -> Self {
|
||||||
Self {
|
Self {
|
||||||
_bump: bump,
|
_bump: bump,
|
||||||
@@ -533,52 +591,14 @@ impl OwnedIr {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl BytecodeContext for Evaluator {
|
|
||||||
fn intern_string(&mut self, s: &str) -> StringId {
|
|
||||||
StringId(self.strings.get_or_intern(s))
|
|
||||||
}
|
|
||||||
|
|
||||||
fn register_span(&mut self, range: rnix::TextRange) -> u32 {
|
|
||||||
let id = self.spans.len();
|
|
||||||
let source_id = self
|
|
||||||
.sources
|
|
||||||
.len()
|
|
||||||
.checked_sub(1)
|
|
||||||
.expect("current_source not set");
|
|
||||||
self.spans.push((source_id, range));
|
|
||||||
id as u32
|
|
||||||
}
|
|
||||||
|
|
||||||
fn get_code(&self) -> &[u8] {
|
|
||||||
&self.bytecode
|
|
||||||
}
|
|
||||||
|
|
||||||
fn get_code_mut(&mut self) -> &mut Vec<u8> {
|
|
||||||
&mut self.bytecode
|
|
||||||
}
|
|
||||||
|
|
||||||
fn add_constant(&mut self, val: fix_codegen::Const) -> u32 {
|
|
||||||
use fix_codegen::Const::*;
|
|
||||||
let val = match val {
|
|
||||||
Smi(x) => StaticValue::new_inline(x),
|
|
||||||
Float(x) => StaticValue::new_float(x),
|
|
||||||
Bool(x) => StaticValue::new_inline(x),
|
|
||||||
String(x) => StaticValue::new_inline(x),
|
|
||||||
PrimOp { id, arity } => StaticValue::new_primop(id, arity),
|
|
||||||
Null => StaticValue::default(),
|
|
||||||
};
|
|
||||||
self.constants.insert(val)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl DisassemblerContext for Evaluator {
|
impl DisassemblerContext for Evaluator {
|
||||||
fn get_code(&self) -> &[u8] {
|
fn get_code(&self) -> &[u8] {
|
||||||
&self.bytecode
|
&self.code.bytecode
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(clippy::unwrap_used)]
|
#[allow(clippy::unwrap_used)]
|
||||||
fn resolve_string(&self, id: u32) -> &str {
|
fn resolve_string(&self, id: u32) -> &str {
|
||||||
let id = string_interner::symbol::SymbolU32::try_from_usize(id as usize).unwrap();
|
let id = string_interner::symbol::SymbolU32::try_from_usize(id as usize).unwrap();
|
||||||
self.strings.resolve(id).unwrap()
|
self.runtime.strings.resolve(id).unwrap()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user