Step -> ControlFlow (use ?)

This commit is contained in:
2026-04-21 09:31:41 +08:00
parent 11b0b8a78e
commit b31c2a4906
11 changed files with 86 additions and 128 deletions
+17 -13
View File
@@ -132,11 +132,13 @@ impl<T: VmContext> VmContextExt for T {
}
#[repr(u8)]
pub(crate) enum Step {
Continue,
pub(crate) enum Break {
Force,
Done,
}
pub(crate) type Step = std::ops::ControlFlow<Break>;
#[derive(Collect)]
#[collect(no_drop)]
pub struct Vm<'gc> {
@@ -273,19 +275,19 @@ impl<'gc> Vm<'gc> {
#[inline(always)]
pub(crate) fn finish_ok(&mut self, val: fix_common::Value) -> Step {
self.result = Some(Ok(val));
Step::Done
Step::Break(Break::Done)
}
#[inline(always)]
pub(crate) fn finish_err(&mut self, err: Box<Error>) -> Step {
self.result = Some(Err(err));
Step::Done
Step::Break(Break::Done)
}
#[inline(always)]
pub(crate) fn finish_type_err(&mut self, expected: NixType, got: NixType) -> Step {
self.result = Some(Err(Error::eval_error(format!("expected {expected}, got {got}"))));
Step::Done
Step::Break(Break::Done)
}
#[inline(always)]
@@ -369,8 +371,10 @@ impl<'gc> Vm<'gc> {
depth: usize,
reader: &mut BytecodeReader<'_>,
mc: &Mutation<'gc>,
) -> Option<Step> {
let thunk = self.peek(depth).as_gc::<Thunk>()?;
) -> Step {
let Some(thunk) = self.peek(depth).as_gc::<Thunk>() else {
return Step::Continue(());
};
let mut state = thunk.borrow_mut(mc);
match *state {
ThunkState::Pending { ip, env, with_env } => {
@@ -386,17 +390,17 @@ impl<'gc> Vm<'gc> {
self.env = env;
self.with_env = with_env;
reader.set_pc(ip);
Some(Step::Continue)
Step::Break(Break::Force)
}
ThunkState::Evaluated(v) => {
drop(state);
self.replace(depth, v.relax());
None
Step::Continue(())
}
ThunkState::Apply { .. } => todo!("force apply"),
ThunkState::Blackhole => {
drop(state);
Some(self.finish_err(Error::eval_error("infinite recursion encountered")))
self.finish_err(Error::eval_error("infinite recursion encountered"))
}
}
}
@@ -582,10 +586,10 @@ impl<'gc> Vm<'gc> {
};
match result {
Step::Continue => {}
Step::Done => {
Step::Continue(()) | Step::Break(Break::Force) => {}
Step::Break(Break::Done) => {
return Action::Done(
self.result.take().expect("StepResult::Done without result"),
self.result.take().expect("Break::Done without result"),
);
}
}