mod context; mod control; mod conv; mod eq; mod io; mod list; mod path; pub use context::*; pub use control::*; pub use conv::*; pub use eq::*; use fix_bytecode::Continuation; use fix_error::Error; use fix_runtime::{BytecodeReader, Machine, Step, VmRuntimeCtx}; use gc_arena::Mutation; pub use io::*; pub use list::*; pub use path::*; #[macro_export] macro_rules! slots { { $($ident:ident : $ty:ty);* $(;)? } => { slots! { @acc [ 0 ] $($ident : $ty;)* } }; /* { $($ident:ident : $ty:ty);* $(;)? } => { slots! { @reverse [ $($ident : $ty;)* ] [] } }; { @reverse [ $ident:ident : $ty:ty; $($remain:tt)* ] [ $($acc:tt)* ] } => { slots! { @reverse [ $($remain)* ] [ $ident : $ty; $($acc)* ] } }; { @reverse [] [ $($rev_id:ident : $rev_ty:ty;)* ] } => { slots! { @acc [ 0 ] $($rev_id : $rev_ty;)* } }; */ { @acc [ $($acc:tt)* ] $ident:ident : $ty:ty; $($remain:tt)* } => { let $ident : Slot<$ty> = Slot::new($($acc)*); slots! { @acc [ $($acc)* + 1 ] $($remain)* } }; { @acc [ $($acc:tt)* ] } => {}; } pub fn dispatch_cont<'gc, M: Machine<'gc>>( m: &mut M, ctx: &mut impl VmRuntimeCtx, reader: &mut BytecodeReader<'_>, mc: &Mutation<'gc>, ) -> Step { use Continuation::*; let cont = reader.read_u8(); let Ok(cont) = Continuation::try_from(cont) else { return m.finish_err(Error::eval_error("invalid primop phase")); }; match cont { PAbort => abort(m, ctx, reader, mc), PAll => all_entry(m, reader, mc), PAllCallPred => all_call_pred(m, reader, mc), PAllCheck => all_check(m, reader, mc), PAny => any_entry(m, reader, mc), PAnyCallPred => any_call_pred(m, reader, mc), PAnyCheck => any_check(m, reader, mc), PDeepSeq => deep_seq_force_top(m, reader, mc), PDeepSeqPush => deep_seq_push(m, reader, mc), PDeepSeqLoop => deep_seq_loop(m, reader, mc), PSeq => seq(m, reader, mc), PFilterForceList | PFilterSetupStack | PFilterCallPred | PFilterCheck => { filter::dispatch(m, reader, mc, cont) } PFoldlStrict => foldl_strict_entry(m, reader, mc), PFoldlStrictEmpty => foldl_strict_empty(m, reader, mc), PFoldlStrictCall1 => foldl_strict_call1(m, reader, mc), PFoldlStrictCall2 => foldl_strict_call2(m, reader, mc), PFoldlStrictUpdate => foldl_strict_update(m, reader, mc), ForceResultShallow => force_result_shallow(m, ctx, reader, mc), ForceResultShallowPush => force_result_shallow_push(m, ctx, reader, mc), ForceResultShallowLoop => force_result_shallow_loop(m, reader, mc), ForceResultDeepFinish => force_result_deep_finish(m, ctx, reader, mc), EqStep => eq_step(m, reader, mc), EqForce => eq_force(m, ctx, reader, mc), CallPattern => call_pattern(m, ctx, reader, mc), CallFunctor1 => call_functor_1(m, reader, mc), CallFunctor2 => call_functor_2(m, reader, mc), PImport => import(m, ctx, reader, mc), PImportFinalize => import_finalize(m, ctx, reader), PScopedImport => scoped_import(m, ctx, reader, mc), PScopedImportFinalize => scoped_import_finalize(m, ctx, reader, mc), PPathExists => path_exists(m, ctx, reader, mc), PToPath => to_path(m, ctx, reader, mc), PIsPath => is_path(m, reader, mc), PToString => to_string(m, ctx, reader, mc), PTypeOf => type_of(m, ctx, reader, mc), PHasContext => has_context(m, ctx, reader, mc), PGetContext => get_context(m, ctx, reader, mc), PAppendContext => append_context(m, ctx, reader, mc), PAppendContextLoop => append_context_loop(m, ctx, reader, mc), PAppendContextEntryForced => append_context_entry_forced(m, ctx, reader, mc), PAppendContextOutputsForced => append_context_outputs_forced(m, ctx, reader, mc), PAppendContextOutputElementLoop => append_context_output_element_loop(m, ctx, reader, mc), PAppendContextOutputElementForced => { append_context_output_element_forced(m, ctx, reader, mc) } PUnsafeDiscardStringContext => unsafe_discard_string_context(m, ctx, reader, mc), PUnsafeDiscardOutputDependency => unsafe_discard_output_dependency(m, ctx, reader, mc), phase => todo!("primop phase {phase:?}"), } }