nk 1.0.0
C++ Numerical Computing Runtime
Loading...
Searching...
No Matches
callback_builtin.hpp
1// include/callback_builtin.hpp
2#pragma once
3
4#include <nk/value/value.hpp>
5
6#include <cstddef>
7#include <functional>
8#include <memory>
9#include <vector>
10
11// State-machine callbacks (vm_callbacks_plan.md).
12//
13// A higher-order builtin (cellfun / arrayfun / …) that calls user code in a
14// loop normally drives that loop on the C++ stack and runs each callback to
15// completion via Engine::callFunctionHandleMulti (the re-entrant callReentrant
16// path). A breakpoint inside such a callback therefore can fire but cannot
17// suspend — the pause cannot unwind through the builtin's C++ for-loop.
18//
19// The continuation mechanism removes that C++ loop: the builtin is expressed as
20// a resumable state machine that, between callbacks, RETURNS control to the VM
21// dispatch loop. Each callback then runs as an ordinary VM frame (pushed on
22// frames_), which is fully pausable — the same property in-bytecode calls enjoy.
23// No fiber / separate stack / Asyncify needed; works identically on every
24// preset including WASM.
25
26namespace nk {
27
28class VM;
29class Engine;
30
31// A suspended native computation driving user-code callbacks as VM frames.
32// Owned via shared_ptr: it lives on the awaited frame (CallFrame::cont) and is
33// handed back to itself on each resume so it can re-attach to the next frame.
35{
36 virtual ~VmContinuation() = default;
37
38 // Advance the state machine by one step.
39 // prevResult — the value the just-returned callback frame produced, or
40 // nullptr on the very first step (before any callback ran).
41 // self — this continuation (shared ownership) so step() can pass it
42 // to VM::pushCallbackFrame when scheduling the next callback.
43 // Returns true → a new callback frame was pushed; the computation is
44 // suspended and will resume when that frame returns.
45 // Returns false → finished; the final result has already been written to the
46 // captured destination (no frame pushed).
47 virtual bool step(VM &vm, Value *prevResult,
48 const std::shared_ptr<VmContinuation> &self) = 0;
49};
50
51// A higher-order builtin that can run its callbacks on the VM. Registered on the
52// Engine under the builtin's name (alongside its ordinary synchronous external
53// registration). The VM consults it at the call site BEFORE the synchronous
54// path: tryStart returns a continuation to drive, or nullptr to fall back to the
55// ordinary builtin (e.g. when the function handle is itself a builtin — no user
56// code to step through — or the argument form isn't one the state machine
57// covers). `dest` is where the single output must be written: a stable pointer
58// into the VM register stack, valid for the whole computation.
60{
61 virtual ~CallbackBuiltin() = default;
62 virtual std::shared_ptr<VmContinuation> tryStart(Span<const Value> args, std::size_t nargout,
63 Value *dest, Engine &eng) = 0;
64};
65
66// Ready-made continuation for the common "apply a handle to each of N items,
67// collect the results, pack one output" shape shared by cellfun / arrayfun /
68// structfun / feval / splitapply / … A CallbackBuiltin builds one of these in
69// tryStart, supplying:
70// handle — the user-code function handle (plain or {handle, captures…}),
71// n — number of callbacks to run,
72// makeArgs — per-index callback arguments,
73// pack — build the single output Value from the collected results,
74// dest — stable destination pointer (into the VM register stack).
75// step() is defined in vm.cpp (it needs VM::pushCallbackFrame). A single-shot
76// builtin (feval) is just n == 1.
78{
79 Value handle;
80 std::size_t n = 0;
81 std::size_t i = 0;
82 Value *dest = nullptr;
83 std::function<std::vector<Value>(std::size_t)> makeArgs;
84 std::function<Value(std::vector<Value> &)> pack;
85 std::vector<Value> results;
86
87 bool step(VM &vm, Value *prevResult, const std::shared_ptr<VmContinuation> &self) override;
88};
89
90} // namespace nk
Definition vm.hpp:24
Core MATLAB-compatible multidimensional array and scalar value type.
Definition value.hpp:61