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