runtime, vm: write thunk results back to the forcing stack slot

This commit is contained in:
2026-08-22 19:05:13 +08:00
parent 0c0e1849ae
commit 5a06fb4c1e
8 changed files with 43 additions and 17 deletions
+1
View File
@@ -75,6 +75,7 @@ pub trait Machine<'gc> {
pc: ret_pc,
thunk: _,
env,
depth: None,
}) = self.pop_call_frame()
else {
unreachable!()
+2 -1
View File
@@ -59,8 +59,9 @@ pub struct ErrorFrame {
#[collect(no_drop)]
pub struct CallFrame<'gc> {
pub pc: usize,
pub thunk: Option<Gc<'gc, Thunk<'gc>>>,
pub env: GcEnv<'gc>,
pub thunk: Option<Gc<'gc, Thunk<'gc>>>,
pub depth: Option<usize>,
}
#[derive(Debug)]
+22 -16
View File
@@ -26,11 +26,11 @@ pub trait ValueVariant<'gc>: private::Cealed {
private_bounds,
reason = "Storable is a sealed implementation detail of the value system"
)]
type Ty: Storable + 'gc;
type Ty: Storable<'gc>;
const TYPE: NixType;
}
trait Storable: private::Cealed {
trait Storable<'gc>: TryFrom<Value<'gc>> + Into<Value<'gc>> + private::Cealed + 'gc {
fn is(raw: &RawBox) -> bool;
fn to_raw_box(self) -> RawBox;
@@ -46,7 +46,7 @@ macro_rules! define_value_types {
gc { $($gtype:ty => $gtag:path, $gty:path, $gname:literal;)* }
) => {
$(
impl Storable for $itype {
impl Storable<'_> for $itype {
#[inline(always)]
fn is(value: &RawBox) -> bool {
value.tag() == Some($itag)
@@ -80,7 +80,7 @@ macro_rules! define_value_types {
}
)*
$(
impl Storable for Gc<'_, $gtype> {
impl<'gc> Storable<'gc> for Gc<'gc, unelide_lifetimes!('gc; $gtype)> {
#[inline(always)]
fn is(value: &RawBox) -> bool {
value.tag() == Some($gtag)
@@ -202,7 +202,7 @@ define_value_types! {
impl private::Cealed for f64 {}
impl Storable for f64 {
impl Storable<'_> for f64 {
#[inline(always)]
fn is(value: &RawBox) -> bool {
value.is_float()
@@ -224,7 +224,14 @@ impl<'gc> ValueVariant<'gc> for f64 {
const TYPE: NixType = NixType::Float;
}
impl<'gc, T: Storable + 'gc> From<T> for Value<'gc> {
impl<'gc> TryFrom<Value<'gc>> for f64 {
type Error = ();
fn try_from(value: Value<'gc>) -> Result<Self, Self::Error> {
value.downcast::<f64>().ok_or(())
}
}
impl<'gc, T: Storable<'gc>> From<T> for Value<'gc> {
fn from(value: T) -> Self {
Value::new(value)
}
@@ -260,7 +267,7 @@ impl<'gc> Value<'gc> {
private_bounds,
reason = "Storable is a sealed implementation detail of the value system"
)]
pub fn new<T: Storable>(val: T) -> Self {
pub fn new<T: Storable<'gc>>(val: T) -> Self {
Self {
raw: val.to_raw_box(),
_marker: PhantomData,
@@ -380,7 +387,7 @@ impl StaticValue {
private_bounds,
reason = "Storable is a sealed implementation detail of the value system"
)]
pub fn new<T: Storable + 'static>(val: T) -> Self {
pub fn new<T: Storable<'static>>(val: T) -> Self {
Self(Value::new(val))
}
@@ -597,14 +604,6 @@ pub struct Env<'gc> {
}
pub type GcEnv<'gc> = GcRefLock<'gc, Env<'gc>>;
#[derive(Collect, Debug)]
#[collect(no_drop)]
pub struct WithEnv<'gc> {
pub env: Value<'gc>,
pub prev: Option<GcWithEnv<'gc>>,
}
pub type GcWithEnv<'gc> = Gc<'gc, WithEnv<'gc>>;
impl<'gc> Env<'gc> {
pub fn empty() -> Self {
Env {
@@ -722,6 +721,13 @@ impl<'gc> From<StrictValue<'gc>> for Value<'gc> {
}
}
impl<'gc> TryFrom<Value<'gc>> for StrictValue<'gc> {
type Error = Gc<'gc, Thunk<'gc>>;
fn try_from(value: Value<'gc>) -> Result<Self, Self::Error> {
value.restrict()
}
}
impl fmt::Debug for StrictValue<'_> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
fmt::Debug::fmt(&self.0, f)