jz 0.6.0 → 0.7.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.
Files changed (49) hide show
  1. package/README.md +66 -43
  2. package/bench/README.md +128 -78
  3. package/bench/bench.svg +32 -42
  4. package/cli.js +73 -7
  5. package/dist/interop.js +1 -0
  6. package/dist/jz.js +6024 -0
  7. package/index.d.ts +126 -0
  8. package/index.js +190 -34
  9. package/interop.js +71 -27
  10. package/layout.js +5 -0
  11. package/module/array.js +71 -39
  12. package/module/collection.js +41 -5
  13. package/module/core.js +2 -4
  14. package/module/math.js +138 -2
  15. package/module/number.js +21 -0
  16. package/module/object.js +26 -0
  17. package/module/simd.js +37 -5
  18. package/module/string.js +41 -12
  19. package/module/typedarray.js +415 -26
  20. package/package.json +21 -6
  21. package/src/autoload.js +3 -0
  22. package/src/compile/analyze-scans.js +174 -11
  23. package/src/compile/analyze.js +38 -3
  24. package/src/compile/emit-assign.js +9 -6
  25. package/src/compile/emit.js +347 -36
  26. package/src/compile/index.js +307 -29
  27. package/src/compile/infer.js +36 -1
  28. package/src/compile/loop-divmod.js +155 -0
  29. package/src/compile/narrow.js +108 -11
  30. package/src/compile/peel-stencil.js +261 -0
  31. package/src/compile/plan/advise.js +55 -1
  32. package/src/compile/plan/index.js +4 -0
  33. package/src/compile/plan/inline.js +5 -2
  34. package/src/compile/plan/literals.js +220 -5
  35. package/src/compile/plan/scope.js +115 -39
  36. package/src/compile/program-facts.js +21 -2
  37. package/src/ctx.js +45 -7
  38. package/src/ir.js +55 -7
  39. package/src/kind-traits.js +27 -0
  40. package/src/kind.js +65 -3
  41. package/src/optimize/index.js +344 -45
  42. package/src/optimize/vectorize.js +2968 -182
  43. package/src/prepare/index.js +64 -7
  44. package/src/prepare/lift-iife.js +149 -0
  45. package/src/reps.js +3 -2
  46. package/src/static.js +9 -0
  47. package/src/type.js +10 -6
  48. package/src/wat/assemble.js +195 -13
  49. package/src/wat/optimize.js +363 -185
package/bench/bench.svg CHANGED
@@ -1,12 +1,12 @@
1
- <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 720 500" width="720" height="500" role="img" aria-label="jz benchmark — each ball runs back and forth at a rate proportional to that engine's speed; jz is the 1.00× baseline, lower is faster">
2
- <rect width="720" height="500" rx="12" fill="#ffffff"/>
1
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 720 474" width="720" height="474" role="img" aria-label="jz benchmark — every rival compiled to WebAssembly, run in V8 · native C = reference; geometric mean across 22 benchmark cases · lower is faster, jz = 1.00× baseline; each ball's speed is proportional to that engine's geometric-mean runtime across the corpus">
2
+ <rect width="720" height="474" rx="12" fill="#ffffff"/>
3
3
 
4
4
  <g font-family="-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,sans-serif">
5
5
  <rect x="174" y="43.5" width="476" height="3" rx="1.5" fill="#edf0f2"/>
6
6
  <line x1="174" y1="38" x2="174" y2="52" stroke="#ced4da" stroke-width="2"/>
7
7
  <line x1="650" y1="38" x2="650" y2="52" stroke="#ced4da" stroke-width="2"/>
8
8
  <text x="156" y="41" text-anchor="end" font-size="14" font-weight="700" fill="#000000">jz</text>
9
- <text x="156" y="56" text-anchor="end" font-size="10" fill="#aeb4ba">→ wasm</text>
9
+ <text x="156" y="56" text-anchor="end" font-size="10" fill="#aeb4ba">-O3</text>
10
10
  <text x="662" y="49" font-size="13" font-weight="700" fill="#000000">1.00×</text>
11
11
  <circle cx="182.0" cy="45" r="8" fill="#000000">
12
12
  <animate attributeName="cx" dur="1.6s" repeatCount="indefinite" calcMode="linear"
@@ -17,11 +17,11 @@
17
17
  <rect x="174" y="93.5" width="476" height="3" rx="1.5" fill="#edf0f2"/>
18
18
  <line x1="174" y1="88" x2="174" y2="102" stroke="#ced4da" stroke-width="2"/>
19
19
  <line x1="650" y1="88" x2="650" y2="102" stroke="#ced4da" stroke-width="2"/>
20
- <text x="156" y="91" text-anchor="end" font-size="14" font-weight="500" fill="#343a40">Rust</text>
21
- <text x="156" y="106" text-anchor="end" font-size="10" fill="#aeb4ba">rustc -O3</text>
20
+ <text x="156" y="91" text-anchor="end" font-size="14" font-weight="500" fill="#343a40">native C</text>
21
+ <text x="156" y="106" text-anchor="end" font-size="10" fill="#aeb4ba">clang -O3 · ref</text>
22
22
  <text x="662" y="99" font-size="13" font-weight="500" fill="#868e96">1.07×</text>
23
23
  <circle cx="182.0" cy="95" r="8" fill="#adb5bd">
24
- <animate attributeName="cx" dur="1.7111717105322697s" repeatCount="indefinite" calcMode="linear"
24
+ <animate attributeName="cx" dur="1.7120000000000002s" repeatCount="indefinite" calcMode="linear"
25
25
  keyTimes="0;0.5;1" values="182.0;642.0;182.0" begin="-0.41s"/>
26
26
  </circle>
27
27
  </g>
@@ -29,11 +29,11 @@
29
29
  <rect x="174" y="143.5" width="476" height="3" rx="1.5" fill="#edf0f2"/>
30
30
  <line x1="174" y1="138" x2="174" y2="152" stroke="#ced4da" stroke-width="2"/>
31
31
  <line x1="650" y1="138" x2="650" y2="152" stroke="#ced4da" stroke-width="2"/>
32
- <text x="156" y="141" text-anchor="end" font-size="14" font-weight="500" fill="#343a40">Zig</text>
33
- <text x="156" y="156" text-anchor="end" font-size="10" fill="#aeb4ba">ReleaseFast</text>
34
- <text x="662" y="149" font-size="13" font-weight="500" fill="#868e96">1.31×</text>
32
+ <text x="156" y="141" text-anchor="end" font-size="14" font-weight="500" fill="#343a40">C</text>
33
+ <text x="156" y="156" text-anchor="end" font-size="10" fill="#aeb4ba">zig cc → wasm</text>
34
+ <text x="662" y="149" font-size="13" font-weight="500" fill="#868e96">2.43×</text>
35
35
  <circle cx="182.0" cy="145" r="8" fill="#adb5bd">
36
- <animate attributeName="cx" dur="2.097403438402887s" repeatCount="indefinite" calcMode="linear"
36
+ <animate attributeName="cx" dur="3.8880000000000003s" repeatCount="indefinite" calcMode="linear"
37
37
  keyTimes="0;0.5;1" values="182.0;642.0;182.0" begin="-0.82s"/>
38
38
  </circle>
39
39
  </g>
@@ -41,11 +41,11 @@
41
41
  <rect x="174" y="193.5" width="476" height="3" rx="1.5" fill="#edf0f2"/>
42
42
  <line x1="174" y1="188" x2="174" y2="202" stroke="#ced4da" stroke-width="2"/>
43
43
  <line x1="650" y1="188" x2="650" y2="202" stroke="#ced4da" stroke-width="2"/>
44
- <text x="156" y="191" text-anchor="end" font-size="14" font-weight="500" fill="#343a40">Bun</text>
45
- <text x="156" y="206" text-anchor="end" font-size="10" fill="#aeb4ba">JSC</text>
46
- <text x="662" y="199" font-size="13" font-weight="500" fill="#868e96">1.51×</text>
44
+ <text x="156" y="191" text-anchor="end" font-size="14" font-weight="500" fill="#343a40">Rust</text>
45
+ <text x="156" y="206" text-anchor="end" font-size="10" fill="#aeb4ba">rustc → wasm</text>
46
+ <text x="662" y="199" font-size="13" font-weight="500" fill="#868e96">2.63×</text>
47
47
  <circle cx="182.0" cy="195" r="8" fill="#adb5bd">
48
- <animate attributeName="cx" dur="2.4126551201460966s" repeatCount="indefinite" calcMode="linear"
48
+ <animate attributeName="cx" dur="4.208s" repeatCount="indefinite" calcMode="linear"
49
49
  keyTimes="0;0.5;1" values="182.0;642.0;182.0" begin="-1.23s"/>
50
50
  </circle>
51
51
  </g>
@@ -53,11 +53,11 @@
53
53
  <rect x="174" y="243.5" width="476" height="3" rx="1.5" fill="#edf0f2"/>
54
54
  <line x1="174" y1="238" x2="174" y2="252" stroke="#ced4da" stroke-width="2"/>
55
55
  <line x1="650" y1="238" x2="650" y2="252" stroke="#ced4da" stroke-width="2"/>
56
- <text x="156" y="241" text-anchor="end" font-size="14" font-weight="500" fill="#343a40">Go</text>
57
- <text x="156" y="256" text-anchor="end" font-size="10" fill="#aeb4ba">gc</text>
58
- <text x="662" y="249" font-size="13" font-weight="500" fill="#868e96">1.62×</text>
56
+ <text x="156" y="241" text-anchor="end" font-size="14" font-weight="500" fill="#343a40">V8</text>
57
+ <text x="156" y="256" text-anchor="end" font-size="10" fill="#aeb4ba">Node (JS)</text>
58
+ <text x="662" y="249" font-size="13" font-weight="500" fill="#868e96">2.69×</text>
59
59
  <circle cx="182.0" cy="245" r="8" fill="#adb5bd">
60
- <animate attributeName="cx" dur="2.599256056991375s" repeatCount="indefinite" calcMode="linear"
60
+ <animate attributeName="cx" dur="4.304s" repeatCount="indefinite" calcMode="linear"
61
61
  keyTimes="0;0.5;1" values="182.0;642.0;182.0" begin="-1.64s"/>
62
62
  </circle>
63
63
  </g>
@@ -65,11 +65,11 @@
65
65
  <rect x="174" y="293.5" width="476" height="3" rx="1.5" fill="#edf0f2"/>
66
66
  <line x1="174" y1="288" x2="174" y2="302" stroke="#ced4da" stroke-width="2"/>
67
67
  <line x1="650" y1="288" x2="650" y2="302" stroke="#ced4da" stroke-width="2"/>
68
- <text x="156" y="291" text-anchor="end" font-size="14" font-weight="500" fill="#343a40">V8</text>
69
- <text x="156" y="306" text-anchor="end" font-size="10" fill="#aeb4ba">Node</text>
70
- <text x="662" y="299" font-size="13" font-weight="500" fill="#868e96">1.98×</text>
68
+ <text x="156" y="291" text-anchor="end" font-size="14" font-weight="500" fill="#343a40">AssemblyScript</text>
69
+ <text x="156" y="306" text-anchor="end" font-size="10" fill="#aeb4ba">asc -O3</text>
70
+ <text x="662" y="299" font-size="13" font-weight="500" fill="#868e96">2.80×</text>
71
71
  <circle cx="182.0" cy="295" r="8" fill="#adb5bd">
72
- <animate attributeName="cx" dur="3.161748945741268s" repeatCount="indefinite" calcMode="linear"
72
+ <animate attributeName="cx" dur="4.4799999999999995s" repeatCount="indefinite" calcMode="linear"
73
73
  keyTimes="0;0.5;1" values="182.0;642.0;182.0" begin="-2.05s"/>
74
74
  </circle>
75
75
  </g>
@@ -77,11 +77,11 @@
77
77
  <rect x="174" y="343.5" width="476" height="3" rx="1.5" fill="#edf0f2"/>
78
78
  <line x1="174" y1="338" x2="174" y2="352" stroke="#ced4da" stroke-width="2"/>
79
79
  <line x1="650" y1="338" x2="650" y2="352" stroke="#ced4da" stroke-width="2"/>
80
- <text x="156" y="341" text-anchor="end" font-size="14" font-weight="500" fill="#343a40">AssemblyScript</text>
81
- <text x="156" y="356" text-anchor="end" font-size="10" fill="#aeb4ba">asc -O3</text>
82
- <text x="662" y="349" font-size="13" font-weight="500" fill="#868e96">2.02×</text>
80
+ <text x="156" y="341" text-anchor="end" font-size="14" font-weight="500" fill="#343a40">Porffor</text>
81
+ <text x="156" y="356" text-anchor="end" font-size="10" fill="#aeb4ba">runs 3 / 22</text>
82
+ <text x="662" y="349" font-size="13" font-weight="500" fill="#868e96">3.49×</text>
83
83
  <circle cx="182.0" cy="345" r="8" fill="#adb5bd">
84
- <animate attributeName="cx" dur="3.234040602137033s" repeatCount="indefinite" calcMode="linear"
84
+ <animate attributeName="cx" dur="5.5840000000000005s" repeatCount="indefinite" calcMode="linear"
85
85
  keyTimes="0;0.5;1" values="182.0;642.0;182.0" begin="-2.46s"/>
86
86
  </circle>
87
87
  </g>
@@ -89,24 +89,14 @@
89
89
  <rect x="174" y="393.5" width="476" height="3" rx="1.5" fill="#edf0f2"/>
90
90
  <line x1="174" y1="388" x2="174" y2="402" stroke="#ced4da" stroke-width="2"/>
91
91
  <line x1="650" y1="388" x2="650" y2="402" stroke="#ced4da" stroke-width="2"/>
92
- <text x="156" y="391" text-anchor="end" font-size="14" font-weight="500" fill="#343a40">Porffor</text>
93
- <text x="156" y="406" text-anchor="end" font-size="10" fill="#aeb4ba">runs 3 / 13</text>
94
- <text x="662" y="399" font-size="13" font-weight="500" fill="#868e96">3.08×</text>
92
+ <text x="156" y="391" text-anchor="end" font-size="14" font-weight="500" fill="#343a40">Go</text>
93
+ <text x="156" y="406" text-anchor="end" font-size="10" fill="#aeb4ba">gc wasm</text>
94
+ <text x="662" y="399" font-size="13" font-weight="500" fill="#868e96">4.91×</text>
95
95
  <circle cx="182.0" cy="395" r="8" fill="#adb5bd">
96
- <animate attributeName="cx" dur="4.926330541139543s" repeatCount="indefinite" calcMode="linear"
96
+ <animate attributeName="cx" dur="7.856000000000001s" repeatCount="indefinite" calcMode="linear"
97
97
  keyTimes="0;0.5;1" values="182.0;642.0;182.0" begin="-2.87s"/>
98
98
  </circle>
99
99
  </g>
100
- <g font-family="-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,sans-serif">
101
- <rect x="174" y="443.5" width="476" height="3" rx="1.5" fill="#edf0f2"/>
102
- <line x1="174" y1="438" x2="174" y2="452" stroke="#ced4da" stroke-width="2"/>
103
- <line x1="650" y1="438" x2="650" y2="452" stroke="#ced4da" stroke-width="2"/>
104
- <text x="156" y="441" text-anchor="end" font-size="14" font-weight="500" fill="#343a40">NumPy</text>
105
- <text x="156" y="456" text-anchor="end" font-size="10" fill="#aeb4ba">Python</text>
106
- <text x="662" y="449" font-size="13" font-weight="500" fill="#868e96">8.31×</text>
107
- <circle cx="182.0" cy="445" r="8" fill="#adb5bd">
108
- <animate attributeName="cx" dur="10s" repeatCount="indefinite" calcMode="linear"
109
- keyTimes="0;0.5;1" values="182.0;642.0;182.0" begin="-3.28s"/>
110
- </circle>
111
- </g>
100
+ <text x="360" y="440" text-anchor="middle" font-family="-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,sans-serif" font-size="11" font-weight="600" fill="#495057">every rival compiled to WebAssembly, run in V8 · native C = reference</text>
101
+ <text x="360" y="458" text-anchor="middle" font-family="-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,sans-serif" font-size="11" fill="#868e96">geometric mean across 22 benchmark cases · lower is faster, jz = 1.00× baseline</text>
112
102
  </svg>
package/cli.js CHANGED
@@ -36,8 +36,10 @@ Examples:
36
36
  jz program.js --wat # → program.wat
37
37
  jz program.js -o out.wasm # custom output name
38
38
  jz program.js -o - # write to stdout
39
- jz program.js -O3 # aggressive optimization
39
+ jz program.js -O3 # optimize for speed
40
40
  jz program.js -Os # optimize for size
41
+ jz program.js -D DEBUG=false # inject a compile-time constant
42
+ jz program.js --memory 64 # 64 initial pages (4 MB)
41
43
  jz program.js --host wasi # emit WASI Preview 1 imports
42
44
  jz --strict program.js # strict mode
43
45
  jz --jzify lib.js # → lib.jz
@@ -45,11 +47,22 @@ Examples:
45
47
 
46
48
  Options:
47
49
  --output, -o <file> Output file (.wat, .wasm, or - for stdout)
48
- -O<n>, --optimize <n> Optimization level: 0 off, 1 size-only, 2 default,
49
- 3 aggressive. Aliases: -Os/size, -Ob/balanced, -Of/speed.
50
+ -O<n>, --optimize <n> Optimization level: 0 off, 1 minimal, 2 default (all
51
+ stable passes), 3 speed. -Os optimizes for size.
52
+ --define, -D <K=V> Inject a compile-time constant (VALUE parsed as JSON,
53
+ else string). Repeatable.
50
54
  --host <js|wasi> Runtime-service lowering (default js)
55
+ --memory <pages> Initial memory size in 64 KiB pages
56
+ --max-memory <pages> Cap memory growth at this many pages (default unbounded)
57
+ --import-memory Import env.memory instead of exporting own memory
51
58
  --no-alloc Omit _alloc/_clear allocator exports (standalone wasm)
59
+ --no-simd Disable auto-vectorization (no v128) for non-SIMD engines
60
+ --why-not-simd Report, per loop, why the auto-vectorizer declined it
61
+ --experimental-stencil Enable neighbour-load stencil vectorization (a[i±1]; opt-in)
62
+ --experimental-outer-strip Strip-mine pixel loops over an inner reduction to f64x2 (opt-in)
63
+ --no-tail-call Use ordinary call frames instead of return_call
52
64
  --names Emit wasm name section for profilers/debuggers
65
+ --stats Print compile-phase timings to stderr
53
66
  --strict Pure canonical subset: reject full-JS syntax + dynamic fallbacks
54
67
  --jzify Transform JS to jz source (no compilation)
55
68
  --eval, -e Evaluate expression or file
@@ -121,17 +134,47 @@ async function handleJzify(args) {
121
134
  }
122
135
  }
123
136
 
124
- // -O<n>/-Os/-Ob/-Of and --optimize <val>value accepted by compile()'s `optimize` opt
125
- const OPT_ALIAS = { s: 'size', b: 'balanced', f: 'speed' }
137
+ // -O<n> numeric levels (0–3); -Os size preset. The 'size'/'speed' strings are
138
+ // also accepted via `--optimize <name>` for parity with the JS API (-O3 = speed).
139
+ const OPT_ALIAS = { s: 'size' }
126
140
  function parseOptimize(v) {
127
141
  if (v == null) return undefined
128
142
  if (/^\d+$/.test(v)) return +v
129
143
  return OPT_ALIAS[v] ?? v
130
144
  }
131
145
 
146
+ // -D NAME=VALUE / --define NAME=VALUE → [key, value]. VALUE is parsed as JSON when
147
+ // it can be (numbers, booleans, null, JSON arrays/objects); otherwise a bare string.
148
+ function parseDefine(s) {
149
+ const eq = s.indexOf('=')
150
+ if (eq === -1) throw new Error(`--define expects NAME=VALUE (got '${s}')`)
151
+ let value
152
+ try { value = JSON.parse(s.slice(eq + 1)) } catch { value = s.slice(eq + 1) }
153
+ return [s.slice(0, eq), value]
154
+ }
155
+
156
+ function parsePages(v, flag) {
157
+ const n = parseInt(v, 10)
158
+ if (!Number.isInteger(n) || n < 1) throw new Error(`${flag} expects a positive integer page count (64 KiB/page)`)
159
+ return n
160
+ }
161
+
162
+ // --stats: dump top-level compile-phase timings to stderr (stdout stays clean for
163
+ // `-o -`). Sub-phase (optMod:*) detail is left to the programmatic `profile` sink.
164
+ function printStats(profile) {
165
+ const rows = Object.entries(profile.totals || {}).filter(([n]) => !n.includes(':'))
166
+ if (!rows.length) return
167
+ const width = Math.max(5, ...rows.map(([n]) => n.length))
168
+ const total = rows.reduce((sum, [, ms]) => sum + ms, 0)
169
+ console.error('compile stats (ms):')
170
+ for (const [name, ms] of rows) console.error(` ${name.padEnd(width)} ${ms.toFixed(2)}`)
171
+ console.error(` ${'total'.padEnd(width)} ${total.toFixed(2)}`)
172
+ }
173
+
132
174
  async function handleCompile(args) {
133
175
  let inputFile = null, outputFile = null, wat = false, strict = false, resolveNode = false, importsFile = null
134
- let optimize, host, alloc = true, names = false
176
+ let optimize, host, alloc = true, names = false, stats = false, noSimd = false, noTailCall = false
177
+ let memory, maxMemory, importMemory = false, define, whyNotSimd = false, experimentalStencil = false, experimentalOuterStrip = false
135
178
 
136
179
  for (let i = 0; i < args.length; i++) {
137
180
  const a = args[i]
@@ -140,11 +183,22 @@ async function handleCompile(args) {
140
183
  else if (a === '--strict') strict = true
141
184
  else if (a === '--resolve') resolveNode = true
142
185
  else if (a === '--imports') importsFile = args[++i]
186
+ else if (a === '--define' || a === '-D') { const [k, v] = parseDefine(args[++i]); (define ||= {})[k] = v }
187
+ else if (a.startsWith('-D') && a.length > 2) { const [k, v] = parseDefine(a.slice(2)); (define ||= {})[k] = v }
143
188
  else if (a === '--optimize' || a === '-O') optimize = parseOptimize(args[++i])
144
189
  else if (/^-O.+/.test(a)) optimize = parseOptimize(a.slice(2))
145
190
  else if (a === '--host') host = args[++i]
191
+ else if (a === '--memory') memory = parsePages(args[++i], '--memory')
192
+ else if (a === '--max-memory') maxMemory = parsePages(args[++i], '--max-memory')
193
+ else if (a === '--import-memory') importMemory = true
146
194
  else if (a === '--no-alloc') alloc = false
195
+ else if (a === '--no-simd') noSimd = true
196
+ else if (a === '--why-not-simd') whyNotSimd = true
197
+ else if (a === '--experimental-stencil') experimentalStencil = true
198
+ else if (a === '--experimental-outer-strip') experimentalOuterStrip = true
199
+ else if (a === '--no-tail-call') noTailCall = true
147
200
  else if (a === '--names') names = true
201
+ else if (a === '--stats') stats = true
148
202
  else if (!inputFile) inputFile = a
149
203
  }
150
204
 
@@ -161,6 +215,7 @@ async function handleCompile(args) {
161
215
  // `.jz` files are treated as strict; `--strict` forces it for any extension.
162
216
  if (inputFile.endsWith('.jz')) strict = true
163
217
  const warnings = { entries: [] }
218
+ const profile = stats ? {} : null
164
219
  const opts = {
165
220
  wat,
166
221
  warnings,
@@ -168,8 +223,18 @@ async function handleCompile(args) {
168
223
  importMetaUrl: pathToFileURL(resolve(inputFile)).href,
169
224
  ...(optimize !== undefined && { optimize }),
170
225
  ...(host && { host }),
226
+ ...(memory !== undefined && { memory }),
227
+ ...(maxMemory !== undefined && { maxMemory }),
228
+ ...(importMemory && { importMemory: true }),
171
229
  ...(alloc === false && { alloc: false }),
172
- ...(names && { profile: { names: true } }),
230
+ ...(noSimd && { noSimd: true }),
231
+ ...(whyNotSimd && { whyNotSimd: true }),
232
+ ...(experimentalStencil && { experimentalStencil: true }),
233
+ ...(experimentalOuterStrip && { experimentalOuterStrip: true }),
234
+ ...(noTailCall && { noTailCall: true }),
235
+ ...(define && { define }),
236
+ ...(names && { names: true }),
237
+ ...(profile && { profile }),
173
238
  ...(Object.keys(modules).length && { modules }),
174
239
  }
175
240
 
@@ -182,6 +247,7 @@ async function handleCompile(args) {
182
247
 
183
248
  for (const w of warnings.entries)
184
249
  console.warn(formatWarning(w))
250
+ if (profile) printStats(profile)
185
251
 
186
252
  if (outputFile === '-') {
187
253
  process.stdout.write(result)
@@ -0,0 +1 @@
1
+ var fe=new TextDecoder;function Q(t={}){let e=null,a=(c,i)=>{let p=c===1?globalThis.process?.stdout:globalThis.process?.stderr;if(p&&typeof p.write=="function")try{p.write(i);return}catch{}let A=i.replace(/\n$/,"");(c===1?console.log:console.warn)(A)},l=t.write||a;return{wasi_snapshot_preview1:{fd_read(c,i,p,A){let g=new DataView(e.buffer),d=0;for(let h=0;h<p;h++){let _=g.getUint32(i+h*8,!0),T=g.getUint32(i+h*8+4,!0),U=new Uint8Array(e.buffer,_,T);d+=t.read&&t.read(c,U)||0}return g.setUint32(A,d,!0),0},fd_write(c,i,p,A){let g=new DataView(e.buffer),d=0;for(let h=0;h<p;h++){let _=g.getUint32(i+h*8,!0),T=g.getUint32(i+h*8+4,!0);l(c,fe.decode(new Uint8Array(e.buffer,_,T))),d+=T}return g.setUint32(A,d,!0),0},clock_time_get(c,i,p){let A=new DataView(e.buffer),g=BigInt(Math.round(c===0?Date.now()*1e6:performance.now()*1e6));return A.setBigInt64(p,g,!0),0},random_get(c,i){let p=new Uint8Array(e.buffer,c,i);if(globalThis.crypto?.getRandomValues)globalThis.crypto.getRandomValues(p);else for(let A=0;A<i;A++)p[A]=Math.random()*256|0;return 0},proc_exit(){},environ_sizes_get(c,i){let p=new DataView(e.buffer);return p.setUint32(c,0,!0),p.setUint32(i,0,!0),0},environ_get(){return 0}},_setMemory(c){e=c}}}var Z=t=>{if(!t.exports.__timer_tick)return;let e=t.exports.__timer_tick,a=!1,l=setInterval(()=>{let c=e();c>0&&(a=!0),a&&c<=0&&clearInterval(l)},1)};var L={PTR_ADDR:1020,START:1024},k={TAG_SHIFT:47,TAG_MASK:15,AUX_SHIFT:32,AUX_MASK:32767,OFFSET_MASK:4294967295,NAN_PREFIX:32760,NAN_PREFIX_BITS:0x7FF8000000000000n,SSO_BIT:16384,SLICE_BIT:8192,SLICE_LEN_MASK:8191},N={ATOM:0,ARRAY:1,BUFFER:2,TYPED:3,STRING:4,OBJECT:6,HASH:7,SET:8,MAP:9,CLOSURE:10,EXTERNAL:11},E={NULL:1,UNDEF:2,FALSE:4,TRUE:5},Ie=1<<N.ARRAY|1<<N.HASH|1<<N.SET|1<<N.MAP;var P=(t,e)=>(2146959360|(t&15)<<15|e&32767)>>>0,X=t=>t>>>15&15,Y=t=>t&32767;var B={[E.NULL]:P(N.ATOM,E.NULL),[E.UNDEF]:P(N.ATOM,E.UNDEF),[E.FALSE]:P(N.ATOM,E.FALSE),[E.TRUE]:P(N.ATOM,E.TRUE)};var J=new TextEncoder,le=new TextDecoder,ue=(t,e)=>{let a=WebAssembly.Module.imports(t).some(l=>l.module==="wasi_snapshot_preview1");return{needsWasi:a,wasiImports:a?Q(e):null}},me=t=>new Set(WebAssembly.Module.imports(t).filter(e=>e.module==="env"&&e.kind==="function").map(e=>e.name)),pe=(t,e)=>{let a=()=>new DataView(t.buffer),l=e?()=>e.value:()=>a().getInt32(L.PTR_ADDR,!0),c=e?d=>{e.value=d}:d=>a().setInt32(L.PTR_ADDR,d,!0),i=e?e.value:L.START;return{alloc:d=>{let h=l()+7&-8,_=h+d;return _>t.buffer.byteLength&&t.grow(Math.ceil((_-t.buffer.byteLength)/65536)),c(_),h},reset:()=>c(i),initHeapPtr:()=>{if(e)return;let d=a();d.getInt32(L.PTR_ADDR,!0)<L.START&&d.setInt32(L.PTR_ADDR,L.START,!0)}}},G=(t,e)=>{let a=WebAssembly.Module.customSections(t,e);return a.length?new Uint8Array(a[0]):null},ye=t=>{let e=new TextDecoder,a=0;return{pos:()=>a,seek:l=>{a=l},eof:()=>a>=t.length,u8:()=>t[a++],varint:()=>{let l=0,c=0;for(;;){let i=t[a++];if(l|=(i&127)<<c,!(i&128))return l;c+=7}},str:l=>{let c=e.decode(t.subarray(a,a+l));return a+=l,c},bytes:l=>{let c=t.subarray(a,a+l);return a+=l,c}}},oe=new ArrayBuffer(8),I=new Uint32Array(oe),M=new Float64Array(oe),se=(()=>{let t=new ArrayBuffer(8),e=new BigInt64Array(t),a=new Float64Array(t);return{i64ToF64:l=>(e[0]=l,a[0]),f64ToI64:l=>(a[0]=l,e[0])}})(),S=se.i64ToF64,j=se.f64ToI64;I[1]=B[E.NULL];I[0]=0;var de=M[0];I[1]=B[E.UNDEF];I[0]=0;var V=M[0];I[1]=B[E.FALSE];I[0]=0;var Ue=M[0];I[1]=B[E.TRUE];I[0]=0;var Se=M[0],R=t=>t===null?de:t===void 0?V:t,W=t=>{if(t===t)return t;if(M[0]=t,X(I[1])===4){let e=Y(I[1]);if(e&k.SSO_BIT){let a=e&7,l=I[0],c="";for(let i=0;i<a;i++)c+=String.fromCharCode(l>>>i*8&255);return c}}if(I[0]!==0)return t;if(I[1]===B[E.NULL])return null;if(I[1]!==B[E.UNDEF])return I[1]===B[E.FALSE]?!1:I[1]===B[E.TRUE]?!0:t},K=(t,e)=>{let a=S(e);return t.mem?t.mem.read(a):W(a)},O=(t,e,a)=>(I[1]=P(t,e),I[0]=a>>>0,M[0]),$=t=>(M[0]=t,I[0]),ee=t=>(M[0]=t,X(I[1])),v=t=>(M[0]=t,Y(I[1])),q={Int8Array:[0,1,"getInt8","setInt8"],Uint8Array:[1,1,"getUint8","setUint8"],Int16Array:[2,2,"getInt16","setInt16"],Uint16Array:[3,2,"getUint16","setUint16"],Int32Array:[4,4,"getInt32","setInt32"],Uint32Array:[5,4,"getUint32","setUint32"],Float32Array:[6,4,"getFloat32","setFloat32"],Float64Array:[7,8,"getFloat64","setFloat64"]},te=Object.values(q),H=new WeakSet,z=t=>{if(t instanceof WebAssembly.Memory&&H.has(t))return t;if(!t||typeof t=="object"&&!(t instanceof WebAssembly.Memory)&&!t.instance&&!t.exports&&!t.memory){let r=new WebAssembly.Memory({initial:t?.initial||1,...t?.maximum?{maximum:t.maximum}:{},...t?.shared?{shared:t.shared}:{}});return z(r)}let e,a,l,c;if(t instanceof WebAssembly.Memory)e=t,a=null,l=null,c=null;else{let r=t?.instance?.exports||t?.exports||t;if(e=t?.exports?.memory||r.memory,!e)return{read:W,wrapVal:R,scalar:!0};a={...r,memory:e},l=t.extMap||null,c=t.module||null}let i=()=>new DataView(e.buffer),{alloc:p,reset:A,initHeapPtr:g}=pe(e,a?.__heap),d=a?._alloc||p;g();let h=(r,n,m)=>{let s=d(16+m),o=i();return o.setBigInt64(s,0n,!0),o.setInt32(s+8,r,!0),o.setInt32(s+12,n,!0),s+16},_=e.schemas||[],T=c&&G(c,"jz:schema");if(T){let r=ye(T),n=()=>{let o=r.u8();return o===0?null:o===1?[null,n()]:r.str(r.varint())},m=r.varint(),s=[];for(let o=0;o<m;o++){let f=r.varint(),u=[];for(let y=0;y<f;y++)u.push(n());s.push(u)}for(let o of s){let f=o.join(",");_.some(u=>u.join(",")===f)||_.push(o)}}if(H.has(e))return e.schemas=_,a?._alloc&&(d=a._alloc,e.alloc=d),e.reset=A,l&&(e._extMap=l),e;e.schemas=_,e._extMap=l,e.Array=r=>{let n=r.length,m=h(n,n,n*8),s=new BigInt64Array(n);for(let f=0;f<n;f++)s[f]=j(e.wrapVal(r[f]));let o=new BigInt64Array(e.buffer,m,n);for(let f=0;f<n;f++)o[f]=s[f];return O(1,0,m)},e.String=r=>{if(r.length<=4&&/^[\x00-\x7f]*$/.test(r)){let u=0;for(let y=0;y<r.length;y++)u|=r.charCodeAt(y)<<y*8;return O(4,k.SSO_BIT|r.length,u)}let n=J.encode(r),m=n.length,s=d(4+m),o=i();o.setInt32(s,m,!0);let f=s+4;return n.forEach((u,y)=>o.setUint8(f+y,u)),O(4,0,f)},e.Buffer=r=>{let n=r instanceof ArrayBuffer?new Uint8Array(r):ArrayBuffer.isView(r)?new Uint8Array(r.buffer,r.byteOffset,r.byteLength):new Uint8Array(r),m=n.length,s=h(m,m,m);return new Uint8Array(e.buffer).set(n,s),O(2,0,s)},e.wrapVal=function(r){if(r==null)return R(r);if(typeof r=="number"||typeof r=="boolean")return Number(r);if(typeof r=="string")return e.String(r);if(typeof r=="bigint")return e.String(r.toString());if(Array.isArray(r))return e.Array(r);if(r instanceof ArrayBuffer)return e.Buffer(r);if(r instanceof DataView)return e.Buffer(r.buffer);let n=r?.constructor?.name;return n&&q[n]?e[n](r):typeof r=="object"||typeof r=="function"?e.External(r):V},e.External=function(r){if(r==null)return R(r);let n=e._extMap;if(!n)return V;let m=n.indexOf(r);return m===-1&&(m=n.length,n.push(r)),O(11,0,m)},e.Object=function(r){let n=Object.keys(r),m=n.join(","),s=e.schemas,o=s.findIndex(b=>b.join(",")===m);if(o===-1){let b=s.reduce((w,D,ae)=>D.length===n.length&&n.every(ce=>D.includes(ce))?w.concat(ae):w,[]);if(b.length===1)o=b[0];else{if(b.length>1)throw Error(`Ambiguous schema for {${m}} \u2014 pass keys in schema order`);if(e._extMap)return e.External(r);throw Error(`No schema for {${m}}`)}}let f=s[o],u=f.length,y=d(u*8),x=new BigInt64Array(u);for(let b=0;b<u;b++){let w=r[f[b]];w==null?w=R(w):typeof w=="string"?w=e.String(w):Array.isArray(w)&&(w=e.Array(w)),x[b]=j(w)}let F=new BigInt64Array(e.buffer,y,u);for(let b=0;b<u;b++)F[b]=x[b];return O(6,o,y)},e.read=function(r){if(Array.isArray(r))return r.map(o=>e.read(o));if(r===r)return r;let n=ee(r),m=v(r),s=$(r);if(n===0&&s===0){if(m===1)return null;if(m===2)return;if(m===4)return!1;if(m===5)return!0}if(n===11&&e._extMap)return e._extMap[s];if(n===1){let o=i(),f=s;for(;o.getInt32(f-4,!0)===-1;)f=o.getInt32(f-8,!0);let u=o.getInt32(f-8,!0),y=new Array(u);for(let x=0;x<u;x++)y[x]=e.read(o.getFloat64(f+x*8,!0));return y}if(n===3){let o=v(r),f=o&7,[,u]=te[f],y=[Int8Array,Uint8Array,Int16Array,Uint16Array,Int32Array,Uint32Array,Float32Array,Float64Array][f],x=i();if(o&8){let b=x.getInt32(s,!0),w=x.getInt32(s+4,!0);return new y(e.buffer,w,b/u)}let F=x.getInt32(s-8,!0);return new y(e.buffer,s,F/u)}if(n===2){let o=i().getInt32(s-8,!0),f=new ArrayBuffer(o);return new Uint8Array(f).set(new Uint8Array(e.buffer,s,o)),f}if(n===4){let o=v(r);if(o&k.SSO_BIT){let u=o&7,y="";for(let x=0;x<u;x++)y+=String.fromCharCode(s>>>x*8&255);return y}let f=i().getInt32(s-4,!0);return le.decode(new Uint8Array(e.buffer,s,f))}if(n===6){let o=i(),f=v(r),u=e.schemas[f];if(!u)return r;let y={};for(let x=0;x<u.length;x++)y[u[x]]=e.read(o.getFloat64(s+x*8,!0));return y}if(n===7){let o=i(),f=o.getInt32(s-8,!0),u=o.getInt32(s-4,!0),y={};for(let x=0,F=0;x<u&&F<f;x++)if(o.getFloat64(s+x*24,!0)!==0){let w=e.read(o.getFloat64(s+x*24+8,!0));y[w]=e.read(o.getFloat64(s+x*24+16,!0)),F++}return y}if(n===8){let o=i(),f=o.getInt32(s-8,!0),u=o.getInt32(s-4,!0),y=new Set;for(let x=0;x<u&&y.size<f;x++)o.getFloat64(s+x*16,!0)!==0&&y.add(e.read(o.getFloat64(s+x*16+8,!0)));return y}if(n===9){let o=i(),f=o.getInt32(s-8,!0),u=o.getInt32(s-4,!0),y=new Map;for(let x=0;x<u&&y.size<f;x++)o.getFloat64(s+x*24,!0)!==0&&y.set(e.read(o.getFloat64(s+x*24+8,!0)),e.read(o.getFloat64(s+x*24+16,!0)));return y}return r},e.write=function(r,n){let m=ee(r),s=$(r),o=i();if(m===1){let f=o.getInt32(s-4,!0);if(n.length>f)throw Error(`write: ${n.length} exceeds capacity ${f}`);o.setInt32(s-8,n.length,!0);for(let u=0;u<n.length;u++)o.setFloat64(s+u*8,R(n[u]),!0)}else if(m===3){let f=v(r),u=f&7,[,y,,x]=te[u],F=n.length*y;if(f&8){let b=o.getInt32(s,!0),w=o.getInt32(s+4,!0);if(F>b)throw Error(`write: ${F} bytes exceeds view size ${b}`);for(let D=0;D<n.length;D++)o[x](w+D*y,n[D],!0)}else{let b=o.getInt32(s-4,!0);if(F>b)throw Error(`write: ${F} bytes exceeds capacity ${b}`);o.setInt32(s-8,F,!0);for(let w=0;w<n.length;w++)o[x](s+w*y,n[w],!0)}}else if(m===6){let f=e.schemas[v(r)];if(!f)throw Error("write: unknown schema");for(let u of Object.keys(n)){let y=f.indexOf(u);y>=0&&o.setFloat64(s+y*8,R(n[u]),!0)}}else throw Error(`write: unsupported type ${m}`)},e.alloc=d,e.reset=A;let U=[Int8Array,Uint8Array,Int16Array,Uint16Array,Int32Array,Uint32Array,Float32Array,Float64Array];for(let[r,[n,m,,s]]of Object.entries(q))e[r]=o=>{let f=o.length,u=f*m,y=h(u,u,u);if(m>=2&&U[n]&&o instanceof U[n])new U[n](e.buffer,y,f).set(o);else{let x=i();for(let F=0;F<f;F++)x[s](y+F*m,o[F],!0)}return O(3,n,y)};return H.add(e),e},Ae=(t,e)=>{let a=new Map,l=e?t:t.module||t,c=e||t.instance||t,i=new TextDecoder,p=G(l,"jz:rest");if(p)try{for(let n of JSON.parse(i.decode(p)))a.set(typeof n=="string"?n:n.name,typeof n=="string"?0:n.fixed)}catch{}let A=new Map,g=G(l,"jz:extparam");if(g)try{for(let n of JSON.parse(i.decode(g))){let m=new Set(n.p);n.d&&(m.def=new Map(Object.entries(n.d).map(([s,o])=>[Number(s),o]))),A.set(n.name,m)}}catch{}let d=z(t),h=c.exports.__jz_last_err_bits,_=n=>{if(!(n instanceof WebAssembly.Exception)||!h)throw n;let m=h.value;I[0]=Number(m&0xffffffffn),I[1]=Number(m>>32n&0xffffffffn);let s=d?d.read(M[0]):W(M[0]);if(s instanceof Error)throw s;let o=new Error(typeof s=="string"?s:String(s));throw o.cause=n,o.thrown=s,o},T={},U=(n,m,s,o)=>n?.has(m)?s===void 0&&n.def?.has(m)?n.def.get(m):s:o(s);if(!d||d.scalar){for(let[n,m]of Object.entries(c.exports)){if(typeof m!="function"){T[n]=m;continue}let s=A.get(n),o=m.length;T[n]=(...f)=>{for(;f.length<o;)f.push(void 0);try{return W(m(...f.map((u,y)=>U(s,y,u,R))))}catch(u){_(u)}}}return T}let r=d.wrapVal.bind(d);for(let[n,m]of Object.entries(c.exports))if(a.has(n)&&typeof m=="function"){let s=a.get(n),o=A.get(n);T[n]=(...f)=>{let u=f.slice(0,s).map((y,x)=>U(o,x,y,r));for(;u.length<s;)u.push(V);u.push(d.Array(f.slice(s)));try{return d.read(m.apply(null,u))}catch(y){_(y)}}}else if(typeof m=="function"){let s=A.get(n),o=m.length;T[n]=(...f)=>{for(;f.length<o;)f.push(void 0);try{return d.read(m.apply(null,f.map((u,y)=>U(s,y,u,r))))}catch(u){_(u)}}}else T[n]=m;return T},xe=t=>{let e={extMap:[null],mem:null};return t._interp=t._interp||{},t._interp.__ext_prop=(a,l)=>{let c=S(a),i=S(l),p=e.extMap[$(c)],A=e.mem.read(i);return j(e.mem.wrapVal(typeof p[A]=="function"?p[A].bind(p):p[A]))},t._interp.__ext_has=(a,l)=>e.mem.read(S(l))in e.extMap[$(S(a))]?1:0,t._interp.__ext_set=(a,l,c)=>(e.extMap[$(S(a))][e.mem.read(S(l))]=e.mem.read(S(c)),1),t._interp.__ext_call=(a,l,c)=>{let i=e.extMap[$(S(a))],p=e.mem.read(S(l)),A=e.mem.read(S(c));return j(e.mem.wrapVal(i[p].apply(i,A)))},e},ge=(t,e,a)=>{let l=me(t);if(l.size){if(e.env||(e.env={}),l.has("print")&&!e.env.print){let c=["","",""],i=[],p=g=>{(g===2?console.error:console.log)(c[g]),c[g]=""},A=(g,d,h)=>{let _=K(a,g);c[d]+=String(_),h===32?c[d]+=" ":h===10&&p(d)};e.env.print=(g,d,h)=>{a.mem?A(g,d,h):i.push([g,d,h])},a.flushPrint=()=>{for(let g of i)A(...g);i.length=0}}if(l.has("now")&&!e.env.now&&(e.env.now=c=>c===1&&typeof performance<"u"?performance.now():Date.now()),l.has("rngSeed")&&!e.env.rngSeed&&(e.env.rngSeed=()=>{let c=new Uint32Array(1);return globalThis.crypto?.getRandomValues?globalThis.crypto.getRandomValues(c):c[0]=Math.random()*4294967296>>>0,c[0]|0}),l.has("parseFloat")&&!e.env.parseFloat&&(e.env.parseFloat=c=>{let i=K(a,c);return parseFloat(i)}),l.has("parseInt")&&!e.env.parseInt&&(e.env.parseInt=(c,i)=>{let p=K(a,c);return parseInt(p,i||void 0)}),l.has("setTimeout")||l.has("clearTimeout")){let c=new Map,i=1;l.has("setTimeout")&&!e.env.setTimeout&&(e.env.setTimeout=(p,A,g)=>{let d=i++,h=()=>a.invoke?.(p);if(g){let _=setInterval(h,A);c.set(d,()=>clearInterval(_))}else{let _=setTimeout(()=>{c.delete(d),h()},A);c.set(d,()=>clearTimeout(_))}return d}),l.has("clearTimeout")&&!e.env.clearTimeout&&(e.env.clearTimeout=p=>{let A=c.get(p);return A&&(A(),c.delete(p)),0})}}},ne={length:t=>t.length,charCodeAt:(t,e)=>t.charCodeAt(e)},re=!1,C=!1,ie=()=>{if(re)return C;re=!0;try{let t=new Uint8Array([0,97,115,109,1,0,0,0,1,6,1,96,1,111,1,127,2,24,1,15,...J.encode("wasm:js-string"),6,...J.encode("length"),0,0]),e=new WebAssembly.Module(t,{builtins:["js-string"]});new WebAssembly.Instance(e,{}),C=!0}catch{C=!1}return C},he=(t,e,a)=>{let{needsWasi:l,wasiImports:c}=ue(t,e),i=c||{};if(e._interp&&(i.env={...i.env,...e._interp}),!ie())for(let p of WebAssembly.Module.imports(t))p.module==="wasm:js-string"&&ne[p.name]&&(i["wasm:js-string"]||(i["wasm:js-string"]={}),i["wasm:js-string"][p.name]=ne[p.name]);if(e.imports)for(let[p,A]of Object.entries(e.imports)){i[p]||(i[p]={});for(let g of Object.getOwnPropertyNames(A)){let d=A[g],h=typeof d=="function"?d:d&&typeof d=="object"?d.fn:null;typeof h=="function"&&(i[p][g]=(..._)=>{let T=_.map(r=>{let n=typeof r=="bigint"?S(r):r;return a.mem?a.mem.read(n):W(n)}),U=h.call(A,...T);return j(a.mem?a.mem.wrapVal(U):R(U))})}}ge(t,i,a),e.memory instanceof WebAssembly.Memory&&(H.has(e.memory)||(e.memory=z(e.memory)),i.env||(i.env={}),i.env.memory=e.memory);for(let p of WebAssembly.Module.imports(t))if(p.kind==="global"&&p.module==="env"){let A=globalThis[p.name];if(A!==void 0){i.env||(i.env={});let g=a.extMap.indexOf(A);g===-1&&(g=a.extMap.length,a.extMap.push(A)),i.env[p.name]=new WebAssembly.Global({value:"i64",mutable:!1},j(O(11,0,g)))}}return{imports:i,needsWasi:l}},we=(t,e,a,l,c,i)=>{l&&a._setMemory(e.exports.memory),i.invoke=e.exports.__invoke_closure||null,Z(e);let p=c.memory instanceof WebAssembly.Memory?c.memory:e.exports.memory,A={module:t,instance:e,exports:{...e.exports,memory:p},extMap:i.extMap},g=z(A);return i.mem=g,i.flushPrint?.(),{exports:Ae(A),memory:g?.scalar?null:g,instance:e,module:t}},_e=t=>{if(t instanceof WebAssembly.Module)return t;if(ie())try{return new WebAssembly.Module(t,{builtins:["js-string"]})}catch{return new WebAssembly.Module(t)}return new WebAssembly.Module(t)},Me=(t,e={})=>{let a=xe(e),l=_e(t),{imports:c,needsWasi:i}=he(l,e,a),p=Object.keys(c).some(g=>g!=="_setMemory"),A=new WebAssembly.Instance(l,p?c:void 0);return we(l,A,c,i,e,a)};export{Ue as FALSE_NAN,de as NULL_NAN,Se as TRUE_NAN,V as UNDEF_NAN,v as aux,R as coerce,j as f64ToI64,S as i64ToF64,Me as instantiate,z as memory,$ as offset,O as ptr,_e as toModule,ee as type,Ae as wrap};