diff --git a/Cargo.lock b/Cargo.lock index 4218c53..d37f998 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -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" diff --git a/Cargo.toml b/Cargo.toml index 1a1ec9e..685ed17 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -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" diff --git a/fix-bytecode/Cargo.toml b/fix-bytecode/Cargo.toml index 6a9608b..6961263 100644 --- a/fix-bytecode/Cargo.toml +++ b/fix-bytecode/Cargo.toml @@ -5,7 +5,6 @@ edition = "2024" [dependencies] colored = "3.1.1" -likely_stable = { workspace = true } num_enum = { workspace = true } string-interner = { workspace = true } diff --git a/fix-bytecode/src/disassembler.rs b/fix-bytecode/src/disassembler.rs index a4682f1..a38d645 100644 --- a/fix-bytecode/src/disassembler.rs +++ b/fix-bytecode/src/disassembler.rs @@ -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 => { diff --git a/fix-bytecode/src/lib.rs b/fix-bytecode/src/lib.rs index 1a524c6..a46457f 100644 --- a/fix-bytecode/src/lib.rs +++ b/fix-bytecode/src/lib.rs @@ -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; diff --git a/fix-compiler/Cargo.toml b/fix-compiler/Cargo.toml index 09ad0c9..9c04e4f 100644 --- a/fix-compiler/Cargo.toml +++ b/fix-compiler/Cargo.toml @@ -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 } diff --git a/fix-compiler/src/ir.rs b/fix-compiler/src/ir.rs index 2809a36..ab00623 100644 --- a/fix-compiler/src/ir.rs +++ b/fix-compiler/src/ir.rs @@ -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)); } diff --git a/fix-runtime/Cargo.toml b/fix-runtime/Cargo.toml index f21d87e..ee63d6e 100644 --- a/fix-runtime/Cargo.toml +++ b/fix-runtime/Cargo.toml @@ -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 } diff --git a/fix-runtime/src/value.rs b/fix-runtime/src/value.rs index 52c3c2a..0932a29 100644 --- a/fix-runtime/src/value.rs +++ b/fix-runtime/src/value.rs @@ -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(val: T) -> Self { Self::from_raw_value(RawValue::store(T::TAG, val)) } #[inline] + #[allow(private_bounds)] pub fn new_gc(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(self) -> bool { self.tag() == Some(T::TAG) } @@ -224,6 +220,7 @@ impl<'gc> Value<'gc> { } #[inline] + #[allow(private_bounds)] pub fn as_inline(self) -> Option { if self.is::() { Some(unsafe { @@ -236,6 +233,7 @@ impl<'gc> Value<'gc> { } #[inline] + #[allow(private_bounds)] pub fn as_gc(self) -> Option> { if self.is::() { Some(unsafe { @@ -307,11 +305,13 @@ impl<'gc> Value<'gc> { } #[inline] + #[allow(private_bounds)] pub fn expect_inline(self) -> Result { self.as_inline::().ok_or_else(|| self.ty()) } #[inline] + #[allow(private_bounds)] pub fn expect_gc(self) -> Result, NixType> { self.as_gc::().ok_or_else(|| self.ty()) } @@ -350,6 +350,7 @@ impl StaticValue { Self(Value::new_float(val)) } #[inline] + #[allow(private_bounds)] pub fn new_inline(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(self) -> bool { self.0.is::() } @@ -374,6 +376,7 @@ impl StaticValue { self.0.as_float() } #[inline] + #[allow(private_bounds)] pub fn as_inline(self) -> Option { self.0.as_inline::() } @@ -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), } diff --git a/fix-vm/Cargo.toml b/fix-vm/Cargo.toml index f59c2a2..ae23248 100644 --- a/fix-vm/Cargo.toml +++ b/fix-vm/Cargo.toml @@ -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" } diff --git a/fix-vm/src/instructions/misc.rs b/fix-vm/src/instructions/misc.rs index c0e3c5d..c3d40a5 100644 --- a/fix-vm/src/instructions/misc.rs +++ b/fix-vm/src/instructions/misc.rs @@ -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, diff --git a/fix-vm/src/instructions/variables.rs b/fix-vm/src/instructions/variables.rs index d3f06d0..c9d9358 100644 --- a/fix-vm/src/instructions/variables.rs +++ b/fix-vm/src/instructions/variables.rs @@ -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(()) +} diff --git a/fix-vm/src/lib.rs b/fix-vm/src/lib.rs index 391766b..27555f6 100644 --- a/fix-vm/src/lib.rs +++ b/fix-vm/src/lib.rs @@ -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();