runtime, vm: write thunk results back to the forcing stack slot
This commit is contained in:
@@ -75,6 +75,7 @@ pub trait Machine<'gc> {
|
|||||||
pc: ret_pc,
|
pc: ret_pc,
|
||||||
thunk: _,
|
thunk: _,
|
||||||
env,
|
env,
|
||||||
|
depth: None,
|
||||||
}) = self.pop_call_frame()
|
}) = self.pop_call_frame()
|
||||||
else {
|
else {
|
||||||
unreachable!()
|
unreachable!()
|
||||||
|
|||||||
@@ -59,8 +59,9 @@ pub struct ErrorFrame {
|
|||||||
#[collect(no_drop)]
|
#[collect(no_drop)]
|
||||||
pub struct CallFrame<'gc> {
|
pub struct CallFrame<'gc> {
|
||||||
pub pc: usize,
|
pub pc: usize,
|
||||||
pub thunk: Option<Gc<'gc, Thunk<'gc>>>,
|
|
||||||
pub env: GcEnv<'gc>,
|
pub env: GcEnv<'gc>,
|
||||||
|
pub thunk: Option<Gc<'gc, Thunk<'gc>>>,
|
||||||
|
pub depth: Option<usize>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
|
|||||||
+22
-16
@@ -26,11 +26,11 @@ pub trait ValueVariant<'gc>: private::Cealed {
|
|||||||
private_bounds,
|
private_bounds,
|
||||||
reason = "Storable is a sealed implementation detail of the value system"
|
reason = "Storable is a sealed implementation detail of the value system"
|
||||||
)]
|
)]
|
||||||
type Ty: Storable + 'gc;
|
type Ty: Storable<'gc>;
|
||||||
const TYPE: NixType;
|
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 is(raw: &RawBox) -> bool;
|
||||||
|
|
||||||
fn to_raw_box(self) -> RawBox;
|
fn to_raw_box(self) -> RawBox;
|
||||||
@@ -46,7 +46,7 @@ macro_rules! define_value_types {
|
|||||||
gc { $($gtype:ty => $gtag:path, $gty:path, $gname:literal;)* }
|
gc { $($gtype:ty => $gtag:path, $gty:path, $gname:literal;)* }
|
||||||
) => {
|
) => {
|
||||||
$(
|
$(
|
||||||
impl Storable for $itype {
|
impl Storable<'_> for $itype {
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn is(value: &RawBox) -> bool {
|
fn is(value: &RawBox) -> bool {
|
||||||
value.tag() == Some($itag)
|
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)]
|
#[inline(always)]
|
||||||
fn is(value: &RawBox) -> bool {
|
fn is(value: &RawBox) -> bool {
|
||||||
value.tag() == Some($gtag)
|
value.tag() == Some($gtag)
|
||||||
@@ -202,7 +202,7 @@ define_value_types! {
|
|||||||
|
|
||||||
impl private::Cealed for f64 {}
|
impl private::Cealed for f64 {}
|
||||||
|
|
||||||
impl Storable for f64 {
|
impl Storable<'_> for f64 {
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn is(value: &RawBox) -> bool {
|
fn is(value: &RawBox) -> bool {
|
||||||
value.is_float()
|
value.is_float()
|
||||||
@@ -224,7 +224,14 @@ impl<'gc> ValueVariant<'gc> for f64 {
|
|||||||
const TYPE: NixType = NixType::Float;
|
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 {
|
fn from(value: T) -> Self {
|
||||||
Value::new(value)
|
Value::new(value)
|
||||||
}
|
}
|
||||||
@@ -260,7 +267,7 @@ impl<'gc> Value<'gc> {
|
|||||||
private_bounds,
|
private_bounds,
|
||||||
reason = "Storable is a sealed implementation detail of the value system"
|
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 {
|
Self {
|
||||||
raw: val.to_raw_box(),
|
raw: val.to_raw_box(),
|
||||||
_marker: PhantomData,
|
_marker: PhantomData,
|
||||||
@@ -380,7 +387,7 @@ impl StaticValue {
|
|||||||
private_bounds,
|
private_bounds,
|
||||||
reason = "Storable is a sealed implementation detail of the value system"
|
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))
|
Self(Value::new(val))
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -597,14 +604,6 @@ pub struct Env<'gc> {
|
|||||||
}
|
}
|
||||||
pub type GcEnv<'gc> = GcRefLock<'gc, 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> {
|
impl<'gc> Env<'gc> {
|
||||||
pub fn empty() -> Self {
|
pub fn empty() -> Self {
|
||||||
Env {
|
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<'_> {
|
impl fmt::Debug for StrictValue<'_> {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
fmt::Debug::fmt(&self.0, f)
|
fmt::Debug::fmt(&self.0, f)
|
||||||
|
|||||||
@@ -34,6 +34,7 @@ pub(crate) fn call<'gc, M: Machine<'gc>>(
|
|||||||
pc: resume_pc,
|
pc: resume_pc,
|
||||||
thunk: None,
|
thunk: None,
|
||||||
env: m.env(),
|
env: m.env(),
|
||||||
|
depth: None,
|
||||||
});
|
});
|
||||||
reader.set_pc(Continuation::CallPattern.ip() as usize);
|
reader.set_pc(Continuation::CallPattern.ip() as usize);
|
||||||
return Step::Continue(());
|
return Step::Continue(());
|
||||||
@@ -47,6 +48,7 @@ pub(crate) fn call<'gc, M: Machine<'gc>>(
|
|||||||
pc: resume_pc,
|
pc: resume_pc,
|
||||||
thunk: None,
|
thunk: None,
|
||||||
env: m.env(),
|
env: m.env(),
|
||||||
|
depth: None,
|
||||||
});
|
});
|
||||||
reader.set_pc(ip as usize);
|
reader.set_pc(ip as usize);
|
||||||
m.set_env(new_env);
|
m.set_env(new_env);
|
||||||
@@ -57,6 +59,7 @@ pub(crate) fn call<'gc, M: Machine<'gc>>(
|
|||||||
pc: resume_pc,
|
pc: resume_pc,
|
||||||
thunk: None,
|
thunk: None,
|
||||||
env: m.env(),
|
env: m.env(),
|
||||||
|
depth: None,
|
||||||
});
|
});
|
||||||
reader.set_pc(primop.dispatch_ip as usize)
|
reader.set_pc(primop.dispatch_ip as usize)
|
||||||
} else {
|
} else {
|
||||||
@@ -77,6 +80,7 @@ pub(crate) fn call<'gc, M: Machine<'gc>>(
|
|||||||
pc: resume_pc,
|
pc: resume_pc,
|
||||||
thunk: None,
|
thunk: None,
|
||||||
env: m.env(),
|
env: m.env(),
|
||||||
|
depth: None,
|
||||||
});
|
});
|
||||||
reader.set_pc(app.primop.dispatch_ip as usize)
|
reader.set_pc(app.primop.dispatch_ip as usize)
|
||||||
} else {
|
} else {
|
||||||
@@ -101,6 +105,7 @@ pub(crate) fn call<'gc, M: Machine<'gc>>(
|
|||||||
pc: resume_pc,
|
pc: resume_pc,
|
||||||
thunk: None,
|
thunk: None,
|
||||||
env: m.env(),
|
env: m.env(),
|
||||||
|
depth: None,
|
||||||
});
|
});
|
||||||
m.push(arg);
|
m.push(arg);
|
||||||
m.push(func.relax());
|
m.push(func.relax());
|
||||||
@@ -140,6 +145,7 @@ pub(crate) fn op_return<'gc, M: Machine<'gc>>(
|
|||||||
pc: ret_pc,
|
pc: ret_pc,
|
||||||
thunk,
|
thunk,
|
||||||
env,
|
env,
|
||||||
|
depth,
|
||||||
}) = m.pop_call_frame()
|
}) = m.pop_call_frame()
|
||||||
else {
|
else {
|
||||||
match m.force_mode() {
|
match m.force_mode() {
|
||||||
@@ -156,6 +162,7 @@ pub(crate) fn op_return<'gc, M: Machine<'gc>>(
|
|||||||
pc: Continuation::ForceResultDeepFinish.ip() as usize,
|
pc: Continuation::ForceResultDeepFinish.ip() as usize,
|
||||||
thunk: None,
|
thunk: None,
|
||||||
env: m.env(),
|
env: m.env(),
|
||||||
|
depth: None,
|
||||||
});
|
});
|
||||||
m.inc_call_depth();
|
m.inc_call_depth();
|
||||||
reader.set_pc(Continuation::PDeepSeq.ip() as usize);
|
reader.set_pc(Continuation::PDeepSeq.ip() as usize);
|
||||||
@@ -166,6 +173,9 @@ pub(crate) fn op_return<'gc, M: Machine<'gc>>(
|
|||||||
reader.set_pc(ret_pc);
|
reader.set_pc(ret_pc);
|
||||||
if let Some(outer_thunk) = thunk {
|
if let Some(outer_thunk) = thunk {
|
||||||
*outer_thunk.borrow_mut(mc) = ThunkState::Evaluated(val);
|
*outer_thunk.borrow_mut(mc) = ThunkState::Evaluated(val);
|
||||||
|
if let Some(depth) = depth {
|
||||||
|
m.replace(depth, val.relax());
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
m.dec_call_depth();
|
m.dec_call_depth();
|
||||||
m.push(val.relax())
|
m.push(val.relax())
|
||||||
|
|||||||
@@ -41,6 +41,7 @@ pub(crate) fn op_lookup_with<'gc, M: Machine<'gc>>(
|
|||||||
thunk: Some(thunk),
|
thunk: Some(thunk),
|
||||||
pc: resume_pc,
|
pc: resume_pc,
|
||||||
env: m.env(),
|
env: m.env(),
|
||||||
|
depth: None,
|
||||||
});
|
});
|
||||||
m.set_env(env);
|
m.set_env(env);
|
||||||
reader.set_pc(ip);
|
reader.set_pc(ip);
|
||||||
@@ -52,6 +53,7 @@ pub(crate) fn op_lookup_with<'gc, M: Machine<'gc>>(
|
|||||||
thunk: Some(thunk),
|
thunk: Some(thunk),
|
||||||
pc: resume_pc,
|
pc: resume_pc,
|
||||||
env: m.env(),
|
env: m.env(),
|
||||||
|
depth: None,
|
||||||
});
|
});
|
||||||
m.push(func);
|
m.push(func);
|
||||||
return m.call(reader, mc, arg, resume_pc);
|
return m.call(reader, mc, arg, resume_pc);
|
||||||
|
|||||||
@@ -211,6 +211,7 @@ impl<'gc> Machine<'gc> for Vm<'gc> {
|
|||||||
thunk: Some(thunk),
|
thunk: Some(thunk),
|
||||||
pc: resume_pc,
|
pc: resume_pc,
|
||||||
env: self.env,
|
env: self.env,
|
||||||
|
depth: Some(depth),
|
||||||
});
|
});
|
||||||
self.env = env;
|
self.env = env;
|
||||||
reader.set_pc(ip);
|
reader.set_pc(ip);
|
||||||
@@ -225,6 +226,7 @@ impl<'gc> Machine<'gc> for Vm<'gc> {
|
|||||||
thunk: Some(thunk),
|
thunk: Some(thunk),
|
||||||
pc: resume_pc,
|
pc: resume_pc,
|
||||||
env: self.env,
|
env: self.env,
|
||||||
|
depth: Some(depth),
|
||||||
});
|
});
|
||||||
self.push(func);
|
self.push(func);
|
||||||
self.call(reader, mc, arg, resume_pc)
|
self.call(reader, mc, arg, resume_pc)
|
||||||
|
|||||||
@@ -166,6 +166,7 @@ fn enter_eq_machine<'gc, M: Machine<'gc>>(
|
|||||||
pc: resume_pc,
|
pc: resume_pc,
|
||||||
thunk: None,
|
thunk: None,
|
||||||
env: m.env(),
|
env: m.env(),
|
||||||
|
depth: None,
|
||||||
});
|
});
|
||||||
m.inc_call_depth();
|
m.inc_call_depth();
|
||||||
m.push(Value::new(negate));
|
m.push(Value::new(negate));
|
||||||
|
|||||||
@@ -46,6 +46,7 @@ pub fn import<'gc, M: Machine<'gc>>(
|
|||||||
pc: Continuation::PImportFinalize.ip() as usize,
|
pc: Continuation::PImportFinalize.ip() as usize,
|
||||||
thunk: None,
|
thunk: None,
|
||||||
env,
|
env,
|
||||||
|
depth: None,
|
||||||
});
|
});
|
||||||
|
|
||||||
m.set_pending_load(PendingLoad {
|
m.set_pending_load(PendingLoad {
|
||||||
@@ -79,6 +80,7 @@ pub fn import_finalize<'gc, M: Machine<'gc>>(
|
|||||||
pc: ret_pc,
|
pc: ret_pc,
|
||||||
thunk: _,
|
thunk: _,
|
||||||
env,
|
env,
|
||||||
|
depth: None,
|
||||||
}) = m.pop_call_frame()
|
}) = m.pop_call_frame()
|
||||||
else {
|
else {
|
||||||
unreachable!()
|
unreachable!()
|
||||||
@@ -120,6 +122,7 @@ pub fn scoped_import<'gc, M: Machine<'gc>>(
|
|||||||
pc: Continuation::PScopedImportFinalize.ip() as usize,
|
pc: Continuation::PScopedImportFinalize.ip() as usize,
|
||||||
thunk: None,
|
thunk: None,
|
||||||
env,
|
env,
|
||||||
|
depth: None,
|
||||||
});
|
});
|
||||||
|
|
||||||
m.set_pending_load(PendingLoad {
|
m.set_pending_load(PendingLoad {
|
||||||
|
|||||||
Reference in New Issue
Block a user