optimize: remove {StepResult,TailResult}::ForceThunk
This commit is contained in:
+37
-77
@@ -131,21 +131,12 @@ impl<T: VmContext> VmContextExt for T {
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) enum StepResult<'gc> {
|
||||
#[repr(u8)]
|
||||
pub(crate) enum StepResult {
|
||||
Continue,
|
||||
ForceThunk(ForceInfo<'gc>),
|
||||
Done,
|
||||
}
|
||||
|
||||
pub(crate) struct ForceInfo<'gc> {
|
||||
pub(crate) thunk: Gc<'gc, Thunk<'gc>>,
|
||||
pub(crate) stack_depth: usize,
|
||||
pub(crate) inst_start_pc: usize,
|
||||
pub(crate) ip: usize,
|
||||
pub(crate) env: GcEnv<'gc>,
|
||||
pub(crate) with_env: Option<GcWithEnv<'gc>>,
|
||||
}
|
||||
|
||||
#[derive(Collect)]
|
||||
#[collect(no_drop)]
|
||||
pub struct Vm<'gc> {
|
||||
@@ -279,19 +270,19 @@ impl<'gc> Vm<'gc> {
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub(crate) fn finish_ok(&mut self, val: fix_common::Value) -> StepResult<'gc> {
|
||||
pub(crate) fn finish_ok(&mut self, val: fix_common::Value) -> StepResult {
|
||||
self.result = Some(Ok(val));
|
||||
StepResult::Done
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub(crate) fn finish_err(&mut self, err: Box<Error>) -> StepResult<'gc> {
|
||||
pub(crate) fn finish_err(&mut self, err: Box<Error>) -> StepResult {
|
||||
self.result = Some(Err(err));
|
||||
StepResult::Done
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub(crate) fn finish_vm_err(&mut self, err: VmError) -> StepResult<'gc> {
|
||||
pub(crate) fn finish_vm_err(&mut self, err: VmError) -> StepResult {
|
||||
self.finish_err(err.into_error())
|
||||
}
|
||||
|
||||
@@ -338,65 +329,42 @@ impl<'gc> Vm<'gc> {
|
||||
pub(crate) fn try_force(
|
||||
&mut self,
|
||||
depth: usize,
|
||||
inst_start_pc: usize,
|
||||
reader: &mut BytecodeReader<'_>,
|
||||
mc: &Mutation<'gc>,
|
||||
) -> StepResult<'gc> {
|
||||
) -> Option<StepResult> {
|
||||
let val = self.peek_stack(depth);
|
||||
if let Some(thunk) = val.as_gc::<Thunk>() {
|
||||
let mut state = thunk.borrow_mut(mc);
|
||||
match *state {
|
||||
ThunkState::Pending { ip, env, with_env } => {
|
||||
*state = ThunkState::Blackhole;
|
||||
drop(state);
|
||||
StepResult::ForceThunk(ForceInfo {
|
||||
thunk,
|
||||
stack_depth: depth,
|
||||
inst_start_pc,
|
||||
ip,
|
||||
env,
|
||||
with_env,
|
||||
})
|
||||
}
|
||||
ThunkState::Evaluated(v) => {
|
||||
self.replace_stack(depth, v.relax());
|
||||
StepResult::Continue
|
||||
}
|
||||
ThunkState::Apply { .. } => todo!("force apply"),
|
||||
ThunkState::Blackhole => {
|
||||
self.finish_err(Error::eval_error("infinite recursion encountered"))
|
||||
}
|
||||
let Some(thunk) = val.as_gc::<Thunk>() else {
|
||||
return None;
|
||||
};
|
||||
let mut state = thunk.borrow_mut(mc);
|
||||
match *state {
|
||||
ThunkState::Pending { ip, env, with_env } => {
|
||||
*state = ThunkState::Blackhole;
|
||||
drop(state);
|
||||
self.call_stack.push(CallFrame {
|
||||
thunk: Some(thunk),
|
||||
stack_depth: depth,
|
||||
pc: reader.inst_start_pc(),
|
||||
env: self.env,
|
||||
with_env: self.with_env,
|
||||
});
|
||||
self.env = env;
|
||||
self.with_env = with_env;
|
||||
reader.set_pc(ip);
|
||||
Some(StepResult::Continue)
|
||||
}
|
||||
ThunkState::Evaluated(v) => {
|
||||
drop(state);
|
||||
self.replace_stack(depth, v.relax());
|
||||
None
|
||||
}
|
||||
ThunkState::Apply { .. } => todo!("force apply"),
|
||||
ThunkState::Blackhole => {
|
||||
drop(state);
|
||||
Some(self.finish_err(Error::eval_error("infinite recursion encountered")))
|
||||
}
|
||||
} else {
|
||||
StepResult::Continue
|
||||
}
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub(crate) fn try_force_resolved(
|
||||
&mut self,
|
||||
depth: usize,
|
||||
inst_start_pc: usize,
|
||||
mc: &Mutation<'gc>,
|
||||
) -> Option<StepResult<'gc>> {
|
||||
match self.try_force(depth, inst_start_pc, mc) {
|
||||
StepResult::Continue => None,
|
||||
other => Some(other),
|
||||
}
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub(crate) fn apply_force_thunk(&mut self, info: ForceInfo<'gc>) -> usize {
|
||||
self.call_stack.push(CallFrame {
|
||||
thunk: Some(info.thunk),
|
||||
stack_depth: info.stack_depth,
|
||||
pc: info.inst_start_pc,
|
||||
env: self.env,
|
||||
with_env: self.with_env,
|
||||
});
|
||||
self.env = info.env;
|
||||
self.with_env = info.with_env;
|
||||
info.ip
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
@@ -476,10 +444,6 @@ impl<'gc> Vm<'gc> {
|
||||
TailResult::YieldFuel(new_pc) => Action::Continue {
|
||||
pc: new_pc as usize,
|
||||
},
|
||||
TailResult::ForceThunk(info) => {
|
||||
let new_pc = self.apply_force_thunk(info);
|
||||
Action::Continue { pc: new_pc }
|
||||
}
|
||||
TailResult::Done => {
|
||||
Action::Done(self.result.take().expect("TailResult::Done without result"))
|
||||
}
|
||||
@@ -552,7 +516,7 @@ impl<'gc> Vm<'gc> {
|
||||
OpLeq => self.op_leq(ctx, &mut reader, mc),
|
||||
OpGeq => self.op_geq(ctx, &mut reader, mc),
|
||||
OpConcat => self.op_concat(&mut reader, mc),
|
||||
OpUpdate => self.op_update(mc, reader.inst_start_pc()),
|
||||
OpUpdate => self.op_update(&mut reader, mc),
|
||||
|
||||
OpNeg => self.op_neg(),
|
||||
OpNot => self.op_not(),
|
||||
@@ -583,10 +547,6 @@ impl<'gc> Vm<'gc> {
|
||||
|
||||
match result {
|
||||
StepResult::Continue => {}
|
||||
StepResult::ForceThunk(info) => {
|
||||
let new_pc = self.apply_force_thunk(info);
|
||||
reader.set_pc(new_pc);
|
||||
}
|
||||
StepResult::Done => {
|
||||
return Action::Done(
|
||||
self.result.take().expect("StepResult::Done without result"),
|
||||
|
||||
Reference in New Issue
Block a user