jz 0.5.1 → 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 (86) hide show
  1. package/README.md +315 -318
  2. package/bench/README.md +369 -0
  3. package/bench/bench.svg +102 -0
  4. package/cli.js +104 -30
  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 +362 -84
  9. package/interop.js +159 -186
  10. package/jz.svg +5 -0
  11. package/jzify/arguments.js +97 -0
  12. package/jzify/bundler.js +382 -0
  13. package/jzify/classes.js +328 -0
  14. package/jzify/hoist-vars.js +177 -0
  15. package/jzify/index.js +51 -0
  16. package/jzify/names.js +37 -0
  17. package/jzify/switch.js +106 -0
  18. package/jzify/transform.js +349 -0
  19. package/layout.js +184 -0
  20. package/module/array.js +377 -176
  21. package/module/collection.js +639 -145
  22. package/module/console.js +55 -43
  23. package/module/core.js +264 -153
  24. package/module/date.js +15 -3
  25. package/module/function.js +73 -6
  26. package/module/index.js +2 -1
  27. package/module/json.js +226 -61
  28. package/module/math.js +551 -187
  29. package/module/number.js +327 -60
  30. package/module/object.js +474 -184
  31. package/module/regex.js +255 -25
  32. package/module/schema.js +24 -6
  33. package/module/simd.js +117 -0
  34. package/module/string.js +621 -226
  35. package/module/symbol.js +1 -1
  36. package/module/timer.js +9 -14
  37. package/module/typedarray.js +459 -73
  38. package/package.json +58 -14
  39. package/src/abi/index.js +39 -23
  40. package/src/abi/string.js +38 -41
  41. package/src/ast.js +460 -0
  42. package/src/autoload.js +29 -24
  43. package/src/bridge.js +111 -0
  44. package/src/compile/analyze-scans.js +824 -0
  45. package/src/compile/analyze.js +1600 -0
  46. package/src/compile/emit-assign.js +411 -0
  47. package/src/compile/emit.js +3512 -0
  48. package/src/compile/flow-types.js +103 -0
  49. package/src/{compile.js → compile/index.js} +778 -128
  50. package/src/{infer.js → compile/infer.js} +62 -98
  51. package/src/compile/loop-divmod.js +155 -0
  52. package/src/{narrow.js → compile/narrow.js} +409 -106
  53. package/src/compile/peel-stencil.js +261 -0
  54. package/src/compile/plan/advise.js +370 -0
  55. package/src/compile/plan/common.js +150 -0
  56. package/src/compile/plan/index.js +122 -0
  57. package/src/compile/plan/inline.js +682 -0
  58. package/src/compile/plan/literals.js +1199 -0
  59. package/src/compile/plan/loops.js +472 -0
  60. package/src/compile/plan/scope.js +649 -0
  61. package/src/compile/program-facts.js +423 -0
  62. package/src/ctx.js +220 -64
  63. package/src/ir.js +589 -172
  64. package/src/kind-traits.js +132 -0
  65. package/src/kind.js +524 -0
  66. package/src/op-policy.js +57 -0
  67. package/src/{optimize.js → optimize/index.js} +1432 -473
  68. package/src/optimize/vectorize.js +4660 -0
  69. package/src/param-reps.js +65 -0
  70. package/src/parse.js +44 -0
  71. package/src/{prepare.js → prepare/index.js} +649 -205
  72. package/src/prepare/lift-iife.js +149 -0
  73. package/src/reps.js +116 -0
  74. package/src/resolve.js +12 -3
  75. package/src/static.js +208 -0
  76. package/src/type.js +651 -0
  77. package/src/{assemble.js → wat/assemble.js} +275 -55
  78. package/src/wat/optimize.js +3938 -0
  79. package/transform.js +21 -0
  80. package/wasi.js +47 -5
  81. package/src/analyze.js +0 -3818
  82. package/src/emit.js +0 -3040
  83. package/src/jzify.js +0 -1580
  84. package/src/plan.js +0 -2132
  85. package/src/vectorize.js +0 -1088
  86. /package/src/{codegen.js → wat/codegen.js} +0 -0
@@ -0,0 +1,65 @@
1
+ /**
2
+ * Cross-call paramReps lattice — Map<funcName, Map<paramIdx, ValueRep fields>>.
3
+ *
4
+ * Cycle-free leaf consumed by narrow.js (fixpoint) and infer.js (call-site
5
+ * evidence producers).
6
+ *
7
+ * THE LATTICE (per field). Three states:
8
+ * - BOTTOM = `undefined` — unobserved / "no site has spoken yet".
9
+ * - a value — consensus across all sites seen so far.
10
+ * - TOP = `null` — conflict: two sites disagreed. Sticky.
11
+ *
12
+ * The meet is monotone: meet(BOTTOM, x) = x, meet(x, x) = x, meet(x, y≠x) = TOP,
13
+ * meet(TOP, _) = TOP. Over a finite height-2 lattice it converges with NO resets —
14
+ * narrow.js's clearStickyNull (which used to un-stick a spurious "can't tell yet"
15
+ * poison) is gone entirely (root B closed). Two complementary policies keep it so:
16
+ *
17
+ * - `val` runs SOFT (narrow.js mergeRule soft=true): a can't-tell-yet site is
18
+ * skipped (stays BOTTOM), never poisoned, so a later pass — e.g. once pointer-
19
+ * ABI enrichment puts VAL.TYPED into callerValTypes — simply fills it in. A
20
+ * signature-mutating consumer (applyPointerParamAbi) can't trust this partial
21
+ * soft value, so it re-folds the sites HARD (hardParamVal); a final hard sweep
22
+ * settles `val` for emit + late readers (specializeBimorphicTyped, …).
23
+ * - `schemaId` (and the others) stay HARD, but no longer get stuck: narrowValResults
24
+ * is hoisted ABOVE the param lattice, so a call arg `f()` resolves to its VAL
25
+ * result on the first pass and the can't-tell poison never forms.
26
+ *
27
+ * @module param-reps
28
+ */
29
+
30
+ /** Build `paramName → fact` lookup for a caller's already-narrowed param facts. */
31
+ export const paramFactsOf = (paramReps, callerFunc, key) => {
32
+ if (!callerFunc) return null
33
+ const m = paramReps.get(callerFunc.name)
34
+ if (!m) return null
35
+ let out = null
36
+ for (const [k, r] of m) {
37
+ const v = r[key]
38
+ if (v != null && k < callerFunc.sig.params.length) {
39
+ out ||= new Map()
40
+ out.set(callerFunc.sig.params[k].name, v)
41
+ }
42
+ }
43
+ return out
44
+ }
45
+
46
+ /** The meet itself: fold `observed` into a param's ValueRep field. BOTTOM
47
+ * (undefined) → observed; equal → unchanged; disagreement → TOP (null, sticky).
48
+ * A null `observed` is "can't tell" — whether that means BOTTOM (skip) or TOP
49
+ * (poison) is the *caller's* policy: narrow.js's soft mergeRule skips before
50
+ * calling here; the hard mergeRule / missing-arg path poisons by passing null. */
51
+ export const mergeParamFact = (rep, key, observed) => {
52
+ if (rep[key] === null) return // already TOP — sticky
53
+ if (observed == null) { rep[key] = null; return } // caller chose to poison (hard path)
54
+ if (rep[key] === undefined) rep[key] = observed // BOTTOM → first observation
55
+ else if (rep[key] !== observed) rep[key] = null // disagreement → TOP
56
+ }
57
+
58
+ /** Get-or-create per-param rep at (funcName, paramIdx) on a paramReps map. */
59
+ export const ensureParamRep = (paramReps, funcName, k) => {
60
+ let m = paramReps.get(funcName)
61
+ if (!m) { m = new Map(); paramReps.set(funcName, m) }
62
+ let r = m.get(k)
63
+ if (!r) { r = {}; m.set(k, r) }
64
+ return r
65
+ }
package/src/parse.js ADDED
@@ -0,0 +1,44 @@
1
+ /**
2
+ * jz's parser entry — subscript's jessie dialect with one jz-specific override.
3
+ *
4
+ * `NaN` parses to the self-describing `['nan']` marker rather than subscript's
5
+ * default `[, NaN]` value-literal. A raw number-NaN (0x7FF8…) is ambiguous with
6
+ * jz's NaN-boxed value space: as the literal flows through the self-host kernel's
7
+ * parse/marshalling path it decodes back as a boxed value (object), so `() => NaN`
8
+ * would miscompile to `f64.const 0`. The string-tagged marker can't be mistaken
9
+ * for a number, survives intact, and emit() lowers it to the canonical quiet NaN
10
+ * (see compile/emit.js `op === 'nan'`). This mirrors subscript's own reason for
11
+ * encoding `undefined` as `[]` instead of `[, undefined]` (feature/literal.js).
12
+ * Infinity is 0x7FF0 — outside the NaN-box space — so it survives as a plain
13
+ * literal and needs no override.
14
+ */
15
+ import { parse as jessieParse, token } from 'subscript/feature/jessie'
16
+
17
+ // Strip a leading `#!` shebang line before subscript sees it. subscript registers the
18
+ // shebang via `parse.comment['#!']='\n'` (feature/shebang.js) on a literal-seeded object,
19
+ // then enumerates it — a cross-module dynamic-extension of a fixed-schema object that the
20
+ // self-host kernel doesn't surface (the added key is stored but unenumerated). An explicit
21
+ // strip is the conventional parser responsibility anyway (Node, V8 do the same), is
22
+ // host/kernel-identical, and is independent of object-model internals.
23
+ const parse = (src) => {
24
+ if (typeof src === 'string' && src.charCodeAt(0) === 35 && src.charCodeAt(1) === 33) {
25
+ const nl = src.indexOf('\n')
26
+ src = nl < 0 ? '' : src.slice(nl)
27
+ }
28
+ return jessieParse(src)
29
+ }
30
+
31
+ token('NaN', 200, a => !a && ['nan'])
32
+
33
+ // `true`/`false` parse to the self-describing `['bool', 1|0]` marker rather than
34
+ // subscript's `[, true]`/`[, false]` value-literal. The raw JS boolean degrades to
35
+ // the bare number 1/0 as the literal flows through the self-host kernel's
36
+ // parse/marshalling path, so `valTypeOf` reads VAL.NUMBER and the value loses its
37
+ // VAL.BOOL kind — `typeof true` returns "number", `JSON.stringify(true)` yields "1".
38
+ // The marker (op `'bool'`) is type-tagged by op, not by its degradable payload, so
39
+ // valTypeOf returns VAL.BOOL unconditionally; emit lowers it to the same 0/1 carrier
40
+ // (no perf cost). Same rationale as the `NaN` → `['nan']` override above.
41
+ token('true', 200, a => !a && ['bool', 1])
42
+ token('false', 200, a => !a && ['bool', 0])
43
+
44
+ export { parse }