jz 0.4.0 → 0.5.0
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/README.md +275 -255
- package/cli.js +8 -51
- package/index.js +166 -31
- package/{src/host.js → interop.js} +291 -88
- package/module/array.js +181 -71
- package/module/collection.js +222 -8
- package/module/console.js +1 -1
- package/module/core.js +251 -118
- package/module/date.js +9 -5
- package/module/function.js +11 -1
- package/module/json.js +361 -55
- package/module/math.js +551 -128
- package/module/number.js +390 -227
- package/module/object.js +252 -34
- package/module/regex.js +123 -16
- package/module/schema.js +15 -1
- package/module/string.js +540 -96
- package/module/timer.js +1 -1
- package/module/typedarray.js +674 -57
- package/package.json +10 -7
- package/src/abi/array.js +89 -0
- package/src/abi/index.js +35 -0
- package/src/abi/number.js +137 -0
- package/src/abi/object.js +57 -0
- package/src/abi/string.js +529 -0
- package/src/analyze.js +1870 -485
- package/src/assemble.js +27 -12
- package/src/autoload.js +13 -1
- package/src/compile.js +446 -179
- package/src/ctx.js +85 -18
- package/src/emit.js +662 -196
- package/src/infer.js +548 -0
- package/src/ir.js +291 -23
- package/src/jzify.js +786 -94
- package/src/narrow.js +433 -251
- package/src/optimize.js +126 -122
- package/src/plan.js +703 -34
- package/src/prepare.js +822 -150
- package/src/resolve.js +85 -0
- package/src/vectorize.js +99 -18
- package/src/ast.js +0 -160
- package/src/auto-config.js +0 -120
- package/src/fuse.js +0 -159
package/src/ctx.js
CHANGED
|
@@ -7,6 +7,8 @@
|
|
|
7
7
|
* Refactored into focused sub-contexts for better maintainability.
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
|
+
import { DEFAULTS as ABI_DEFAULTS } from './abi/index.js'
|
|
11
|
+
|
|
10
12
|
// === Carrier layout ===
|
|
11
13
|
// i64 carrier holds either:
|
|
12
14
|
// - raw f64 number bits (any non-NaN-shape pattern), discriminated by
|
|
@@ -26,6 +28,9 @@ export const LAYOUT = {
|
|
|
26
28
|
NAN_PREFIX: 0x7FF8, // top 13 bits of any NaN-shape pointer
|
|
27
29
|
NAN_PREFIX_BITS: 0x7FF8000000000000n, // pre-shifted for i64 OR
|
|
28
30
|
SSO_BIT: 0x4000, // STRING aux bit 14: 1=inline (≤4 ASCII chars in offset), 0=heap
|
|
31
|
+
SLICE_BIT: 0x2000, // STRING aux bit 13: 1=view (no length header — len in aux[12:0],
|
|
32
|
+
// offset points into a parent buffer), 0=own heap string.
|
|
33
|
+
SLICE_LEN_MASK: 0x1FFF, // aux[12:0] — view length (≤8191; larger slices fall back to copy)
|
|
29
34
|
}
|
|
30
35
|
|
|
31
36
|
// === Tagged-pointer type codes ===
|
|
@@ -84,6 +89,10 @@ export const ctx = {
|
|
|
84
89
|
memory: {}, // module memory config (pages, shared)
|
|
85
90
|
error: {}, // source location carried through emit for err() messages
|
|
86
91
|
transform: {}, // compile-time options (jzify, etc.)
|
|
92
|
+
abi: {}, // per-type rep lookup (see abi/index.js). { number: rep, string: rep, ... }
|
|
93
|
+
// Set by reset() to the default carrier bundle. Read by codegen sites
|
|
94
|
+
// that delegate rep-specific behavior — today just the optimizer's
|
|
95
|
+
// peephole hook; expanding as per-site narrowing tags individual sites.
|
|
87
96
|
}
|
|
88
97
|
|
|
89
98
|
/** Create a child scope via shallow flat copy (metacircular-safe: no prototype chain).
|
|
@@ -93,17 +102,38 @@ export const derive = (parent) => ({ ...parent })
|
|
|
93
102
|
/** Include stdlib names for emission. */
|
|
94
103
|
export const inc = (...names) => names.forEach(n => ctx.core.includes.add(n))
|
|
95
104
|
|
|
105
|
+
/** Wrap an emit handler with a declarative stdlib-dependency list. The deps
|
|
106
|
+
* become data — exposed as `.deps` (tabulatable, analyzable) — and are `inc`'d
|
|
107
|
+
* on every call, while the body `fn` stays a pure `args → IR` builder (also
|
|
108
|
+
* reachable as `.pure`). Emitters with no stdlib needs skip the wrapper and
|
|
109
|
+
* register as plain functions; behaviour is identical either way. */
|
|
110
|
+
export const emitter = (deps, fn) => {
|
|
111
|
+
const run = (...args) => (inc(...deps), fn(...args))
|
|
112
|
+
run.deps = deps
|
|
113
|
+
run.pure = fn
|
|
114
|
+
// Preserve the body's arity: `typeof Math.x` folding keys off emitter `.length`
|
|
115
|
+
// to tell callable builtins (sin) from constant ones (PI). The rest-param
|
|
116
|
+
// wrapper would otherwise report 0 for everything.
|
|
117
|
+
Object.defineProperty(run, 'length', { value: fn.length, configurable: true })
|
|
118
|
+
return run
|
|
119
|
+
}
|
|
120
|
+
|
|
96
121
|
/** Expand ctx.core.includes transitively via ctx.core.stdlibDeps. Call before WASM assembly.
|
|
97
122
|
* Each module co-locates its own deps with its stdlib registrations at init time. */
|
|
98
123
|
export function resolveIncludes() {
|
|
99
124
|
const graph = ctx.core.stdlibDeps
|
|
100
|
-
|
|
101
|
-
while (
|
|
102
|
-
|
|
103
|
-
const
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
if (
|
|
125
|
+
let changed = true
|
|
126
|
+
while (changed) {
|
|
127
|
+
changed = false
|
|
128
|
+
for (const name of [...ctx.core.includes]) {
|
|
129
|
+
const entry = graph[name]
|
|
130
|
+
const deps = typeof entry === 'function' ? entry() : entry
|
|
131
|
+
if (deps) for (const dep of deps) {
|
|
132
|
+
if (!ctx.core.includes.has(dep)) {
|
|
133
|
+
ctx.core.includes.add(dep)
|
|
134
|
+
changed = true
|
|
135
|
+
}
|
|
136
|
+
}
|
|
107
137
|
}
|
|
108
138
|
}
|
|
109
139
|
}
|
|
@@ -118,6 +148,10 @@ export function reset(proto, globals) {
|
|
|
118
148
|
extImports: new Set(), // __ext_* helpers actually emitted as env imports —
|
|
119
149
|
// pullStdlib() removes them from `includes` after wiring,
|
|
120
150
|
// so post-compile auditors (host: 'wasi') read this instead.
|
|
151
|
+
jsstring: new Set(), // `wasm:js-string` builtin names referenced by emitted code.
|
|
152
|
+
// Drained at module-assembly time into `(import "wasm:js-string" "name" …)`
|
|
153
|
+
// nodes; host wires JS-side polyfills via interop's
|
|
154
|
+
// env builder for engines without builtin support.
|
|
121
155
|
}
|
|
122
156
|
|
|
123
157
|
|
|
@@ -141,7 +175,7 @@ export function reset(proto, globals) {
|
|
|
141
175
|
globalTypes: new Map(),
|
|
142
176
|
globalValTypes: null,
|
|
143
177
|
globalTypedElem: null,
|
|
144
|
-
|
|
178
|
+
globalReps: null, // Map<name, ValueRep> — module-level pointer reps (TYPED const globals stored as raw i32 offset, etc.)
|
|
145
179
|
consts: null,
|
|
146
180
|
}
|
|
147
181
|
|
|
@@ -149,16 +183,24 @@ export function reset(proto, globals) {
|
|
|
149
183
|
list: [],
|
|
150
184
|
names: new Set(), // Set<string> — known func names (list + imported funcs); populated at compile() start
|
|
151
185
|
map: new Map(), // Map<string, func> — name → func entry; populated at compile() start
|
|
186
|
+
multiProp: new Set(), // Set<"obj.prop"> — function-properties assigned >1× (wrapper composition); suppresses the static fn.prop() direct call
|
|
152
187
|
exports: {},
|
|
153
188
|
current: null,
|
|
154
189
|
locals: new Map(),
|
|
155
|
-
|
|
156
|
-
refinements: new Map(), // flow-sensitive: name → VAL
|
|
190
|
+
localReps: null,
|
|
191
|
+
refinements: new Map(), // flow-sensitive: name → {val?: VAL.*, notString?: true} inside a type-guarded branch
|
|
157
192
|
boxed: new Map(),
|
|
158
193
|
stack: [],
|
|
159
194
|
uniq: 0,
|
|
160
195
|
inTry: false,
|
|
161
196
|
localProps: null,
|
|
197
|
+
// Pass-scoped overlays installed by analyzeBody/observeSlots. While set,
|
|
198
|
+
// `lookupValType`/`typedElemCtor` consult the in-progress fact maps before
|
|
199
|
+
// falling back to global state — lets shorthand `{x}` / typed-array writes
|
|
200
|
+
// observe locals that haven't been promoted to ctx.types yet. Saved/restored
|
|
201
|
+
// by the pass owners so re-entrant analyzeBody calls don't clobber each other.
|
|
202
|
+
localValTypesOverlay: null,
|
|
203
|
+
localTypedElemsOverlay: null,
|
|
162
204
|
}
|
|
163
205
|
|
|
164
206
|
ctx.types = {
|
|
@@ -181,6 +223,21 @@ export function reset(proto, globals) {
|
|
|
181
223
|
// returns the slot's kind for `.prop` AST nodes, letting
|
|
182
224
|
// `+`/`===`/method dispatch elide `__is_str_key` checks
|
|
183
225
|
// on numeric properties of known shapes.
|
|
226
|
+
slotIntCertain: new Map(), // schemaId → Array<boolean | undefined>
|
|
227
|
+
// undefined: no write observed, true: all observed
|
|
228
|
+
// writes are integer-shaped, false: poisoned by at
|
|
229
|
+
// least one non-int write. Populated by
|
|
230
|
+
// `analyzeSchemaSlotIntCertain` (whole-program
|
|
231
|
+
// walk over `{}` literals + `obj.prop = expr`
|
|
232
|
+
// writes). Read by `ctx.schema.slotIntCertainAt`
|
|
233
|
+
// so Math.floor/toNumF64/intIndexIR consumers fire
|
|
234
|
+
// on `.prop` reads of provably-integer slots.
|
|
235
|
+
inlineArray: new Set(), // schemaId set — schemas whose `Array<S>` instances
|
|
236
|
+
// use the `structInline` SRoA carrier (K f64
|
|
237
|
+
// fields inlined per element, no per-row object).
|
|
238
|
+
// Populated whole-program by `analyzeStructInline`
|
|
239
|
+
// (default-disqualify); read by the array
|
|
240
|
+
// push/index/length codegen.
|
|
184
241
|
}
|
|
185
242
|
|
|
186
243
|
ctx.closure = {
|
|
@@ -199,6 +256,8 @@ export function reset(proto, globals) {
|
|
|
199
256
|
strPool: null, // shared-memory: accumulated raw bytes of string literals (no length prefix)
|
|
200
257
|
strPoolDedup: new Map(), // str → offset in strPool
|
|
201
258
|
throws: false,
|
|
259
|
+
userThrows: false, // user wrote `throw`/`try`/`catch`/`finally` — keep runtime declared
|
|
260
|
+
// even when all throws are dead-code-eliminated (JS-side ABI contract).
|
|
202
261
|
}
|
|
203
262
|
|
|
204
263
|
ctx.memory = {
|
|
@@ -226,8 +285,15 @@ export function reset(proto, globals) {
|
|
|
226
285
|
// instantiation time. 'wasi': error at compile time if any `__ext_*` import
|
|
227
286
|
// would be emitted, since wasmtime/wasmer hosts have no JS runtime to satisfy
|
|
228
287
|
// them and silent fallback would corrupt output.
|
|
288
|
+
inspect: false, // when true, compile() additionally populates ctx.inspect with the inferred
|
|
289
|
+
// per-function signatures, locals, and JSON shapes — readable by editor
|
|
290
|
+
// hosts for inlay hints / hover types without re-running the analyzer.
|
|
229
291
|
}
|
|
230
292
|
|
|
293
|
+
// Inspection sink. Populated by compile() only when transform.inspect is true.
|
|
294
|
+
// Shape: { abi, functions: { [name]: { exported, params, results, ptrKind?, locals, callerReps } }, schemas }.
|
|
295
|
+
ctx.inspect = null
|
|
296
|
+
|
|
231
297
|
// Feature flags: capabilities the compiled module may exercise at runtime.
|
|
232
298
|
// Set true by producer sites (import points, auto-imports, dynamic call sites).
|
|
233
299
|
// Read by stdlib template factories and deps graph at resolveIncludes() time to
|
|
@@ -243,16 +309,17 @@ export function reset(proto, globals) {
|
|
|
243
309
|
// (b) a capability needs an opt-in A/B switch against the default path
|
|
244
310
|
// (SSO is the planned first user — default string-literal emission
|
|
245
311
|
// currently forces SSO for ≤4 ASCII chars at string.js:49)
|
|
312
|
+
ctx.abi = ABI_DEFAULTS
|
|
313
|
+
|
|
314
|
+
// Only flags actually read by codegen live here. Hash/regex/json substrates
|
|
315
|
+
// are pulled organically by inc(__*) — no flag mediates them, so no flag exists.
|
|
246
316
|
ctx.features = {
|
|
247
|
-
external: false, // PTR.EXTERNAL possible — opts.imports, HOST_GLOBALS, or __ext_call site.
|
|
248
|
-
hash: false, // PTR.HASH + __dyn_* substrate. Organic: any inc(__hash_*/__dyn_*) implies on.
|
|
317
|
+
external: false, // PTR.EXTERNAL possible — opts.imports, HOST_GLOBALS, or __ext_call site.
|
|
249
318
|
sso: true, // ≤4-ASCII string packing. Default on; flip off to A/B the heap-only path.
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
map: false, // Map. Organic via inc(__map_*).
|
|
255
|
-
closure: false, // First-class functions. Organic via ctx.closure.table population.
|
|
319
|
+
typedarray: false,// Float64Array/Int32Array/etc. Set on typed-array construction; gates PTR.TYPED dispatch.
|
|
320
|
+
set: false, // Set. Set on Set construction; gates PTR.SET dispatch.
|
|
321
|
+
map: false, // Map. Set on Map construction; gates PTR.MAP dispatch.
|
|
322
|
+
closure: false, // First-class functions. Set when ctx.closure.table is populated.
|
|
256
323
|
timers: false, // Set by prepare.js when timer module is included
|
|
257
324
|
blockingTimers: false, // wasmtime CLI: include __timer_loop in _start
|
|
258
325
|
}
|