nk
1.0.0
C++ Numerical Computing Runtime
Toggle main menu visibility
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
26
namespace
nk {
27
28
class
VM
;
29
class
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.
34
struct
VmContinuation
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.
59
struct
CallbackBuiltin
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.
77
struct
LoopContinuation
:
VmContinuation
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
nk::Engine
Definition
engine.hpp:32
nk::Span
Definition
span.hpp:11
nk::VM
Definition
vm.hpp:24
nk::Value
Core MATLAB-compatible multidimensional array and scalar value type.
Definition
value.hpp:61
nk::CallbackBuiltin
Definition
callback_builtin.hpp:60
nk::LoopContinuation
Definition
callback_builtin.hpp:78
nk::VmContinuation
Definition
callback_builtin.hpp:35
src
core
include
nk
core
callback_builtin.hpp
Generated by
1.17.0