numbl 0.4.18 → 0.4.19
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.
- package/dist-browser/browser.js +1 -1
- package/dist-browser/numbl-core/executors/jit/callExecutor.d.ts +7 -1
- package/dist-browser/numbl-core/executors/jit/loopExecutor.d.ts +12 -7
- package/dist-browser/numbl-core/executors/jit/topLevelExecutor.d.ts +3 -0
- package/dist-browser/numbl-core/executors/jit/valueAdapter.d.ts +9 -2
- package/dist-browser/numbl-core/executors/registry.d.ts +8 -0
- package/dist-browser/numbl-core/interpreter/interpreter.d.ts +11 -0
- package/dist-browser/numbl-core/jit/builtins/runtime/system/cscalar.d.ts +4 -4
- package/dist-browser/numbl-core/jit/codegen/emitIndex.d.ts +1 -1
- package/dist-browser/numbl-core/jit/compileSpec.d.ts +4 -0
- package/dist-browser/numbl-core/jit/lowering/lower.d.ts +13 -0
- package/dist-browser/numbl-core/jitDeclineDiagnostics.d.ts +6 -0
- package/dist-browser/numbl-core/version.d.ts +1 -1
- package/dist-cli/cli.js +361 -109
- package/dist-lib/lib.js +298 -67
- package/dist-lib/numbl-core/executors/jit/callExecutor.d.ts +7 -1
- package/dist-lib/numbl-core/executors/jit/loopExecutor.d.ts +12 -7
- package/dist-lib/numbl-core/executors/jit/topLevelExecutor.d.ts +3 -0
- package/dist-lib/numbl-core/executors/jit/valueAdapter.d.ts +9 -2
- package/dist-lib/numbl-core/executors/registry.d.ts +8 -0
- package/dist-lib/numbl-core/interpreter/interpreter.d.ts +11 -0
- package/dist-lib/numbl-core/jit/builtins/runtime/system/cscalar.d.ts +4 -4
- package/dist-lib/numbl-core/jit/codegen/emitIndex.d.ts +1 -1
- package/dist-lib/numbl-core/jit/compileSpec.d.ts +4 -0
- package/dist-lib/numbl-core/jit/lowering/lower.d.ts +13 -0
- package/dist-lib/numbl-core/jitDeclineDiagnostics.d.ts +6 -0
- package/dist-lib/numbl-core/version.d.ts +1 -1
- package/dist-site-viewer/assets/{index-34LVPucU.js → index-B5Y5557F.js} +252 -252
- package/dist-site-viewer/assets/{numbl-worker-BCMSGYEy.js → numbl-worker-CtoT7C0f.js} +103 -87
- package/dist-site-viewer/index.html +1 -1
- package/package.json +1 -1
|
@@ -25,7 +25,10 @@
|
|
|
25
25
|
* - **Loop-depth gate.** Declines when `interp.loopDepth > 0` so a
|
|
26
26
|
* hot loop iterating function calls doesn't pay per-call JIT
|
|
27
27
|
* propose / spec-cache overhead. Once an outer call is JIT'd, its
|
|
28
|
-
* loops run inside mtoc2's compiled code anyway.
|
|
28
|
+
* loops run inside mtoc2's compiled code anyway. The gate lifts when
|
|
29
|
+
* every enclosing loop was itself declined: nothing above will be
|
|
30
|
+
* compiled then, and an expensive callee would otherwise run
|
|
31
|
+
* interpreted all the way down (`Interpreter.jitDeclinedLoopDepth`).
|
|
29
32
|
*/
|
|
30
33
|
import type { Executor } from "../types.js";
|
|
31
34
|
import { type JitType } from "../../jitTypes.js";
|
|
@@ -40,6 +43,9 @@ interface JitCallData {
|
|
|
40
43
|
}
|
|
41
44
|
interface CompiledArtifact {
|
|
42
45
|
readonly specFn: (...args: unknown[]) => unknown;
|
|
46
|
+
/** The spec's declared output types — needed to convert a returned
|
|
47
|
+
* struct back (an untagged JS object otherwise). */
|
|
48
|
+
readonly outputTypes: ReadonlyArray<CompilerType>;
|
|
43
49
|
}
|
|
44
50
|
export declare const jitCallExecutor: Executor<JitCallData, CompiledArtifact | null>;
|
|
45
51
|
export {};
|
|
@@ -9,13 +9,15 @@
|
|
|
9
9
|
* that the synthetic body is a single-element `[loopStmt]` instead of
|
|
10
10
|
* a whole script body.
|
|
11
11
|
*
|
|
12
|
-
* Loop-depth gate:
|
|
13
|
-
*
|
|
14
|
-
* loop-body would pay per-iter
|
|
15
|
-
* speedup, because the *outer* loop is the
|
|
16
|
-
* (it captures the inner loop's body and runs it
|
|
17
|
-
* emitted code)
|
|
18
|
-
*
|
|
12
|
+
* Loop-depth gate: fires when `interp.loopDepth === 0`, or when every
|
|
13
|
+
* enclosing loop has been declined by the JIT. A loop dispatched while the
|
|
14
|
+
* interpreter iterates an enclosing loop-body would pay per-iter
|
|
15
|
+
* propose/cache overhead with no speedup, because the *outer* loop is the
|
|
16
|
+
* natural JIT entry point (it captures the inner loop's body and runs it
|
|
17
|
+
* natively in mtoc2-emitted code) — but that only holds when the outer loop
|
|
18
|
+
* actually compiles. If it declined, the interpreter is walking its body and
|
|
19
|
+
* this loop is the outermost thing still compilable, so the gate lifts
|
|
20
|
+
* (`Interpreter.jitDeclinedLoopDepth`).
|
|
19
21
|
*/
|
|
20
22
|
import type { Executor } from "../types.js";
|
|
21
23
|
import { type JitType } from "../../jitTypes.js";
|
|
@@ -36,6 +38,9 @@ interface JitLoopData {
|
|
|
36
38
|
}
|
|
37
39
|
interface CompiledArtifact {
|
|
38
40
|
readonly specFn: (...args: unknown[]) => unknown;
|
|
41
|
+
/** The synthetic spec's output types, so a struct written back into the
|
|
42
|
+
* env is rebuilt as a struct (the emitted value is an untagged object). */
|
|
43
|
+
readonly outputTypes: ReadonlyArray<CompilerType>;
|
|
39
44
|
}
|
|
40
45
|
export declare const jitLoopExecutor: Executor<JitLoopData, CompiledArtifact | null>;
|
|
41
46
|
export {};
|
|
@@ -31,6 +31,9 @@ interface JitTopLevelData {
|
|
|
31
31
|
interface CompiledArtifact {
|
|
32
32
|
readonly specFn: (...args: unknown[]) => unknown;
|
|
33
33
|
readonly nargout: number;
|
|
34
|
+
/** The synthetic spec's output types, so a struct written back into the
|
|
35
|
+
* env is rebuilt as a struct (the emitted value is an untagged object). */
|
|
36
|
+
readonly outputTypes: ReadonlyArray<CompilerType>;
|
|
34
37
|
}
|
|
35
38
|
export declare const jitTopLevelExecutor: Executor<JitTopLevelData, CompiledArtifact | null>;
|
|
36
39
|
export {};
|
|
@@ -43,8 +43,15 @@ import type { Type } from "../../jit/index.js";
|
|
|
43
43
|
* complex-typed body reads `.re`/`.im`, so a bare number must be
|
|
44
44
|
* boxed into `{re, im:0}`. */
|
|
45
45
|
export declare function numblToJit(v: RuntimeValue, paramType?: Type): unknown;
|
|
46
|
-
/** mtoc2 emit-JS return value → numbl RuntimeValue.
|
|
47
|
-
|
|
46
|
+
/** mtoc2 emit-JS return value → numbl RuntimeValue.
|
|
47
|
+
*
|
|
48
|
+
* `retType` is the compiler type the spec declares for this output. It is
|
|
49
|
+
* only consulted for plain untagged objects, which is how the emitted code
|
|
50
|
+
* represents both a struct and a class instance — the value alone cannot
|
|
51
|
+
* tell them apart, so a struct is only rebuilt when the type says Struct
|
|
52
|
+
* and anything else untagged is rejected (the executor then bails and the
|
|
53
|
+
* interpreter, which has full class semantics, re-runs the call). */
|
|
54
|
+
export declare function jitToNumbl(v: unknown, retType?: Type): RuntimeValue;
|
|
48
55
|
/** True if `e` is the grow-bail sentinel thrown by the emitted JS
|
|
49
56
|
* store helpers (`mtoc2_idx_*_grow_js` in `scalar_index.js`) — an
|
|
50
57
|
* indexed store whose index exceeds the runtime extent, which would
|
|
@@ -110,6 +110,14 @@ export declare class Registry {
|
|
|
110
110
|
* pure overhead.
|
|
111
111
|
*/
|
|
112
112
|
dispatch(siblings: readonly Stmt[], i: number, ctx: DispatchContext): DispatchResult;
|
|
113
|
+
/** Run one stmt on the AST interpreter.
|
|
114
|
+
*
|
|
115
|
+
* When that stmt is a loop, the interpreter is about to walk its body,
|
|
116
|
+
* which invalidates the "an enclosing loop will capture me" assumption
|
|
117
|
+
* behind the executors' `loopDepth` gate. `jitDeclinedLoopDepth` records
|
|
118
|
+
* that for the duration of the body so nested loops and calls can bid for
|
|
119
|
+
* themselves instead of running interpreted all the way down. */
|
|
120
|
+
private interpretFallback;
|
|
113
121
|
private runStmtCandidate;
|
|
114
122
|
/** Cache lookup + compile-on-miss + run + bail handling. Returns
|
|
115
123
|
* the executor's success RunResult, or null when the candidate
|
|
@@ -54,6 +54,17 @@ export declare class Interpreter {
|
|
|
54
54
|
* interpreter never sees them, so this gate only fires on calls
|
|
55
55
|
* that genuinely happen at the interpreter level inside a loop. */
|
|
56
56
|
loopDepth: number;
|
|
57
|
+
/** @internal Number of those enclosing loops that the JIT *declined*, so
|
|
58
|
+
* the interpreter is walking their bodies statement by statement. The
|
|
59
|
+
* `loopDepth > 0` gate above assumes an enclosing loop will be compiled
|
|
60
|
+
* and will swallow whatever is nested inside it; when that loop was
|
|
61
|
+
* declined instead, the assumption is false and everything below it would
|
|
62
|
+
* run interpreted however expensive it is. The executors therefore gate on
|
|
63
|
+
* `loopDepth > 0 && jitDeclinedLoopDepth === 0`: still no per-iteration JIT
|
|
64
|
+
* attempts underneath a loop that is about to be compiled, but a nested
|
|
65
|
+
* loop or call under a declined one gets its own chance. Bumped by the
|
|
66
|
+
* registry around the interpreter fallback for a loop stmt. */
|
|
67
|
+
jitDeclinedLoopDepth: number;
|
|
57
68
|
/** @internal Number of enclosing conditional blocks (`if` / `switch` /
|
|
58
69
|
* `try`) whose bodies the interpreter is currently executing. Used by
|
|
59
70
|
* the loop classifier: when a loop is dispatched with `condBlockDepth >
|
|
@@ -34,7 +34,7 @@ export function mtoc2_cpow(a: any, b: any): {
|
|
|
34
34
|
im: number;
|
|
35
35
|
};
|
|
36
36
|
export function mtoc2_csqrt(z: any): {
|
|
37
|
-
re:
|
|
37
|
+
re: any;
|
|
38
38
|
im: number;
|
|
39
39
|
};
|
|
40
40
|
export function mtoc2_cexp(z: any): {
|
|
@@ -42,15 +42,15 @@ export function mtoc2_cexp(z: any): {
|
|
|
42
42
|
im: number;
|
|
43
43
|
};
|
|
44
44
|
export function mtoc2_clog(z: any): {
|
|
45
|
-
re:
|
|
45
|
+
re: any;
|
|
46
46
|
im: number;
|
|
47
47
|
};
|
|
48
48
|
export function mtoc2_clog2(z: any): {
|
|
49
|
-
re:
|
|
49
|
+
re: any;
|
|
50
50
|
im: number;
|
|
51
51
|
};
|
|
52
52
|
export function mtoc2_clog10(z: any): {
|
|
53
|
-
re:
|
|
53
|
+
re: any;
|
|
54
54
|
im: number;
|
|
55
55
|
};
|
|
56
56
|
export function mtoc2_csin(z: any): {
|
|
@@ -38,7 +38,7 @@ export declare function emitNdScalarOffset(state: RuntimeState, indices: Readonl
|
|
|
38
38
|
* the precomputed source-index buffer). The caller is expected to
|
|
39
39
|
* emit these lines immediately after closing the slot iteration
|
|
40
40
|
* loops and before the GCC statement-expression's yield expression. */
|
|
41
|
-
export declare function emitSliceSlotSetup(state: RuntimeState, lines: string[], indent: string, slotsTyped: ReadonlyArray<IndexSliceArg>, baseCName: string, cleanups?: string[]): string[];
|
|
41
|
+
export declare function emitSliceSlotSetup(state: RuntimeState, lines: string[], indent: string, slotsTyped: ReadonlyArray<IndexSliceArg>, baseCName: string, cleanups?: string[], grow?: boolean): string[];
|
|
42
42
|
/** Emit an `IndexSlice` as a C statement-expression-style block that
|
|
43
43
|
* allocates the result tensor, fills it, and evaluates to the result
|
|
44
44
|
* via a comma expression. The result is consumed at an owned consume
|
|
@@ -79,6 +79,10 @@ export interface CompileSpecResult {
|
|
|
79
79
|
source: string;
|
|
80
80
|
/** Names of runtime snippets activated by emit. Diagnostic only. */
|
|
81
81
|
activatedSnippets: ReadonlyArray<string>;
|
|
82
|
+
/** The spec's output types, in order. The host needs them to convert
|
|
83
|
+
* returned values back: a struct and a class instance are both plain
|
|
84
|
+
* JS objects in the emitted code, so only the type says which is which. */
|
|
85
|
+
outputTypes: ReadonlyArray<Type>;
|
|
82
86
|
}
|
|
83
87
|
export declare function compileSpec(args: CompileSpecArgs): CompileSpecResult;
|
|
84
88
|
export {};
|
|
@@ -225,6 +225,19 @@ export declare class Lowerer {
|
|
|
225
225
|
recordAssignment(name: string, expr: IRExpr, span: Span): Assign;
|
|
226
226
|
private lowerIf;
|
|
227
227
|
private lowerElseChain;
|
|
228
|
+
/** MATLAB `switch` lowered to the equivalent if/elseif chain.
|
|
229
|
+
*
|
|
230
|
+
* The subject is evaluated once — hoisted to a temp unless it is already a
|
|
231
|
+
* plain variable — and each case label becomes an equality test against it:
|
|
232
|
+
* `strcmp` for text, `==` for numbers. A `case {a, b}` list is the OR of
|
|
233
|
+
* the individual tests. Everything after that is `lowerIf`'s problem, which
|
|
234
|
+
* means switch inherits its branch-env merging and cond folding.
|
|
235
|
+
*
|
|
236
|
+
* Declined (leaving the unit to the interpreter, as before this existed):
|
|
237
|
+
* a subject that is neither a scalar number nor text, a label whose kind
|
|
238
|
+
* does not match the subject's, and an empty `case {}`.
|
|
239
|
+
*/
|
|
240
|
+
private lowerSwitch;
|
|
228
241
|
private lowerWhile;
|
|
229
242
|
private lowerFor;
|
|
230
243
|
lowerExpr(e: Expr): IRExpr;
|
|
@@ -23,6 +23,12 @@ export interface JitDecline {
|
|
|
23
23
|
kind: string;
|
|
24
24
|
/** Which executor declined: "jit-top-level" | "jit-call" | "jit-loop". */
|
|
25
25
|
where: string;
|
|
26
|
+
/** Source position of the offending construct, when the thrown error
|
|
27
|
+
* carried one. Only used for diagnostics. */
|
|
28
|
+
at?: {
|
|
29
|
+
file: string;
|
|
30
|
+
start: number;
|
|
31
|
+
};
|
|
26
32
|
}
|
|
27
33
|
/** Record a swallowed JIT decline reason (called from executor catch blocks). */
|
|
28
34
|
export declare function recordJitDecline(d: JitDecline): void;
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
/** Numbl version, used for JIT disk cache invalidation. */
|
|
2
|
-
export declare const NUMBL_VERSION = "0.4.
|
|
2
|
+
export declare const NUMBL_VERSION = "0.4.19";
|