pub struct NativeContext<'a> { /* private fields */ }Expand description
The capability surface a handler is given for exactly one slice.
Borrows the running Process and the shared services. All sends route
through LocalSendFacility (so sender-clock ticking and replay
validation are reused verbatim); spawns route through SpawnFacility.
Implementations§
Source§impl<'a> NativeContext<'a>
impl<'a> NativeContext<'a>
Sourcepub fn readiness_facility(&self) -> Option<&dyn ReadinessFacility>
pub fn readiness_facility(&self) -> Option<&dyn ReadinessFacility>
Return the in-slice readiness facility when the scheduler composed it.
None is the Disabled service’s typed absence: handlers can refuse the
operation while still runnable instead of parking without an armed fd.
Sourcepub fn has_messages(&self) -> bool
pub fn has_messages(&self) -> bool
True when there is at least one queued message to drain this slice.
Sourcepub fn set_trap_exit(&mut self, value: bool) -> bool
pub fn set_trap_exit(&mut self, value: bool) -> bool
Enable or disable exit trapping for this native process — the native
equivalent of process_flag(trap_exit, true). Returns the previous
value.
When trapping is enabled, an exit signal from a linked process is
converted into an {'EXIT', source, reason} message and delivered to
this process’s mailbox (drained at the slice boundary by the SAME
shared store-back the bytecode path uses) instead of terminating it —
so a native handler can supervise linked children. This flips the flag
on the underlying Process, the single source of truth the pid-keyed
propagate_exit path consults; it adds no native-specific trap state.
Sourcepub fn recv(&mut self) -> Option<Term>
pub fn recv(&mut self) -> Option<Term>
Remove and return the next mailbox message in arrival order, or None
when the mailbox is empty.
Implemented over the existing Mailbox API (current_message then
remove_current_message) — it adds no new mailbox method. The returned
term references this process’s own heap and is valid for the rest of
the slice.
Sourcepub fn skip_message(&mut self)
pub fn skip_message(&mut self)
Advance the selective-receive save pointer past the current message
without removing it (the Mailbox skip primitive), for handlers that
want to leave a message in place and scan the next one.
Sourcepub fn send(&mut self, target_pid: u64, message: Term)
pub fn send(&mut self, target_pid: u64, message: Term)
Send message to target_pid, routed through the existing
LocalSendFacility.
Ticks this process’s logical clock before delivery and passes the
sender_clock through, exactly like interpreter::opcodes::messaging.
On a replay mismatch the clock tick is rolled back and the error is
recorded for run_native_slice to surface as an exit, so replay stays
deterministic. A self-send lands in the process’s own Executing slot
and is merged into the mailbox at store-back (no special case here).
Sourcepub fn alloc_tuple(&mut self, elements: &[Term]) -> Option<Term>
pub fn alloc_tuple(&mut self, elements: &[Term]) -> Option<Term>
Allocate a tuple of elements on this process’s heap and return the
tuple term, or None when the heap is full.
This is the allocation primitive an
crate::native::actor::ActorMessage encode implementation uses to
build a compound message of immediates/scalars. Every element MUST be
an immediate (small integer, atom, local pid) or a heap term already
rooted on this process’s heap: the native slice performs no garbage
collection, so this allocator neither triggers a GC nor needs to root
its arguments. Raw closures with free variables must NOT be exchanged
this way (the pre-existing ETF closure-encoding limitation documented on
this module); actors exchange immediates/refs/scalars only.
Sourcepub fn alloc_owned_term(&mut self, owned: &OwnedTerm) -> Option<Term>
pub fn alloc_owned_term(&mut self, owned: &OwnedTerm) -> Option<Term>
Deep-copy a self-contained crate::ets::OwnedTerm graph onto this
process’s heap and return the rooted term, or None when the heap is
full or the copy fails.
This is the delivery primitive a dynamic crate::native::actor::Actor
uses when its Call/Reply/Cast payload is carried as an opaque,
already-detached term graph (e.g. a host value marshalled outside a slice)
rather than rebuilt element by element with Self::alloc_tuple. It
reuses the same copy_term_to_heap deep-copier ETS delivery uses, so the
resulting term is rooted on this heap and valid for the rest of the slice;
the native slice performs no GC, so no rooting of the argument is required.
Sourcepub fn spawn_native(
&mut self,
factory: NativeHandlerFactory,
link_to: Option<u64>,
) -> Result<u64, SpawnError>
pub fn spawn_native( &mut self, factory: NativeHandlerFactory, link_to: Option<u64>, ) -> Result<u64, SpawnError>
Spawn a native child from factory, optionally linking it to this
process, delegating to the same SpawnFacility the scheduler uses.
Sourcepub fn schedule(&mut self, delay: Duration, message: Term) -> Option<TimerRef>
pub fn schedule(&mut self, delay: Duration, message: Term) -> Option<TimerRef>
Schedule message to be delivered to this process’s mailbox after
delay (a self-tick). Returns the timer reference, or None when the
context was built without a timer wheel.
The timer is a Deliver timer: when it fires the scheduler pushes
message into this process’s mailbox (via the same Executing-slot-safe
path that send/IO delivery use) and wakes it, so a handler that
returns NativeOutcome::Wait is rescheduled when the tick lands.
Sourcepub fn send_after(
&mut self,
delay: Duration,
target_pid: u64,
message: Term,
) -> Option<TimerRef>
pub fn send_after( &mut self, delay: Duration, target_pid: u64, message: Term, ) -> Option<TimerRef>
Schedule message to be delivered to target_pid’s mailbox after
delay. Returns the timer reference, or None when the context was
built without a timer wheel.
§Replay determinism
Unlike Self::send, scheduling a timer is NOT itself a replay-recorded
or replay-validated event — and deliberately so, to stay identical to the
erlang:send_after/start_timer BIF path (ProcessContext::schedule_timer),
which also does not record the scheduling call. The replayed event is the
timer expiry: under replay tick_replay_timers discards the live wheel’s
wall-clock fires and instead replays the recorded TimerExpiry set through
expire_timers, so the delivered message and its ordering come from the log,
not from wall-clock timing. The scheduled entry left in the live wheel is
inert under replay (its real fire is discarded). Native timers are therefore
exactly as replay-deterministic as BIF timers; what they do NOT add is the
per-call determinism validation that send performs, because timer
scheduling has no recorded counterpart to validate against.
Sourcepub fn cancel_timer(&mut self, reference: TimerRef) -> Option<Duration>
pub fn cancel_timer(&mut self, reference: TimerRef) -> Option<Duration>
Cancel a pending timer scheduled through this context, returning its
remaining duration. None when there is no timer wheel or the timer
already fired or was already cancelled.
Sourcepub fn start_async(&mut self, mfa: NativeKey, args: &[Term]) -> Result<(), Term>
pub fn start_async(&mut self, mfa: NativeKey, args: &[Term]) -> Result<(), Term>
Start host async work through the SAME async-NIF seam the bytecode path uses, then park this process pending completion (WR-7).
mfa names a host async native (the key the host registered with its
WasmAsyncNifFacility); args are immediate/heap terms rooted on this
process’s heap. The facility starts the host operation (e.g. a browser
fetch/OPFS Promise) bound to this process’s pid and arranges a later
crate::scheduler::WasmScheduler::complete_async callback. The handler
MUST return NativeOutcome::Wait after a successful start_async: the
completion is delivered into this process’s mailbox on a later turn (the
scheduler converts the pid-keyed completion into a {ok, Value} /
{error, Reason} message), and the handler reads it with
NativeContext::recv when it next runs — exactly the wake-on-message
resume model call_async uses.
Returns Ok(()) when the host op was started (now park), or Err(reason)
when no facility is installed or the host rejected synchronously (in which
case the process is NOT parked and the handler should handle reason).
§Errors
Returns the host’s error term, or an undef atom when no
WasmAsyncNifFacility is installed.