Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions packages/doeff-vm-core/src/continuation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -325,6 +325,19 @@ impl Continuation {
Self::new_captured(cont_id, vec![fiber_id])
}

/// Create a continuation view from stored fiber IDs and consumed state.
/// This is NOT a shared handle — it has an independent consumed flag initialized
/// from the provided value. Used by ProgramDispatch to reconstruct continuations
/// from stored topology data without clone_handle().
pub(crate) fn from_ids(cont_id: ContId, fibers: Vec<FiberId>, consumed: bool) -> Self {
memory_stats::register_continuation();
Self {
cont_id,
fibers,
consumed: Arc::new(AtomicBool::new(consumed)),
}
}

pub fn is_started(&self) -> bool {
!self.fibers.is_empty()
}
Expand Down
40 changes: 23 additions & 17 deletions packages/doeff-vm-core/src/frame.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ use crate::continuation::Continuation;
use crate::do_ctrl::{DoCtrl, InterceptMode};
use crate::driver::PyException;
use crate::effect::DispatchEffect;
use crate::ids::{ContId, Marker, SegmentId, VarId};
use crate::ids::{ContId, FiberId, Marker, SegmentId, VarId};
use crate::ir_stream::IRStreamRef;
use crate::kleisli::KleisliRef;
use crate::py_key::HashedPyKey;
Expand Down Expand Up @@ -148,32 +148,38 @@ impl Clone for DispatchDisplay {
}
}

#[derive(Debug)]
#[derive(Debug, Clone)]
pub struct ProgramDispatch {
pub origin_cont_id: ContId,
pub parent_origin_cont_id: Option<ContId>,
pub handler_segment_id: SegmentId,
pub prompt_segment_id: SegmentId,
pub effect: DispatchEffect,
pub trace: DispatchDisplay,
pub origin: Continuation,
pub handler_continuation: Continuation,
/// Fiber IDs of the captured user continuation (replaces origin: Continuation).
pub origin_fiber_ids: Vec<FiberId>,
/// Fiber IDs of the handler's working continuation (replaces handler_continuation: Continuation).
pub handler_fiber_ids: Vec<FiberId>,
/// ContId of the handler's working continuation (for identity matching).
pub handler_cont_id: ContId,
/// Whether the origin continuation has been consumed (resumed/thrown to).
pub origin_consumed: bool,
/// Whether the handler continuation has been consumed.
pub handler_consumed: bool,
pub original_exception: Option<PyException>,
}

impl Clone for ProgramDispatch {
fn clone(&self) -> Self {
Self {
origin_cont_id: self.origin_cont_id,
parent_origin_cont_id: self.parent_origin_cont_id,
handler_segment_id: self.handler_segment_id,
prompt_segment_id: self.prompt_segment_id,
effect: self.effect.clone(),
trace: self.trace.clone(),
origin: self.origin.clone_handle(),
handler_continuation: self.handler_continuation.clone_handle(),
original_exception: self.original_exception.clone(),
}
impl ProgramDispatch {
/// Reconstruct a Continuation view from stored origin fiber IDs.
/// The returned continuation has an independent consumed flag initialized
/// from origin_consumed — it does NOT share state with the real continuation.
pub fn origin_as_continuation(&self) -> Continuation {
Continuation::from_ids(self.origin_cont_id, self.origin_fiber_ids.clone(), self.origin_consumed)
}

/// Reconstruct a Continuation view from stored handler fiber IDs.
pub fn handler_as_continuation(&self) -> Continuation {
Continuation::from_ids(self.handler_cont_id, self.handler_fiber_ids.clone(), self.handler_consumed)
}
}

Expand Down
11 changes: 6 additions & 5 deletions packages/doeff-vm-core/src/vm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -810,11 +810,12 @@ impl VM {
..
} = frame
{
Self::collect_continuation_parent(&dispatch.origin, &mut parent_rewrites);
Self::collect_continuation_parent(
&dispatch.handler_continuation,
&mut parent_rewrites,
);
if let Some(fiber_id) = dispatch.origin_fiber_ids.last() {
parent_rewrites.insert(*fiber_id);
}
if let Some(fiber_id) = dispatch.handler_fiber_ids.last() {
parent_rewrites.insert(*fiber_id);
}
}
if let Frame::EvalReturn(eval_return) = frame {
Self::collect_eval_return_captured_caller(eval_return, &mut parent_rewrites);
Expand Down
Loading
Loading