numbl 0.2.0 → 0.3.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (127) hide show
  1. package/binding.gyp +24 -36
  2. package/dist-cli/cli.js +16096 -18209
  3. package/dist-lib/graphics/types.d.ts +22 -0
  4. package/dist-lib/lib.d.ts +1 -0
  5. package/dist-lib/lib.js +61324 -62782
  6. package/dist-lib/numbl-core/executeCode.d.ts +11 -21
  7. package/dist-lib/numbl-core/executors/cJit/builtins.d.ts +30 -0
  8. package/dist-lib/numbl-core/executors/cJit/chainCodegen.d.ts +59 -0
  9. package/dist-lib/numbl-core/executors/cJit/chainExecutor.d.ts +27 -0
  10. package/dist-lib/numbl-core/executors/cJit/chainPass.d.ts +42 -0
  11. package/dist-lib/numbl-core/executors/cJit/codegen.d.ts +44 -0
  12. package/dist-lib/numbl-core/executors/cJit/compile.d.ts +45 -0
  13. package/dist-lib/numbl-core/executors/cJit/elemwiseCodegen.d.ts +23 -0
  14. package/dist-lib/numbl-core/executors/cJit/elemwiseStructural.d.ts +33 -0
  15. package/dist-lib/numbl-core/executors/cJit/fuseAnalyze.d.ts +39 -0
  16. package/dist-lib/numbl-core/executors/cJit/fuseCodegen.d.ts +16 -0
  17. package/dist-lib/numbl-core/executors/cJit/fuseExecutor.d.ts +28 -0
  18. package/dist-lib/numbl-core/executors/cJit/loopExecutor.d.ts +32 -0
  19. package/dist-lib/numbl-core/executors/cJit/register.d.ts +10 -0
  20. package/dist-lib/numbl-core/executors/cJit/whitelist.d.ts +15 -0
  21. package/dist-lib/numbl-core/executors/cache.d.ts +26 -0
  22. package/dist-lib/numbl-core/executors/context.d.ts +76 -0
  23. package/dist-lib/numbl-core/executors/index.d.ts +17 -0
  24. package/dist-lib/numbl-core/executors/jsJit/callExecutor.d.ts +25 -0
  25. package/dist-lib/numbl-core/{jit/js → executors/jsJit/codegen}/jitCodegen.d.ts +2 -2
  26. package/dist-lib/numbl-core/{jit/js → executors/jsJit/codegen}/jitCodegenHoist.d.ts +1 -1
  27. package/dist-lib/numbl-core/executors/jsJit/codegen/jsMultiReduction.d.ts +67 -0
  28. package/dist-lib/numbl-core/executors/jsJit/helpers/alloc.d.ts +12 -0
  29. package/dist-lib/numbl-core/{jit/js → executors/jsJit/helpers}/jitHelpers.d.ts +2 -2
  30. package/dist-lib/numbl-core/{jit/js → executors/jsJit/helpers}/jitHelpersComplex.d.ts +1 -1
  31. package/dist-lib/numbl-core/executors/jsJit/helpers/jitHelpersIndex.d.ts +33 -0
  32. package/dist-lib/numbl-core/{jit/js → executors/jsJit/helpers}/jitHelpersTensor.d.ts +7 -7
  33. package/dist-lib/numbl-core/executors/jsJit/jitCall.d.ts +59 -0
  34. package/dist-lib/numbl-core/executors/jsJit/jitLoop.d.ts +53 -0
  35. package/dist-lib/numbl-core/executors/jsJit/jitTopLevel.d.ts +44 -0
  36. package/dist-lib/numbl-core/executors/jsJit/loopExecutor.d.ts +15 -0
  37. package/dist-lib/numbl-core/{jit/jitLoopAnalysis.d.ts → executors/jsJit/lower/blockAnalysis.d.ts} +5 -5
  38. package/dist-lib/numbl-core/{jit → executors/jsJit/lower}/jitBailSafety.d.ts +1 -1
  39. package/dist-lib/numbl-core/{jit → executors/jsJit/lower}/jitLower.d.ts +18 -4
  40. package/dist-lib/numbl-core/{jit → executors/jsJit/lower}/jitLowerExpr.d.ts +11 -2
  41. package/dist-lib/numbl-core/{jit → executors/jsJit/lower}/jitLowerStmt.d.ts +2 -2
  42. package/dist-lib/numbl-core/{jit → executors/jsJit/lower}/jitLowerTypes.d.ts +2 -2
  43. package/dist-lib/numbl-core/{jit → executors/jsJit/lower}/scalarEmit.d.ts +2 -2
  44. package/dist-lib/numbl-core/executors/jsJit/shared.d.ts +120 -0
  45. package/dist-lib/numbl-core/executors/jsJit/topLevelExecutor.d.ts +17 -0
  46. package/dist-lib/numbl-core/executors/lowering.d.ts +166 -0
  47. package/dist-lib/numbl-core/executors/plugins.d.ts +39 -0
  48. package/dist-lib/numbl-core/executors/registry.d.ts +148 -0
  49. package/dist-lib/numbl-core/executors/types.d.ts +103 -0
  50. package/dist-lib/numbl-core/fileIOAdapter.d.ts +2 -0
  51. package/dist-lib/numbl-core/functionResolve.d.ts +7 -0
  52. package/dist-lib/numbl-core/helpers/check-helpers.d.ts +4 -5
  53. package/dist-lib/numbl-core/helpers/linsolve.d.ts +2 -3
  54. package/dist-lib/numbl-core/helpers/prng.d.ts +1 -2
  55. package/dist-lib/numbl-core/interpreter/builtins/datetime.d.ts +2 -1
  56. package/dist-lib/numbl-core/interpreter/builtins/misc.d.ts +4 -1
  57. package/dist-lib/numbl-core/interpreter/builtins/types.d.ts +4 -91
  58. package/dist-lib/numbl-core/interpreter/interpreter.d.ts +34 -44
  59. package/dist-lib/numbl-core/interpreter/interpreterSpecialBuiltins.d.ts +6 -3
  60. package/dist-lib/numbl-core/interpreter/types.d.ts +27 -12
  61. package/dist-lib/numbl-core/{jit/jitTypes.d.ts → jitTypes.d.ts} +15 -1
  62. package/dist-lib/numbl-core/jsUserFunctions.d.ts +8 -0
  63. package/dist-lib/numbl-core/lowering/loweringContext.d.ts +24 -0
  64. package/dist-lib/numbl-core/native/lapack-bridge.d.ts +3 -3
  65. package/dist-lib/numbl-core/parser/types.d.ts +20 -0
  66. package/dist-lib/numbl-core/runtime/constructors.d.ts +6 -6
  67. package/dist-lib/numbl-core/runtime/cow.d.ts +33 -0
  68. package/dist-lib/numbl-core/runtime/index.d.ts +3 -2
  69. package/dist-lib/numbl-core/runtime/indexing.d.ts +6 -1
  70. package/dist-lib/numbl-core/runtime/plotBuiltinDispatch.d.ts +86 -0
  71. package/dist-lib/numbl-core/runtime/plotUtils.d.ts +17 -2
  72. package/dist-lib/numbl-core/runtime/refcount.d.ts +85 -0
  73. package/dist-lib/numbl-core/runtime/runtime.d.ts +27 -66
  74. package/dist-lib/numbl-core/runtime/runtimeDispatch.d.ts +2 -2
  75. package/dist-lib/numbl-core/runtime/runtimeIndexing.d.ts +2 -2
  76. package/dist-lib/numbl-core/runtime/runtimeMemberAccess.d.ts +1 -1
  77. package/dist-lib/numbl-core/runtime/runtimePlot.d.ts +1 -0
  78. package/dist-lib/numbl-core/runtime/struct-access.d.ts +2 -1
  79. package/dist-lib/numbl-core/runtime/types.d.ts +104 -62
  80. package/dist-lib/numbl-core/runtime/utils.d.ts +2 -8
  81. package/dist-lib/numbl-core/version.d.ts +1 -1
  82. package/dist-plot-viewer/assets/index-COAM8o1E.js +4426 -0
  83. package/dist-plot-viewer/index.html +1 -1
  84. package/native/lapack_linsolve.cpp +1 -1
  85. package/native/numbl_addon.cpp +9 -0
  86. package/native/numbl_addon_common.h +2 -2
  87. package/native/ops/comparison.c +1 -1
  88. package/package.json +3 -8
  89. package/dist-lib/numbl-core/jit/c/abi.d.ts +0 -90
  90. package/dist-lib/numbl-core/jit/c/assemble.d.ts +0 -56
  91. package/dist-lib/numbl-core/jit/c/classify.d.ts +0 -70
  92. package/dist-lib/numbl-core/jit/c/compile.d.ts +0 -37
  93. package/dist-lib/numbl-core/jit/c/context.d.ts +0 -152
  94. package/dist-lib/numbl-core/jit/c/emit/assign.d.ts +0 -20
  95. package/dist-lib/numbl-core/jit/c/emit/complexScalar.d.ts +0 -18
  96. package/dist-lib/numbl-core/jit/c/emit/fused.d.ts +0 -42
  97. package/dist-lib/numbl-core/jit/c/emit/helpers.d.ts +0 -40
  98. package/dist-lib/numbl-core/jit/c/emit/index.d.ts +0 -14
  99. package/dist-lib/numbl-core/jit/c/emit/scalar.d.ts +0 -23
  100. package/dist-lib/numbl-core/jit/c/emit/stmt.d.ts +0 -25
  101. package/dist-lib/numbl-core/jit/c/emit/tensor.d.ts +0 -127
  102. package/dist-lib/numbl-core/jit/c/emit/userCall.d.ts +0 -58
  103. package/dist-lib/numbl-core/jit/c/epilogue.d.ts +0 -26
  104. package/dist-lib/numbl-core/jit/c/feasibility.d.ts +0 -44
  105. package/dist-lib/numbl-core/jit/c/hybrid.d.ts +0 -42
  106. package/dist-lib/numbl-core/jit/c/install.d.ts +0 -15
  107. package/dist-lib/numbl-core/jit/c/parityError.d.ts +0 -26
  108. package/dist-lib/numbl-core/jit/c/prelude.d.ts +0 -37
  109. package/dist-lib/numbl-core/jit/c/registry.d.ts +0 -51
  110. package/dist-lib/numbl-core/jit/c/visit.d.ts +0 -63
  111. package/dist-lib/numbl-core/jit/e1/install.d.ts +0 -13
  112. package/dist-lib/numbl-core/jit/e1/kernelEmit.d.ts +0 -54
  113. package/dist-lib/numbl-core/jit/e1/openmpFlag.d.ts +0 -13
  114. package/dist-lib/numbl-core/jit/e1/scalarFnKernel.d.ts +0 -44
  115. package/dist-lib/numbl-core/jit/fusedChainHelpers.d.ts +0 -65
  116. package/dist-lib/numbl-core/jit/fusedScalarEmit.d.ts +0 -61
  117. package/dist-lib/numbl-core/jit/fusion.d.ts +0 -71
  118. package/dist-lib/numbl-core/jit/fusionOps.d.ts +0 -25
  119. package/dist-lib/numbl-core/jit/index.d.ts +0 -7
  120. package/dist-lib/numbl-core/jit/jitLoop.d.ts +0 -25
  121. package/dist-lib/numbl-core/jit/jitTopLevel.d.ts +0 -22
  122. package/dist-lib/numbl-core/jit/js/jitHelpersIndex.d.ts +0 -33
  123. package/dist-lib/numbl-core/jit/js/jsFusedCodegen.d.ts +0 -17
  124. package/dist-lib/numbl-core/runtime/alloc.d.ts +0 -23
  125. package/dist-plot-viewer/assets/index-GiUNnMQg.js +0 -4426
  126. package/native/jit_runtime/jit_runtime.c +0 -261
  127. package/native/jit_runtime/jit_runtime.h +0 -204
@@ -9,18 +9,17 @@
9
9
  * Both the native LAPACK addon and the ts-lapack TypeScript fallback are
10
10
  * supported; the native addon is preferred when available.
11
11
  */
12
- import { FloatXArrayType } from "../runtime/types.js";
13
12
  /**
14
13
  * Dispatch linsolve to the native addon (preferred) or ts-lapack fallback.
15
14
  * Returns null only when neither bridge exposes `linsolve` (should not happen
16
15
  * in practice since ts-lapack always has it).
17
16
  */
18
- export declare function linsolveLapack(A: FloatXArrayType, m: number, n: number, B: FloatXArrayType, nrhs: number): Float64Array | null;
17
+ export declare function linsolveLapack(A: Float64Array, m: number, n: number, B: Float64Array, nrhs: number): Float64Array | null;
19
18
  /**
20
19
  * Dispatch complex linsolve to the native addon (preferred) or ts-lapack fallback.
21
20
  * The ts-lapack fallback throws — native addon is required for complex linsolve.
22
21
  */
23
- export declare function linsolveComplexLapack(ARe: FloatXArrayType, AIm: FloatXArrayType, m: number, n: number, BRe: FloatXArrayType, BIm: FloatXArrayType, nrhs: number): {
22
+ export declare function linsolveComplexLapack(ARe: Float64Array, AIm: Float64Array, m: number, n: number, BRe: Float64Array, BIm: Float64Array, nrhs: number): {
24
23
  re: Float64Array;
25
24
  im: Float64Array;
26
25
  };
@@ -2,7 +2,6 @@
2
2
  * Seedable PRNG (xoshiro128**) for random number generation
3
3
  */
4
4
  import { RuntimeValue } from "../runtime/index.js";
5
- import { type FloatXArrayType } from "../runtime/types.js";
6
5
  export declare function setRngShuffle(): void;
7
6
  export declare function setRngSeed(seed: number): void;
8
7
  export declare function seedRng(seed: number): void;
@@ -10,7 +9,7 @@ export declare function seedRng(seed: number): void;
10
9
  export declare function rngRandom(): number;
11
10
  export declare function boxMullerRandom(): number;
12
11
  /** Fill a typed array with normal random values (bulk polar method) */
13
- export declare function fillRandn(data: FloatXArrayType): void;
12
+ export declare function fillRandn(data: Float64Array): void;
14
13
  /** Return the current RNG state as a struct {Type, Seed, State} */
15
14
  export declare function getRngStateStruct(): RuntimeValue;
16
15
  /** Restore RNG state from a struct previously returned by rng() */
@@ -27,7 +27,8 @@
27
27
  * `seconds(d)` returns the numeric seconds of a duration, or wraps a
28
28
  * number as a duration.
29
29
  */
30
- import type { RuntimeValue, RuntimeClassInstance } from "../../runtime/types.js";
30
+ import type { RuntimeValue } from "../../runtime/types.js";
31
+ import { RuntimeClassInstance } from "../../runtime/types.js";
31
32
  export declare function makeDatetime(year: number, month: number, day: number, hour: number, minute: number, second: number): RuntimeClassInstance;
32
33
  export declare function makeDuration(totalSeconds: number): RuntimeClassInstance;
33
34
  /**
@@ -1,4 +1,7 @@
1
1
  import type { RuntimeValue } from "../../runtime/types.js";
2
- /** Clear all appdata — called at the start of each executeCode to isolate runs. */
2
+ /** Clear all appdata — called at the start of each executeCode to isolate
3
+ * runs. Decrefs every stored value so the previous run's containers can
4
+ * hit rc=0 cleanly; if the previous runtime is gone (test harness), we
5
+ * just drop the JS references and let GC reclaim them. */
3
6
  export declare function resetAppdataStore(): void;
4
7
  export declare function convertJsonValue(val: unknown): RuntimeValue;
@@ -1,9 +1,9 @@
1
1
  /**
2
2
  * IBuiltin interface, registry, and shared helpers for interpreter builtins.
3
3
  */
4
- import type { RuntimeValue, RuntimeTensor, RuntimeComplexNumber } from "../../runtime/types.js";
5
- import { FloatXArray } from "../../runtime/types.js";
6
- import { type JitType } from "../../jit/jitTypes.js";
4
+ import type { RuntimeValue } from "../../runtime/types.js";
5
+ import { RuntimeTensor, RuntimeComplexNumber } from "../../runtime/types.js";
6
+ import { type JitType } from "../../jitTypes.js";
7
7
  export interface IBuiltinResolution {
8
8
  outputTypes: JitType[];
9
9
  apply: (args: RuntimeValue[], nargout: number) => RuntimeValue | RuntimeValue[];
@@ -19,49 +19,6 @@ export interface IBuiltin {
19
19
  resolve: (argTypes: JitType[], nargout: number) => IBuiltinResolution | null;
20
20
  /** Optional fast-path JS code emission for JIT. Return null to fall back to $h.ib_<name>. */
21
21
  jitEmit?: (argCode: string[], argTypes: JitType[], getDest?: () => string) => string | null;
22
- /**
23
- * Optional fast-path C code emission for the C-JIT. Return null if the
24
- * builtin can't be emitted as a C expression for the given arg types
25
- * — the C-JIT will bail to JS-JIT for this call site. Covers the
26
- * scalar-argument case only (tensor-argument emission is handled by
27
- * separate tensor-op dispatch in assemble.ts / emit/fused.ts).
28
- */
29
- jitEmitC?: (argCode: string[], argTypes: JitType[]) => string | null;
30
- /**
31
- * Optional C-JIT tensor-op dispatch metadata. When a field is present,
32
- * both the C feasibility check and C codegen read it directly —
33
- * adding a new tensor-unary / tensor-binary / tensor-reduction builtin
34
- * is one edit here (plus the matching native-side enum or C function).
35
- * Previously these were three parallel hardcoded tables (one in
36
- * feasibility.ts, two in context.ts) that could silently drift
37
- * from the native-side opcode enums. Centralizing on the IBuiltin
38
- * registration removes that drift risk.
39
- */
40
- jitCapabilities?: JitCapabilities;
41
- }
42
- /** Per-builtin C-JIT tensor-op dispatch metadata. See IBuiltin.jitCapabilities. */
43
- export interface JitCapabilities {
44
- /**
45
- * libnumbl_ops opcode enum name (e.g. "NUMBL_UNARY_EXP") for
46
- * element-wise unary tensor builtins routed through
47
- * `numbl_realUnaryElemwise`. Set this on element-wise unary functions
48
- * that have a libnumbl_ops opcode and are safe to invoke on any real
49
- * input (domain-restricted ones like log/sqrt stay excluded).
50
- */
51
- tensorUnaryOp?: string;
52
- /**
53
- * C function name (e.g. "fmax", "atan2", "numbl_mod") for 2-arg
54
- * element-wise tensor builtins. The C-JIT emits an inline per-element
55
- * loop calling this function; it must match the interpreter's
56
- * scalar-apply semantics exactly.
57
- */
58
- tensorBinaryFn?: string;
59
- /**
60
- * libnumbl_ops opcode enum name (e.g. "NUMBL_REDUCE_SUM") for
61
- * tensor→scalar reductions routed through `numbl_tensor_reduce_op`.
62
- * Set on reduction builtins (sum / prod / max / min / any / all / mean).
63
- */
64
- tensorReductionOp?: string;
65
22
  }
66
23
  export declare function getIBuiltin(name: string): IBuiltin | undefined;
67
24
  export declare function registerIBuiltin(b: IBuiltin): void;
@@ -83,7 +40,7 @@ export declare function inferJitType(value: unknown): JitType;
83
40
  * that the runtime replaces when profiling is enabled. */
84
41
  export declare function buildIBuiltinHelpers(): Record<string, any>;
85
42
  export declare function mkc(re: number, im: number): number | RuntimeComplexNumber;
86
- export declare function makeTensor(data: InstanceType<typeof FloatXArray>, imag: InstanceType<typeof FloatXArray> | undefined, shape: number[]): RuntimeTensor;
43
+ export declare function makeTensor(data: Float64Array, imag: Float64Array | undefined, shape: number[]): RuntimeTensor;
87
44
  /** Type rule requiring two scalar numbers */
88
45
  export declare function binaryNumberOnly(argTypes: JitType[]): JitType[] | null;
89
46
  export declare function applyUnaryElemwise(v: RuntimeValue, realFn: (x: number) => number, complexFn: (re: number, im: number) => {
@@ -110,8 +67,6 @@ export declare function defineBuiltin(opts: {
110
67
  help?: BuiltinHelp;
111
68
  cases: BuiltinCase[];
112
69
  jitEmit?: (argCode: string[], argTypes: JitType[], getDest?: () => string) => string | null;
113
- jitEmitC?: (argCode: string[], argTypes: JitType[]) => string | null;
114
- jitCapabilities?: JitCapabilities;
115
70
  }): void;
116
71
  type NumberJitType = Extract<JitType, {
117
72
  kind: "number";
@@ -158,46 +113,4 @@ export declare function predicateCases(scalarTest: (x: number) => boolean, compl
158
113
  export declare function unaryMathJitEmit(mathFn: string, tensorHelper: string, requireNonneg?: boolean): (argCode: string[], argTypes: JitType[], getDest?: () => string) => string | null;
159
114
  /** Fast-path emitter for binary Math.* functions on two scalar numbers. */
160
115
  export declare function binaryMathJitEmit(mathFn: string): (argCode: string[], argTypes: JitType[]) => string | null;
161
- /** Fast-path C emitter for unary math functions on a scalar.
162
- * Emits `cFn(x)` for scalar number/boolean; returns null otherwise
163
- * (tensor emission is handled separately by emit/tensor.ts).
164
- * If `requireNonneg` is set, rejects values whose sign isn't known
165
- * to be nonneg — matches the JS guard for domain-restricted functions. */
166
- export declare function unaryMathJitEmitC(cFn: string, requireNonneg?: boolean): (argCode: string[], argTypes: JitType[]) => string | null;
167
- /** Fast-path C emitter for binary math functions on two scalar numbers. */
168
- export declare function binaryMathJitEmitC(cFn: string): (argCode: string[], argTypes: JitType[]) => string | null;
169
- /**
170
- * Fast-path C emitter for 1-arg scalar builtins that collapse to a
171
- * compile-time constant given the arg's kind. Common for shape/type
172
- * predicates where the answer is fully determined by the type
173
- * (e.g. `isnumeric(number) -> 1.0`, `isscalar(number) -> 1.0`,
174
- * `ndims(number) -> 2.0`, `numel(number) -> 1.0`).
175
- *
176
- * `valueByKind` maps each supported JitType kind to its C constant.
177
- * Arg kinds not in the map return null, which bails the C-JIT to
178
- * JS-JIT for that call site. All values must be valid C double
179
- * literals (`"1.0"`, `"0.0"`, `"2.0"`, ...).
180
- */
181
- export declare function scalarConstantJitEmitC(valueByKind: Partial<Record<JitType["kind"], string>>): (argCode: string[], argTypes: JitType[]) => string | null;
182
- /**
183
- * Fast-path C emitter for 1-arg scalar predicates backed by a runtime
184
- * helper whose return value is int (e.g. `numbl_is_nan`,
185
- * `numbl_is_inf`, `numbl_is_finite`). The int is cast to double for
186
- * the C-JIT's uniform boolean-as-double representation. Returns null
187
- * for non-scalar args.
188
- *
189
- * Note: `isnan` / `isinf` / `isfinite` from `<math.h>` can't be used
190
- * directly because the JIT compiles with `-ffast-math`, which implies
191
- * `-ffinite-math-only` and constant-folds those macros to false/true.
192
- * The `numbl_is_nan` / `_is_inf` / `_is_finite` helpers in
193
- * `jit_runtime` use bit-pattern inspection and live in a separately
194
- * compiled archive, so the caller's `-ffast-math` can't defeat them.
195
- */
196
- export declare function unaryPredicateJitEmitC(cFn: string): (argCode: string[], argTypes: JitType[]) => string | null;
197
- /**
198
- * Fast-path C emitter for 1-arg scalar builtins that are the identity
199
- * on real scalars (e.g. `double(x)`, `real(x)`, `conj(x)`). Returns
200
- * `(x)` for `number`/`boolean`, null otherwise.
201
- */
202
- export declare function scalarIdentityJitEmitC(): (argCode: string[], argTypes: JitType[]) => string | null;
203
116
  export {};
@@ -48,55 +48,45 @@ export declare class Interpreter {
48
48
  fileSources: Map<string, string>;
49
49
  /** @internal Guard against infinite recursion in compileSpecialized */
50
50
  compileInProgress: Set<string>;
51
- /** @internal Per-instance cache for JIT-compiled loops (avoids cross-execution collisions). */
52
- loopJitCache: Map<string, {
53
- fn: (...args: unknown[]) => unknown;
54
- source: string;
55
- } | null>;
56
- /** @internal Per-instance cache for C-JIT-compiled loops (parallel to loopJitCache). */
57
- loopCJitCache: Map<string, {
58
- fn: (...args: unknown[]) => unknown;
59
- } | null>;
60
- /** @internal Progressive type widening for loop JIT: location -> last unified input types. */
61
- loopLastInputTypes: Map<string, import("../jit/jitTypes.js").JitType[]>;
62
- /** @internal Sibling stmts of the currently-executing stmt (set by execStmts). */
63
- _postSiblings: import("../parser/types.js").Stmt[] | null;
64
- /** @internal Index in _postSiblings of the next stmt after the current one. */
65
- _postSiblingsIdx: number;
66
51
  /**
67
- * Optimization level:
68
- * 0 — pure AST interpreter, no JIT.
69
- * 1 — JS-JIT (default): type-specialize hot functions/loops to JS via `new Function()`.
70
- * 2 C-JIT: additionally emit C for feasible scalar specializations,
71
- * compile to a native `.node` module, and invoke via N-API.
72
- * Infeasible IR transparently falls back to the JS-JIT path.
52
+ * Optimization mode:
53
+ * "0" — pure AST interpreter, no JIT.
54
+ * "1" — JS-JIT (default): type-specialize hot functions/loops to JS
55
+ * via `new Function()`.
56
+ * "e3" C-JIT scalar-loop only (Node only). No JS-JIT suite is
57
+ * registered alongside; loops either match the C-JIT
58
+ * executor or fall back to the AST interpreter.
73
59
  */
74
- optimization: number;
75
- /**
76
- * Experimental opt variant selector — e.g. `"e1"` for the prototype
77
- * that keeps JS-JIT as the outer and emits on-demand C kernels for
78
- * fusible tensor chains. Undefined for the standard `--opt <n>` path.
79
- */
80
- experimental?: string;
81
- /** Emit fused per-element loops in C-JIT (--fuse flag). */
82
- fuse: boolean;
83
- /** Parallelize fused loops with OpenMP threads (--par flag). */
84
- par: boolean;
85
- /**
86
- * Diagnostic mode (`--check-c-jit-parity`, only meaningful with `--opt 2`).
87
- * When set, any C-JIT miss where JS-JIT would have compiled throws a
88
- * `CJitParityError` instead of silently falling back — surfacing parity
89
- * gaps as a punch list of features to implement in the C-JIT. Env
90
- * failures (missing `cc`, compile failure) also throw, since the user
91
- * explicitly asked to audit C-JIT coverage.
92
- */
93
- checkCJitParity: boolean;
60
+ optimization: import("../executors/plugins.js").OptLevel;
94
61
  /** Callback for JIT compilation logging (JS codegen). */
95
62
  onJitCompile?: (description: string, jsCode: string) => void;
96
- /** Callback for C-JIT compilation logging (--dump-c). */
97
- onCJitCompile?: (description: string, cSource: string) => void;
98
- /** Verbose log sink (plumbed from ExecOptions.log; used by C-JIT for diagnostics). */
63
+ /** Callback for C-JIT compilation logging (C codegen). Invoked once
64
+ * per cache miss, before the C source is compiled. */
65
+ onCJitCompile?: (description: string, cCode: string) => void;
66
+ /** Bridge for loading native shared libraries — used by the C-JIT
67
+ * loop executor (`--opt e3`) to dlopen freshly-compiled `.so`
68
+ * artifacts via koffi. Undefined in browser contexts; the executor
69
+ * declines when undefined. */
70
+ nativeBridge?: import("../workspace/types.js").NativeBridge;
71
+ /** Compile c-jit kernels with `-ffast-math`. On by default for
72
+ * libmvec-vectorized transcendentals (~30% speedup on element-wise
73
+ * tensor benchmarks); opt out via the CLI's `--no-fast-math` flag
74
+ * to keep reductions bitwise-deterministic. */
75
+ fastMath: boolean;
76
+ /** Telemetry: invoked after a registered executor's `run()` succeeds.
77
+ * Used to track which optimizers fire in a session. The kind is the
78
+ * LoweredStmt kind the executor handled ("top-level", "loop", "call",
79
+ * ...). Hot path — keep the callback cheap. */
80
+ onExecutorFired?: (name: string, kind: string) => void;
81
+ /** Verbose log sink (plumbed from ExecOptions.log). */
99
82
  log?: (message: string) => void;
83
+ /** Executor registry. Holds the strategies (JS-JIT, C-kernel, ...)
84
+ * the dispatcher selects among at runtime. The AST interpreter is
85
+ * the dispatcher's hardcoded fallback (not a registered executor).
86
+ * Mode-driven plugins (`--opt 1`, `--opt 2`, ...) register
87
+ * executors during `executeCode` setup. See
88
+ * docs/developer_reference/executors.md. */
89
+ readonly registry: import("../executors/registry.js").Registry;
100
90
  constructor(rt: Runtime, ctx: LoweringContext, functionIndex: FunctionIndex, mainFileName: string, initialVariableValues?: Record<string, RuntimeValue>);
101
91
  /** Clear all JIT and function resolution caches. Called after addpath/rmpath. */
102
92
  clearAllCaches(): void;
@@ -12,15 +12,18 @@ export interface InterpreterContext {
12
12
  evalInLocalScope: (codeArg: unknown, fileName?: string) => unknown;
13
13
  callFunction: (name: string, args: unknown[], nargout: number) => unknown;
14
14
  rt: Runtime;
15
- /** Optimization level (0 = JIT disabled, 1 = JIT scalar functions). */
16
- optimization: number;
15
+ /** Optimization mode: "0" = no JIT, "1" = JS-JIT, "e3" = C-JIT scalar loops. */
16
+ optimization: import("../executors/plugins.js").OptLevel;
17
17
  /** Resolve a workspace function or class name to its source file,
18
18
  * or undefined if no workspace file provides that name.
19
19
  * `kind` distinguishes a regular .m function from a .numbl.js
20
- * user function (treated as a MEX-equivalent) or a class file. */
20
+ * user function (treated as a MEX-equivalent) or a class file.
21
+ * `source` is the raw .m source for "function"/"class" kinds, or empty
22
+ * for "jsfunction" (where the implementation is JS, not .m text). */
21
23
  lookupWorkspaceFile: (name: string) => {
22
24
  path: string;
23
25
  kind: "function" | "jsfunction" | "class";
26
+ source: string;
24
27
  } | undefined;
25
28
  }
26
29
  export declare const FALL_THROUGH: unique symbol;
@@ -4,7 +4,6 @@
4
4
  import type { Stmt, ArgumentsBlock } from "../parser/types.js";
5
5
  import type { Runtime } from "../runtime/runtime.js";
6
6
  import type { RuntimeValue } from "../runtime/types.js";
7
- import type { JitType } from "../jit/jitTypes.js";
8
7
  export declare class BreakSignal {
9
8
  readonly _tag = "break";
10
9
  }
@@ -18,8 +17,8 @@ export declare class ReturnSignal {
18
17
  }
19
18
  export type ControlSignal = BreakSignal | ContinueSignal | ReturnSignal;
20
19
  export declare class Environment {
21
- private parent?;
22
- private vars;
20
+ parent?: Environment | undefined;
21
+ vars: Map<string, RuntimeValue>;
23
22
  /** When true, writes to variables found in parent go to the parent (nested function semantics). */
24
23
  isNested: boolean;
25
24
  /** Nested function definitions registered during execution. Lazy-initialized. */
@@ -44,12 +43,27 @@ export declare class Environment {
44
43
  persistentFuncId: string | undefined;
45
44
  /** Back-reference to the runtime (needed for global/persistent access) */
46
45
  rt: Runtime | null;
46
+ /** Set when a `@nestedFn` handle has been created that captures this env
47
+ * (or an ancestor). Tells the function-exit cleanup that clearing this
48
+ * env would strand the handle's closure, so locals must be left alive. */
49
+ nestedHandleCreated: boolean;
47
50
  constructor(parent?: Environment | undefined);
48
51
  get(name: string): RuntimeValue | undefined;
49
- /** Set variable — for nested scopes, writes to parent if variable exists there. */
52
+ /** Set variable — for nested scopes, writes to parent if variable
53
+ * exists there. Maintains refcounts: increfs the new value, decrefs
54
+ * the slot's prior occupant (in that order so self-rebind is safe). */
50
55
  set(name: string, value: RuntimeValue): void;
51
56
  /** Always writes to this scope (for parameter binding). */
52
57
  setLocal(name: string, value: RuntimeValue): void;
58
+ /** Remove a variable from this scope's local map.
59
+ * Returns true if the name was present locally. Does not touch
60
+ * the parent scope, globals, or persistent registrations — those
61
+ * are removed via `clear global` / `clear functions` (not yet
62
+ * implemented). */
63
+ delete(name: string): boolean;
64
+ /** Remove all local variables from this scope. Globals,
65
+ * persistents, and nested function defs are preserved. */
66
+ clearLocals(): void;
53
67
  has(name: string): boolean;
54
68
  /** Check if this scope directly owns a variable (not parent). */
55
69
  hasLocal(name: string): boolean;
@@ -60,9 +74,17 @@ export declare class Environment {
60
74
  fn: FunctionDef;
61
75
  env: Environment;
62
76
  } | undefined;
77
+ /** Mark this env and every ancestor up to (and including) the env that
78
+ * defines `name` as having had a nested-function handle created. The
79
+ * handle's closure references this env, so any of those scopes' locals
80
+ * must stay alive after the function exits. Returns true if `name`
81
+ * was found as a nested-function definition somewhere in the chain. */
82
+ markChainForNestedHandle(name: string): boolean;
63
83
  localNames(): string[];
64
84
  /** Create a snapshot of this environment (copies all variables by value).
65
- * Used for anonymous functions which capture values at definition time. */
85
+ * Used for anonymous functions which capture values at definition time.
86
+ * Each captured value is incref'd so it survives the source env's
87
+ * clearLocals when the original frame returns. */
66
88
  snapshot(): Environment;
67
89
  toRecord(): Record<string, RuntimeValue>;
68
90
  }
@@ -72,13 +94,6 @@ export interface FunctionDef {
72
94
  outputs: string[];
73
95
  body: Stmt[];
74
96
  argumentsBlocks?: ArgumentsBlock[];
75
- /** JIT compilation cache: maps signature key -> compiled entry or null (failed). */
76
- _jitCache?: Map<string, {
77
- fn: (...args: unknown[]) => unknown;
78
- source: string;
79
- } | null>;
80
- /** Progressive type widening: last unified arg types, keyed by nargout. */
81
- _lastJitArgTypes?: Map<number, JitType[]>;
82
97
  }
83
98
  /** Create a FunctionDef from an AST Function statement. */
84
99
  export declare function funcDefFromStmt(stmt: Stmt & {
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * JIT type system and IR node definitions.
3
3
  */
4
- import type { BinaryOperation, UnaryOperation } from "../parser/types.js";
4
+ import type { BinaryOperation, UnaryOperation } from "./parser/types.js";
5
5
  export type SignCategory = "positive" | "nonneg" | "nonpositive" | "negative";
6
6
  export type JitType = {
7
7
  kind: "number";
@@ -53,6 +53,12 @@ export type JitType = {
53
53
  } | {
54
54
  kind: "cell";
55
55
  shape?: number[];
56
+ /** Per-index element types (1-based), tracked when literal-index
57
+ * writes happen with a known type. Reads with a literal index in
58
+ * the map return the tracked type instead of `unknown`, which
59
+ * unblocks chunkerfunc's `[out{1:3}] = fcurve(ts); r = out{1}; …`
60
+ * pattern. Sparse — missing keys mean "unknown". */
61
+ elements?: Record<number, JitType>;
56
62
  } | {
57
63
  kind: "dictionary";
58
64
  } | {
@@ -361,6 +367,14 @@ export type JitStmt = {
361
367
  callName: string;
362
368
  args: JitExpr[];
363
369
  outputTypes: JitType[];
370
+ /** Dispatch shape:
371
+ * - "ibuiltin" (default) — IBuiltin called via $h.ibcall.
372
+ * - "func_handle" — `callName` is a function-handle var name; the
373
+ * JIT loads the handle and calls jsFn with the requested nargout.
374
+ * - "user" — `callName` is a user-fn name dispatched through the
375
+ * interpreter (no specialized JIT artifact for the callee yet).
376
+ */
377
+ kind?: "ibuiltin" | "func_handle" | "user";
364
378
  } | {
365
379
  /**
366
380
  * Call a synthetic specialization (installed as a forwarder on $h)
@@ -21,6 +21,14 @@ export interface LoadedJsUserFunction {
21
21
  }
22
22
  /** Returns true if the file is a numbl JS user function file (`*.numbl.js`). */
23
23
  export declare function isNumblJsFile(fileName: string): boolean;
24
+ /** Returns true if the file is an mtoc2-only user function file (`*.mtoc2.js`).
25
+ * Numbl recognizes the extension for workspace discovery + function-name
26
+ * resolution, but never executes the body — mtoc2's loader does that. */
27
+ export declare function isMtoc2JsFile(fileName: string): boolean;
28
+ /** Derive a function name from a `.mtoc2.js` workspace file path.
29
+ * "myadd.mtoc2.js" → "myadd"
30
+ * "/path/to/myadd.mtoc2.js" → "myadd" */
31
+ export declare function funcNameFromMtoc2JsFile(fileName: string): string;
24
32
  /**
25
33
  * Load .numbl.js user function files and return them as LoadedJsUserFunction
26
34
  * records. Each loaded record carries the function name, source file name,
@@ -23,6 +23,13 @@ interface WorkspaceRegistry {
23
23
  fileName: string;
24
24
  builtin: IBuiltin;
25
25
  }>;
26
+ /** mtoc2-only user functions (.mtoc2.js): functionName → { fileName, source }.
27
+ * Numbl never executes these — the source text is stored for mtoc2's loader
28
+ * to consume. Numbl's interpreter rejects calls to them with a clear error. */
29
+ mtoc2UserFunctionsByName: Map<string, {
30
+ fileName: string;
31
+ source: string;
32
+ }>;
26
33
  /** Per-workspace-file lowering contexts (created on demand) */
27
34
  fileContexts: Map<string, LoweringContext>;
28
35
  /** Workspace classes: qualifiedName → ClassInfo */
@@ -68,6 +75,10 @@ export interface FunctionIndex {
68
75
  workspaceFunctions: Set<string>;
69
76
  /** JS user functions (resolved at workspace-function priority, not builtin) */
70
77
  jsUserFunctions: Set<string>;
78
+ /** mtoc2-only user functions (.mtoc2.js). Resolved at workspace-function
79
+ * priority, like jsUserFunctions. Numbl's interpreter rejects calls to
80
+ * these; mtoc2 routes them through its own loader. */
81
+ mtoc2UserFunctions: Set<string>;
71
82
  /** Workspace classes (classdef files) */
72
83
  workspaceClasses: Set<string>;
73
84
  /** Local subfunctions per workspace file: primaryFuncName → Set<subfuncName> */
@@ -139,6 +150,12 @@ export declare class LoweringContext {
139
150
  * Register workspace files for on-demand resolution.
140
151
  * Extracts function names from filenames (top-level only, plus +pkg namespaces).
141
152
  * Also handles @ClassName class folders.
153
+ *
154
+ * `.m` files register as workspace functions / classes / private functions
155
+ * (the regular MATLAB-style discovery). `.mtoc2.js` files register as
156
+ * mtoc2-only user functions: numbl tracks the name so resolution sees
157
+ * them, but the body stays unparsed — mtoc2's loader evaluates them.
158
+ * `.mtoc2.js` files in `@ClassName/` are not yet supported.
142
159
  */
143
160
  registerWorkspaceFiles(files: WorkspaceFile[]): void;
144
161
  isWorkspaceFunction(name: string): boolean;
@@ -149,6 +166,13 @@ export declare class LoweringContext {
149
166
  * Uses first-wins semantics so search-path priority is honored.
150
167
  */
151
168
  registerJsUserFunction(funcName: string, fileName: string, builtin: IBuiltin): void;
169
+ /**
170
+ * Register an mtoc2-only user function (.mtoc2.js) in the workspace
171
+ * registry. Numbl stores the source text verbatim; mtoc2's loader
172
+ * evaluates it. Uses first-wins semantics so search-path priority is
173
+ * honored — same as `.numbl.js`.
174
+ */
175
+ registerMtoc2UserFunction(funcName: string, fileName: string, source: string): void;
152
176
  /**
153
177
  * Get the effective directory for this context's file, used for
154
178
  * private function resolution. If the file is inside a private/ folder,
@@ -26,7 +26,7 @@ export interface LapackBridge {
26
26
  * Invert an n×n real matrix stored in column-major order (MATLAB/LAPACK convention).
27
27
  * @param data Column-major Float64Array of length n*n (not modified).
28
28
  * @param n Matrix dimension.
29
- * @returns Inverted matrix as a new Float64Array in column-major order.
29
+ * @returns Inverted matrix as a allocFloat64Array in column-major order.
30
30
  * @throws Error if the matrix is singular.
31
31
  */
32
32
  inv(data: Float64Array, n: number): Float64Array;
@@ -138,7 +138,7 @@ export interface LapackBridge {
138
138
  * @param k Number of columns in A and rows in B.
139
139
  * @param B Column-major Float64Array of length k*n (B is k×n, not modified).
140
140
  * @param n Number of columns in B and C.
141
- * @returns C = A*B as a new Float64Array of length m*n in column-major order.
141
+ * @returns C = A*B as a allocFloat64Array of length m*n in column-major order.
142
142
  */
143
143
  matmul?(A: Float64Array, m: number, k: number, B: Float64Array, n: number): Float64Array;
144
144
  /**
@@ -168,7 +168,7 @@ export interface LapackBridge {
168
168
  * @param n Number of columns in A; also the number of rows in the result X.
169
169
  * @param B Column-major Float64Array of length m*nrhs (B is m×nrhs, not modified).
170
170
  * @param nrhs Number of right-hand sides (columns of B and X).
171
- * @returns X as a new Float64Array of length n*nrhs in column-major order.
171
+ * @returns X as a allocFloat64Array of length n*nrhs in column-major order.
172
172
  */
173
173
  linsolve?(A: Float64Array, m: number, n: number, B: Float64Array, nrhs: number): Float64Array;
174
174
  /**
@@ -316,6 +316,26 @@ export type Stmt = {
316
316
  directive: string;
317
317
  args: string[];
318
318
  span: Span;
319
+ } | {
320
+ /** Synthetic stmt produced by an executor-registered AST
321
+ * transformer (e.g. the C-JIT chain pass). Wraps a contiguous
322
+ * run of original stmts so a specialized executor can claim
323
+ * them as a unit; the interpreter falls back to executing
324
+ * `subStmts` in order when the executor isn't registered or
325
+ * declines.
326
+ *
327
+ * Never produced by the parser. */
328
+ type: "Synth";
329
+ /** Identifies the executor that this synth node was built for
330
+ * (e.g. `"c-jit-chain"`). The matching executor reads `data`. */
331
+ tag: string;
332
+ /** Original adjacent stmts, in source order. Used by the
333
+ * interpreter fallback. */
334
+ subStmts: Stmt[];
335
+ /** Executor-specific pre-computed analysis. Opaque to the
336
+ * interpreter. */
337
+ data: unknown;
338
+ span: Span;
319
339
  };
320
340
  export interface AbstractSyntaxTree {
321
341
  body: Stmt[];
@@ -1,13 +1,13 @@
1
1
  /**
2
- * RuntimeValue constructor helpers (the MV namespace).
2
+ * RuntimeValue constructor helpers (the RTV namespace).
3
3
  */
4
4
  import { ItemType } from "../lowering/itemTypes.js";
5
- import { type RuntimeNumber, type RuntimeTensor, type RuntimeString, type RuntimeChar, type RuntimeLogical, type RuntimeCell, type RuntimeStruct, type RuntimeFunction, type RuntimeClassInstance, type RuntimeComplexNumber, type RuntimeDummyHandle, type RuntimeGraphicsHandle, type RuntimeStructArray, type RuntimeSparseMatrix, type RuntimeDictionary, type RuntimeValue, type FloatXArrayType } from "./types.js";
5
+ import { type RuntimeNumber, RuntimeTensor, type RuntimeString, RuntimeChar, type RuntimeLogical, RuntimeCell, RuntimeStruct, RuntimeFunction, RuntimeClassInstance, RuntimeComplexNumber, RuntimeDummyHandle, RuntimeGraphicsHandle, RuntimeStructArray, RuntimeSparseMatrix, RuntimeDictionary, type RuntimeValue } from "./types.js";
6
6
  export declare const RTV: {
7
7
  num(value: number): RuntimeNumber;
8
- tensor(data: FloatXArrayType | number[], shape: number[], imag?: FloatXArrayType | number[]): RuntimeTensor;
9
- /** Fast tensor constructor — data must be FloatXArray, shape already normalized (no trailing singletons). */
10
- tensorRaw(data: FloatXArrayType, shape: number[]): RuntimeTensor;
8
+ tensor(data: Float64Array | number[], shape: number[], imag?: Float64Array | number[]): RuntimeTensor;
9
+ /** Fast tensor constructor — data must be Float64Array, shape already normalized (no trailing singletons). */
10
+ tensorRaw(data: Float64Array, shape: number[]): RuntimeTensor;
11
11
  /** Create a scalar tensor (1x1) */
12
12
  scalar(value: number): RuntimeNumber;
13
13
  /** Create a row vector [1 x n] */
@@ -15,7 +15,7 @@ export declare const RTV: {
15
15
  /** Create a column vector [n x 1] */
16
16
  col(data: number[], imag?: number[]): RuntimeTensor;
17
17
  /** Create a matrix from row-major data */
18
- matrix(rows: number, cols: number, data: number[] | FloatXArrayType, imag?: number[] | FloatXArrayType): RuntimeTensor;
18
+ matrix(rows: number, cols: number, data: number[] | Float64Array, imag?: number[] | Float64Array): RuntimeTensor;
19
19
  string(value: string): RuntimeString;
20
20
  char(value: string): RuntimeChar;
21
21
  logical(value: boolean): RuntimeLogical;
@@ -0,0 +1,33 @@
1
+ /**
2
+ * Refcount-driven copy-on-write helpers.
3
+ *
4
+ * The lvalue write path uses these to make sure the chain from the env
5
+ * root to the leaf is uniquely owned before mutation: at each level, if
6
+ * the container is shared (`isShared`), it's cloned and the clone is
7
+ * rebound in the parent. After the chain is unique, in-place mutation
8
+ * at the leaf is observable only to the LHS variable.
9
+ */
10
+ import { type RuntimeValue } from "./types.js";
11
+ import { type RefcountRuntime } from "./refcount.js";
12
+ /** Return a fresh wrapper that shadows `v`'s contents but has rc=0
13
+ * (modulo scope adoption from the constructor). The new wrapper holds
14
+ * its own copy of the underlying buffers (for tensors) or its own
15
+ * fields/data array (for containers). Refs to child values are
16
+ * shared with the original — child wrappers get incref'd by the new
17
+ * container's constructor. Caller is responsible for binding the
18
+ * fresh wrapper into the parent slot.
19
+ *
20
+ * Returns the original value unchanged for kinds that don't need to
21
+ * be copied (handle-class instances, primitives) — the caller can
22
+ * `=== v` test if the copy was a no-op. */
23
+ export declare function cowCopy(v: RuntimeValue): RuntimeValue;
24
+ /** If `v` is shared (rc-driven), return a fresh non-shared copy;
25
+ * otherwise return `v` unchanged. The new wrapper has refcount 0
26
+ * (or 1 if the active scope adopts it via the constructor); the
27
+ * caller must bind it into the parent slot to keep it alive.
28
+ *
29
+ * Returns the original `v` for handle-class instances and primitives —
30
+ * callers can `result === v` test to detect a no-op. */
31
+ export declare function cowIfShared(v: RuntimeValue): RuntimeValue;
32
+ export { isShared } from "./refcount.js";
33
+ export type { RefcountRuntime };
@@ -1,7 +1,8 @@
1
- export type { RuntimeValue, RuntimeTensor, RuntimeString, RuntimeLogical, RuntimeCell, RuntimeStruct, RuntimeFunction, RuntimeDictionary, } from "./types.js";
1
+ export type { RuntimeValue, RuntimeString, RuntimeLogical } from "./types.js";
2
+ export { RuntimeTensor, RuntimeCell, RuntimeStruct, RuntimeFunction, RuntimeDictionary, } from "./types.js";
2
3
  export { RuntimeError, CancellationError, offsetToLine, offsetToColumn, } from "./error.js";
3
4
  export type { CallFrame } from "./error.js";
4
- export { tensorSize2D, numel, colMajorIndex, shareRuntimeValue, } from "./utils.js";
5
+ export { tensorSize2D, numel, colMajorIndex } from "./utils.js";
5
6
  export { toNumber, toBool, toString } from "./convert.js";
6
7
  export { valuesAreEqual } from "./compare.js";
7
8
  export { displayValue } from "./display.js";
@@ -2,9 +2,14 @@
2
2
  * Indexing, struct field access, range creation, and tensor concatenation.
3
3
  */
4
4
  import { type RuntimeValue } from "./types.js";
5
+ import { type RefcountRuntime } from "./refcount.js";
6
+ /** Runtime surface needed by index-store mutations. The full Runtime
7
+ * class satisfies this structurally. */
8
+ type StoreRuntime = RefcountRuntime;
5
9
  /** Sentinel marker for colon (:) indexing — means "all indices in this dimension" */
6
10
  export declare const COLON_INDEX: RuntimeValue;
7
11
  /** Index into a value: v(i1, i2, ...) */
8
12
  export declare function indexIntoRTValue(base: RuntimeValue, indices: RuntimeValue[]): RuntimeValue;
9
13
  /** Store into indexed position: base(indices) = rhs — uses copy-on-write for shared data */
10
- export declare function storeIntoRTValueIndex(base: RuntimeValue, indices: RuntimeValue[], rhs: RuntimeValue, parenAssign?: boolean): RuntimeValue;
14
+ export declare function storeIntoRTValueIndex(base: RuntimeValue, indices: RuntimeValue[], rhs: RuntimeValue, parenAssign?: boolean, rt?: StoreRuntime): RuntimeValue;
15
+ export {};