nk 1.0.0
C++ Numerical Computing Runtime
Loading...
Searching...
No Matches
debug_workspace.hpp
1// include/debug_workspace.hpp
2//
3// DebugWorkspace — unified view of variables visible at a debug pause.
4//
5// Two slots:
6// framePtrs — live pointers to Value storage in the paused VM frame
7// (into regStack_ via chunk.varMap + frame.regBase).
8// Stable while the VM session is alive (regStack_ is
9// pre-allocated once and never reallocates).
10// overlay — variables created in the debug console that have no
11// slot in the static frame (new names, not in varMap).
12//
13// Value copy is tagged-pointer + atomic COW refcount, so `set()` does
14// not data-copy even for large matrices.
15//
16// Write semantics (MATLAB at K>>):
17// set(name, val) → *framePtr = val (if frame var) else overlay[name] = val
18// remove(name) → *framePtr = Value::deleted() (if frame var) and
19// overlay.erase(name) (if present)
20// clearAll() → mark every framePtr as deleted + overlay.clear()
21//
22// After a `clear` in the console, a subsequent `continue` that reads the
23// cleared variable will hit ASSERT_DEF and surface an
24// "Undefined function or variable" runtime error — the MATLAB behaviour.
25//
26#pragma once
27
28#include <nk/value/value.hpp>
29
30#include <string>
31#include <unordered_map>
32#include <unordered_set>
33#include <vector>
34
35namespace nk {
36
37class Engine;
38class VM;
39
40class DebugWorkspace
41{
42public:
43 DebugWorkspace() = default;
44 ~DebugWorkspace() = default;
45
46 DebugWorkspace(const DebugWorkspace &) = delete;
47 DebugWorkspace &operator=(const DebugWorkspace &) = delete;
48
49 // Resolve framePtrs from the VM's current (top) paused frame. Also
50 // stashes the Engine pointer so names() can query host-registered
51 // constants via Engine::isReservedName (keeps them out of the
52 // user-visible snapshot the same way built-ins are hidden).
53 // Call after every save/restore of paused state so pointers match the
54 // live register base. depthFromTop selects which frame to bind: 0 = the
55 // current (deepest) frame, increasing toward the base — the dbup/dbdown
56 // axis. An out-of-range depth leaves the workspace unbound.
57 void bindVMFrame(VM &vm, Engine &engine, size_t depthFromTop = 0);
58
59 // Drop framePtrs. Overlay is preserved across (re)binds.
60 void unbindFrame();
61
62 // Reset to empty (both slots). Call on session end.
63 void reset();
64
65 // ── Operations ───────────────────────────────────────────
66 const Value *get(const std::string &name) const;
67 void set(const std::string &name, const Value &val);
68 void remove(const std::string &name);
69 void clearAll();
70
71 // User-visible names — built-in constants and pseudo-vars (pi, eps,
72 // nargin, …) are filtered out so the snapshot matches MATLAB's `whos`.
73 std::vector<std::string> names() const;
74
75 // All live names, including built-ins and pseudo-vars. Used to inject
76 // frame state into the console eval's workspace so `nargin`, `i` in a
77 // for-loop, etc. resolve correctly inside debug expressions.
78 std::vector<std::string> allNames() const;
79
80 // Is `name` bound to a frame register?
81 bool hasFrameVar(const std::string &name) const
82 {
83 return framePtrs_.count(name) > 0;
84 }
85
86 // Overlay exposure — used as VM per-frame dynVars during `continue`
87 // so console-created names are resolvable by the running script.
88 std::unordered_map<std::string, Value> &overlay() { return overlay_; }
89 const std::unordered_map<std::string, Value> &overlay() const { return overlay_; }
90
91private:
92 std::unordered_map<std::string, Value *> framePtrs_;
93 std::unordered_map<std::string, Value> overlay_;
94
95 // Names the compiler emitted a write for in the paused chunk. Used by
96 // names() so built-ins like `pi` appear only when actually shadowed by
97 // the script, matching MATLAB's `whos` behaviour.
98 std::unordered_set<std::string> assignedInFrame_;
99
100 // Built-in names the user has shadowed via the debug console at runtime
101 // (`pi = 5` at K>>). Sticky across evals until session end.
102 std::unordered_set<std::string> shadowedBuiltins_;
103
104 // Engine pointer captured at bindVMFrame time. Used by names() to ask
105 // Engine::isReservedName() so host-registered constants are hidden
106 // alongside the compile-time built-ins.
107 Engine *engine_ = nullptr;
108
109 // Whether `name` should be filtered out of the user-visible snapshot.
110 // Depends on engine_, so it's a member rather than a free function.
111 bool isHiddenName(const std::string &name) const;
112};
113
114} // namespace nk
Definition vm.hpp:24
Core MATLAB-compatible multidimensional array and scalar value type.
Definition value.hpp:61