Compare commits

...

1 Commits

Author SHA1 Message Date
imxyy1soope1 dde3052e2d chore 2026-06-30 18:49:45 +08:00
13 changed files with 79 additions and 106 deletions
Generated
-26
View File
@@ -472,7 +472,6 @@ version = "0.1.0"
dependencies = [
"colored",
"fix-lang",
"likely_stable",
"num_enum",
"string-interner",
]
@@ -489,7 +488,6 @@ dependencies = [
"fix-runtime",
"ghost-cell",
"hashbrown 0.16.1",
"num_enum",
"rnix",
"rowan",
"string-interner",
@@ -524,8 +522,6 @@ dependencies = [
"fix-lang",
"gc-arena",
"hashbrown 0.16.1",
"likely_stable",
"num_enum",
"smallvec",
"sptr",
"string-interner",
@@ -541,11 +537,7 @@ dependencies = [
"fix-runtime",
"gc-arena",
"hashbrown 0.16.1",
"likely_stable",
"num_enum",
"smallvec",
"sptr",
"string-interner",
"sysinfo",
]
@@ -743,15 +735,6 @@ dependencies = [
"libc",
]
[[package]]
name = "likely_stable"
version = "0.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d61f7017d8abea1fc23ff7f01a8147b2656dea3aeb24d519aab6e2177eaf671c"
dependencies = [
"rustc_version",
]
[[package]]
name = "linux-raw-sys"
version = "0.12.1"
@@ -1128,15 +1111,6 @@ version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2"
[[package]]
name = "rustc_version"
version = "0.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cfcb3a22ef46e85b45de6ee7e79d063319ebb6594faafcf1c225ea92ab6e9b92"
dependencies = [
"semver",
]
[[package]]
name = "rustix"
version = "1.1.4"
-1
View File
@@ -22,7 +22,6 @@ bumpalo = {
ere = "0.2"
ghost-cell = "0.2"
hashbrown = "0.16"
likely_stable = "0.1"
num_enum = "0.7.5"
rnix = "0.14"
rowan = "0.16"
-1
View File
@@ -5,7 +5,6 @@ edition = "2024"
[dependencies]
colored = "3.1.1"
likely_stable = { workspace = true }
num_enum = { workspace = true }
string-interner = { workspace = true }
+3 -4
View File
@@ -1,7 +1,6 @@
use std::fmt::Write;
use colored::Colorize;
use num_enum::TryFromPrimitive;
use colored::Colorize as _;
use crate::{InstructionPtr, Op, OperandType, PrimOpPhase};
@@ -81,7 +80,7 @@ impl<'a, Ctx: DisassemblerContext> Disassembler<'a, Ctx> {
fn read_operand_data(&mut self) {
use OperandType::*;
let tag = self.read_u8();
let ty = OperandType::try_from_primitive(tag).expect("invalid operand type");
let ty = OperandType::try_from(tag).expect("invalid operand type");
match ty {
Const => {
self.read_u32();
@@ -201,7 +200,7 @@ impl<'a, Ctx: DisassemblerContext> Disassembler<'a, Ctx> {
}
fn decode_instruction(&mut self, op_byte: u8, current_pc: usize) -> (&'static str, String) {
let op = Op::try_from_primitive(op_byte).expect("invalid op code");
let op = Op::try_from(op_byte).expect("invalid op code");
match op {
Op::PushSmi => {
+2 -1
View File
@@ -447,7 +447,8 @@ impl<'a> BytecodeReader<'a> {
pub fn read_op(&mut self) -> Op {
self.inst_start_pc = self.pc;
let byte = self.bytecode[self.pc];
if !likely_stable::likely((0..Op::Illegal as u8).contains(&byte)) {
if !(0..Op::Illegal as u8).contains(&byte) {
std::hint::cold_path();
panic!("unknown opcode: {byte:#04x}")
}
self.pc += 1;
-1
View File
@@ -8,7 +8,6 @@ bumpalo = { workspace = true }
colored = "3.1.1"
ghost-cell = { workspace = true }
hashbrown = { workspace = true }
num_enum = { workspace = true }
rnix = { workspace = true }
rowan = { workspace = true }
string-interner = { workspace = true }
+1 -2
View File
@@ -5,7 +5,6 @@ use bumpalo::Bump;
use bumpalo::collections::Vec;
use fix_lang::{BUILTINS, BuiltinId, StringId};
use ghost_cell::{GhostCell, GhostToken};
use num_enum::TryFromPrimitive as _;
use rnix::{TextRange, ast};
use string_interner::DefaultStringInterner;
@@ -293,7 +292,7 @@ pub fn new_global_env(
global_env.insert(builtins_sym, MaybeThunk::Builtins);
for (idx, &(name, _)) in BUILTINS.iter().enumerate() {
let id = BuiltinId::try_from_primitive(idx as u8).expect("infallible");
let id = BuiltinId::try_from(idx as u8).expect("infallible");
let name = StringId(strings.get_or_intern(name));
global_env.insert(name, MaybeThunk::Builtin(id));
}
-2
View File
@@ -6,8 +6,6 @@ edition = "2024"
[dependencies]
gc-arena = { workspace = true }
hashbrown = { workspace = true }
likely_stable = { workspace = true }
num_enum = { workspace = true }
smallvec = { workspace = true }
sptr = "0.3"
string-interner = { workspace = true }
+23 -20
View File
@@ -1,5 +1,3 @@
#![allow(dead_code)]
use std::cell::RefCell;
use std::fmt;
use std::marker::PhantomData;
@@ -10,7 +8,6 @@ use fix_lang::*;
use gc_arena::barrier::Unlock;
use gc_arena::collect::Trace;
use gc_arena::{Collect, Gc, GcRefLock, Mutation, RefLock};
use num_enum::TryFromPrimitive;
use smallvec::SmallVec;
use string_interner::Symbol;
use string_interner::symbol::SymbolU32;
@@ -24,14 +21,12 @@ mod private {
/// # Safety
///
/// TAG must be unique among all implementors.
#[allow(private_interfaces)]
pub unsafe trait Storable: private::Cealed {
/// [`Self::TAG`] must be unique among all implementors.
unsafe trait Storable: private::Cealed {
const TAG: RawTag;
}
#[allow(private_bounds)]
pub trait InlineStorable: Storable + RawStore {}
pub trait GcStorable: Storable {}
trait InlineStorable: Storable + RawStore {}
trait GcStorable: Storable {}
macro_rules! define_value_types {
(
@@ -39,7 +34,6 @@ macro_rules! define_value_types {
gc { $($gtype:ty => $gtag:expr, $gname:literal;)* }
) => {
$(
#[allow(private_interfaces)]
unsafe impl Storable for $itype {
const TAG: RawTag = $itag;
}
@@ -47,7 +41,6 @@ macro_rules! define_value_types {
impl private::Cealed for $itype {}
)*
$(
#[allow(private_interfaces)]
unsafe impl Storable for $gtype {
const TAG: RawTag = $gtag;
}
@@ -116,16 +109,16 @@ define_value_types! {
Null => RawTag::P3, "Null";
StringId => RawTag::P4, "SmallString";
PrimOp => RawTag::P5, "PrimOp";
Path => RawTag::N6, "Path";
Path => RawTag::P6, "Path";
}
gc {
i64 => RawTag::P6, "BigInt";
NixString => RawTag::P7, "String";
AttrSet<'_> => RawTag::N1, "AttrSet";
List<'_> => RawTag::N2, "List";
Thunk<'_> => RawTag::N3, "Thunk";
Closure<'_> => RawTag::N4, "Closure";
PrimOpApp<'_> => RawTag::N5, "PrimOpApp";
i64 => RawTag::P7, "BigInt";
NixString => RawTag::N1, "String";
AttrSet<'_> => RawTag::N2, "AttrSet";
List<'_> => RawTag::N3, "List";
Thunk<'_> => RawTag::N4, "Thunk";
Closure<'_> => RawTag::N5, "Closure";
PrimOpApp<'_> => RawTag::N6, "PrimOpApp";
}
}
@@ -185,11 +178,13 @@ impl<'gc> Value<'gc> {
}
#[inline]
#[allow(private_bounds)]
pub fn new_inline<T: InlineStorable>(val: T) -> Self {
Self::from_raw_value(RawValue::store(T::TAG, val))
}
#[inline]
#[allow(private_bounds)]
pub fn new_gc<T: GcStorable>(gc: Gc<'gc, T>) -> Self {
let ptr = Gc::as_ptr(gc);
Self::from_raw_value(RawValue::store(T::TAG, ptr))
@@ -212,6 +207,7 @@ impl<'gc> Value<'gc> {
}
#[inline]
#[allow(private_bounds)]
pub fn is<T: Storable>(self) -> bool {
self.tag() == Some(T::TAG)
}
@@ -224,6 +220,7 @@ impl<'gc> Value<'gc> {
}
#[inline]
#[allow(private_bounds)]
pub fn as_inline<T: InlineStorable>(self) -> Option<T> {
if self.is::<T>() {
Some(unsafe {
@@ -236,6 +233,7 @@ impl<'gc> Value<'gc> {
}
#[inline]
#[allow(private_bounds)]
pub fn as_gc<T: GcStorable>(self) -> Option<Gc<'gc, T>> {
if self.is::<T>() {
Some(unsafe {
@@ -307,11 +305,13 @@ impl<'gc> Value<'gc> {
}
#[inline]
#[allow(private_bounds)]
pub fn expect_inline<T: InlineStorable>(self) -> Result<T, NixType> {
self.as_inline::<T>().ok_or_else(|| self.ty())
}
#[inline]
#[allow(private_bounds)]
pub fn expect_gc<T: GcStorable>(self) -> Result<Gc<'gc, T>, NixType> {
self.as_gc::<T>().ok_or_else(|| self.ty())
}
@@ -350,6 +350,7 @@ impl StaticValue {
Self(Value::new_float(val))
}
#[inline]
#[allow(private_bounds)]
pub fn new_inline<T: InlineStorable>(val: T) -> Self {
Self(Value::new_inline(val))
}
@@ -366,6 +367,7 @@ impl StaticValue {
self.0.is_float()
}
#[inline]
#[allow(private_bounds)]
pub fn is<T: InlineStorable>(self) -> bool {
self.0.is::<T>()
}
@@ -374,6 +376,7 @@ impl StaticValue {
self.0.as_float()
}
#[inline]
#[allow(private_bounds)]
pub fn as_inline<T: InlineStorable>(self) -> Option<T> {
self.0.as_inline::<T>()
}
@@ -637,7 +640,7 @@ impl RawStore for PrimOp {
fn from_val(value: &RawValue) -> Self {
let [id, arity, bytes @ ..] = *value.data();
Self {
id: BuiltinId::try_from_primitive(id).expect("invalid BuiltinId"),
id: BuiltinId::try_from(id).expect("invalid BuiltinId"),
arity,
dispatch_ip: u32::from_le_bytes(bytes),
}
-4
View File
@@ -6,11 +6,7 @@ edition = "2024"
[dependencies]
gc-arena = { workspace = true }
hashbrown = { workspace = true }
likely_stable = { workspace = true }
num_enum = { workspace = true }
smallvec = { workspace = true }
sptr = "0.3"
string-interner = { workspace = true }
sysinfo = { version = "0.38", default-features = false, features = ["system"] }
fix-bytecode = { path = "../fix-bytecode" }
+1 -2
View File
@@ -6,7 +6,6 @@ use fix_lang::{BUILTINS, BuiltinId, StringId};
use fix_runtime::{
AttrSet, Machine, MachineExt, NixString, Path, StrictValue, StringContext, canon_path_str,
};
use num_enum::TryFromPrimitive;
use crate::{BytecodeReader, PrimOp, Step, Value, VmRuntimeCtx, VmRuntimeCtxExt};
@@ -21,7 +20,7 @@ pub(crate) fn op_load_builtin<'gc, M: Machine<'gc>>(
m: &mut M,
reader: &mut BytecodeReader<'_>,
) -> Step {
let Ok(id) = BuiltinId::try_from_primitive(reader.read_u8())
let Ok(id) = BuiltinId::try_from(reader.read_u8())
.map_err(|err| panic!("unknown builtin id: {}", err.number));
m.push(Value::new_inline(PrimOp {
id,
+48 -40
View File
@@ -2,47 +2,55 @@ use fix_runtime::Machine;
use crate::{BytecodeReader, Mutation, Step, Value};
#[inline(always)]
pub(crate) fn op_load_local<'gc, M: Machine<'gc>>(m: &mut M, reader: &mut BytecodeReader<'_>) -> Step {
let idx = reader.read_u32() as usize;
m.push(m.env().borrow().locals[idx]);
Step::Continue(())
}
#[inline(always)]
pub(crate) fn op_load_local<'gc, M: Machine<'gc>>(
m: &mut M,
reader: &mut BytecodeReader<'_>,
) -> Step {
let idx = reader.read_u32() as usize;
m.push(m.env().borrow().locals[idx]);
Step::Continue(())
}
#[inline(always)]
pub(crate) fn op_load_outer<'gc, M: Machine<'gc>>(m: &mut M, reader: &mut BytecodeReader<'_>) -> Step {
let layer = reader.read_u8();
let idx = reader.read_u32() as usize;
let mut cur = m.env();
for _ in 0..layer {
let prev = cur.borrow().prev.expect("LoadOuter: env chain too short");
cur = prev;
}
let val = cur.borrow().locals[idx];
m.push(val);
Step::Continue(())
#[inline(always)]
pub(crate) fn op_load_outer<'gc, M: Machine<'gc>>(
m: &mut M,
reader: &mut BytecodeReader<'_>,
) -> Step {
let layer = reader.read_u8();
let idx = reader.read_u32() as usize;
let mut cur = m.env();
for _ in 0..layer {
let prev = cur.borrow().prev.expect("LoadOuter: env chain too short");
cur = prev;
}
let val = cur.borrow().locals[idx];
m.push(val);
Step::Continue(())
}
#[inline(always)]
pub(crate) fn op_store_local<'gc, M: Machine<'gc>>(m: &mut M,
reader: &mut BytecodeReader<'_>,
mc: &Mutation<'gc>,
) -> Step {
let idx = reader.read_u32() as usize;
let val = m.pop();
m.env().borrow_mut(mc).locals[idx] = val;
Step::Continue(())
}
#[inline(always)]
pub(crate) fn op_store_local<'gc, M: Machine<'gc>>(
m: &mut M,
reader: &mut BytecodeReader<'_>,
mc: &Mutation<'gc>,
) -> Step {
let idx = reader.read_u32() as usize;
let val = m.pop();
m.env().borrow_mut(mc).locals[idx] = val;
Step::Continue(())
}
#[inline(always)]
pub(crate) fn op_alloc_locals<'gc, M: Machine<'gc>>(m: &mut M,
reader: &mut BytecodeReader<'_>,
mc: &Mutation<'gc>,
) -> Step {
let count = reader.read_u32() as usize;
m.env()
.borrow_mut(mc)
.locals
.extend(std::iter::repeat_n(Value::default(), count));
Step::Continue(())
}
#[inline(always)]
pub(crate) fn op_alloc_locals<'gc, M: Machine<'gc>>(
m: &mut M,
reader: &mut BytecodeReader<'_>,
mc: &Mutation<'gc>,
) -> Step {
let count = reader.read_u32() as usize;
m.env()
.borrow_mut(mc)
.locals
.extend(std::iter::repeat_n(Value::default(), count));
Step::Continue(())
}
+1 -2
View File
@@ -13,7 +13,6 @@ use fix_lang::{BUILTINS, BuiltinId, StringId};
use gc_arena::metrics::Pacing;
use gc_arena::{Arena, Collect, Gc, Mutation, RefLock, Rootable};
use hashbrown::HashMap;
use num_enum::TryFromPrimitive;
use smallvec::SmallVec;
#[cfg(feature = "tailcall")]
@@ -58,7 +57,7 @@ fn init_builtins<'gc>(mc: &Mutation<'gc>, ctx: &mut impl VmRuntimeCtx) -> Value<
let mut entries = SmallVec::with_capacity(BUILTINS.len());
for (idx, &(name, arity)) in BUILTINS.iter().enumerate() {
let id = BuiltinId::try_from_primitive(idx as u8).expect("infallible");
let id = BuiltinId::try_from(idx as u8).expect("infallible");
let name = name.strip_prefix("__").unwrap_or(name);
let name = ctx.intern_string(name);
let dispatch_ip = PrimOpPhase::entry_for_builtin(id).ip();