87 lines
1.9 KiB
Rust
87 lines
1.9 KiB
Rust
use std::marker::PhantomData;
|
|
use std::ops::ControlFlow;
|
|
|
|
use fix_bytecode::BytecodeReader;
|
|
use gc_arena::Mutation;
|
|
|
|
use crate::{Break, Forced, Machine, NixType, Step, StrictValue, Value, ValueVariant};
|
|
|
|
pub struct TypeError {
|
|
pub expected: NixType,
|
|
pub got: NixType,
|
|
}
|
|
|
|
pub trait SlotContent<'gc> {
|
|
type Ty: Into<Value<'gc>> + TryFrom<Value<'gc>> + 'gc;
|
|
}
|
|
|
|
impl<'gc> SlotContent<'gc> for Value<'gc> {
|
|
type Ty = Value<'gc>;
|
|
}
|
|
|
|
impl<'gc> SlotContent<'gc> for StrictValue<'gc> {
|
|
type Ty = StrictValue<'gc>;
|
|
}
|
|
|
|
impl<'gc, T> SlotContent<'gc> for T
|
|
where
|
|
T: ValueVariant<'gc>,
|
|
{
|
|
type Ty = T::Ty;
|
|
}
|
|
|
|
pub struct Slot<T> {
|
|
depth: u8,
|
|
_marker: PhantomData<T>,
|
|
}
|
|
|
|
impl<T> Slot<T> {
|
|
#[inline(always)]
|
|
pub const fn new(depth: u8) -> Self {
|
|
Self {
|
|
depth,
|
|
_marker: PhantomData,
|
|
}
|
|
}
|
|
}
|
|
|
|
impl<'gc, T> Slot<T>
|
|
where
|
|
T: SlotContent<'gc>,
|
|
<T::Ty as TryFrom<Value<'gc>>>::Error: std::fmt::Debug,
|
|
{
|
|
#[inline(always)]
|
|
pub fn read<M: Machine<'gc>>(&self, m: &M) -> T::Ty {
|
|
T::Ty::try_from(m.peek(self.depth as usize)).expect("slot held a value of the wrong type")
|
|
}
|
|
|
|
#[inline(always)]
|
|
pub fn write<M: Machine<'gc>>(&self, m: &mut M, val: T::Ty) {
|
|
m.replace(self.depth as usize, T::Ty::into(val));
|
|
}
|
|
}
|
|
|
|
impl<'gc> Slot<Value<'gc>> {
|
|
#[inline(always)]
|
|
pub fn force<T: Forced<'gc>, M: Machine<'gc>>(
|
|
&self,
|
|
m: &mut M,
|
|
reader: &mut BytecodeReader<'_>,
|
|
mc: &Mutation<'gc>,
|
|
) -> ControlFlow<Break, Slot<T>> {
|
|
T::force_and_check(m, reader, mc, self.depth as usize, reader.inst_start_pc())?;
|
|
ControlFlow::Continue(Slot::new(self.depth))
|
|
}
|
|
|
|
#[inline(always)]
|
|
pub fn force_to_pc<M: Machine<'gc>>(
|
|
&self,
|
|
m: &mut M,
|
|
reader: &mut BytecodeReader<'_>,
|
|
mc: &Mutation<'gc>,
|
|
pc: usize,
|
|
) -> Step {
|
|
m.force_slot_to_pc(self.depth as usize, reader, mc, pc)
|
|
}
|
|
}
|