document trying mechanism

This commit is contained in:
2026-05-03 22:05:54 +08:00
parent 7401f1ba5e
commit 88a205f419
8 changed files with 56 additions and 28 deletions
+31 -3
View File
@@ -420,17 +420,45 @@ impl<'gc> Vm<'gc> {
.expect("forced")
}
/// Force the top `T::WIDTH` stack slots and return them as `T`.
///
/// If any slot holds a pending thunk, this method pushes a call frame
/// whose resume PC is the **start of the current instruction**
/// (`reader.inst_start_pc()`), enters the thunk, and returns
/// `Break::Force`. When the thunk eventually returns, the VM will
/// **re-execute the entire opcode handler from the beginning**.
///
/// # Invariants
///
/// * **Do not call this method more than once in a single handler.**
/// If you need to force multiple values, use a tuple type such as
/// `(StrictValue, StrictValue)` so they are forced and popped in one
/// atomic operation. Calling `force_and_retry` twice (or more)
/// means the handler will be re-run from the top after each retry;
/// any stack modifications between the two calls would be duplicated
/// and corrupt the stack layout.
///
/// * The caller must ensure that the stack layout at the point of
/// invocation is **identical** every time the handler is re-entered.
/// In practice this means no pushes, pops, or local mutations may
/// happen before the call, and the call must be the first thing
/// that consumes the instruction's operand values.
///
/// * The return value must be propagated with `?` so that
/// `Break::Force` correctly unwinds to the dispatch loop.
#[inline(always)]
pub(crate) fn try_force<T: Forced<'gc>>(
pub(crate) fn force_and_retry<T: Forced<'gc>>(
&mut self,
reader: &mut BytecodeReader<'_>,
mc: &Mutation<'gc>,
) -> std::ops::ControlFlow<Break, T> {
self.try_force_to_pc(reader, mc, reader.inst_start_pc())
self.force_and_retry_pc(reader, mc, reader.inst_start_pc())
}
/// Same as [`force_and_retry`](Self::force_and_retry) but allows
/// specifying a custom resume PC.
#[inline(always)]
pub(crate) fn try_force_to_pc<T: Forced<'gc>>(
pub(crate) fn force_and_retry_pc<T: Forced<'gc>>(
&mut self,
reader: &mut BytecodeReader<'_>,
mc: &Mutation<'gc>,