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.
- package/README.md +315 -318
- package/bench/README.md +369 -0
- package/bench/bench.svg +102 -0
- package/cli.js +104 -30
- package/dist/interop.js +1 -0
- package/dist/jz.js +6024 -0
- package/index.d.ts +126 -0
- package/index.js +362 -84
- package/interop.js +159 -186
- package/jz.svg +5 -0
- package/jzify/arguments.js +97 -0
- package/jzify/bundler.js +382 -0
- package/jzify/classes.js +328 -0
- package/jzify/hoist-vars.js +177 -0
- package/jzify/index.js +51 -0
- package/jzify/names.js +37 -0
- package/jzify/switch.js +106 -0
- package/jzify/transform.js +349 -0
- package/layout.js +184 -0
- package/module/array.js +377 -176
- package/module/collection.js +639 -145
- package/module/console.js +55 -43
- package/module/core.js +264 -153
- package/module/date.js +15 -3
- package/module/function.js +73 -6
- package/module/index.js +2 -1
- package/module/json.js +226 -61
- package/module/math.js +551 -187
- package/module/number.js +327 -60
- package/module/object.js +474 -184
- package/module/regex.js +255 -25
- package/module/schema.js +24 -6
- package/module/simd.js +117 -0
- package/module/string.js +621 -226
- package/module/symbol.js +1 -1
- package/module/timer.js +9 -14
- package/module/typedarray.js +459 -73
- package/package.json +58 -14
- package/src/abi/index.js +39 -23
- package/src/abi/string.js +38 -41
- package/src/ast.js +460 -0
- package/src/autoload.js +29 -24
- package/src/bridge.js +111 -0
- package/src/compile/analyze-scans.js +824 -0
- package/src/compile/analyze.js +1600 -0
- package/src/compile/emit-assign.js +411 -0
- package/src/compile/emit.js +3512 -0
- package/src/compile/flow-types.js +103 -0
- package/src/{compile.js → compile/index.js} +778 -128
- package/src/{infer.js → compile/infer.js} +62 -98
- package/src/compile/loop-divmod.js +155 -0
- package/src/{narrow.js → compile/narrow.js} +409 -106
- package/src/compile/peel-stencil.js +261 -0
- package/src/compile/plan/advise.js +370 -0
- package/src/compile/plan/common.js +150 -0
- package/src/compile/plan/index.js +122 -0
- package/src/compile/plan/inline.js +682 -0
- package/src/compile/plan/literals.js +1199 -0
- package/src/compile/plan/loops.js +472 -0
- package/src/compile/plan/scope.js +649 -0
- package/src/compile/program-facts.js +423 -0
- package/src/ctx.js +220 -64
- package/src/ir.js +589 -172
- package/src/kind-traits.js +132 -0
- package/src/kind.js +524 -0
- package/src/op-policy.js +57 -0
- package/src/{optimize.js → optimize/index.js} +1432 -473
- package/src/optimize/vectorize.js +4660 -0
- package/src/param-reps.js +65 -0
- package/src/parse.js +44 -0
- package/src/{prepare.js → prepare/index.js} +649 -205
- package/src/prepare/lift-iife.js +149 -0
- package/src/reps.js +116 -0
- package/src/resolve.js +12 -3
- package/src/static.js +208 -0
- package/src/type.js +651 -0
- package/src/{assemble.js → wat/assemble.js} +275 -55
- package/src/wat/optimize.js +3938 -0
- package/transform.js +21 -0
- package/wasi.js +47 -5
- package/src/analyze.js +0 -3818
- package/src/emit.js +0 -3040
- package/src/jzify.js +0 -1580
- package/src/plan.js +0 -2132
- package/src/vectorize.js +0 -1088
- /package/src/{codegen.js → wat/codegen.js} +0 -0
package/src/bridge.js
ADDED
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Stdlib module bridge — `module/*` imports from here, not `src/compile/emit.js`.
|
|
3
|
+
*
|
|
4
|
+
* Emit impls bind on `ctx.bridge` at reset(). Registration: `wat(name, body)`
|
|
5
|
+
* for WAT stdlib, `reg(name, deps, fn)` for emit, or `reg(name, { deps, wat, emit })`
|
|
6
|
+
* to co-register both. `method`/`call` remain sugar for simple `$stdlib` calls.
|
|
7
|
+
*
|
|
8
|
+
* @module bridge
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
import { ctx, emitter } from './ctx.js'
|
|
12
|
+
import { typed, asF64, asI32, asI64 } from './ir.js'
|
|
13
|
+
|
|
14
|
+
export { emitter } from './ctx.js'
|
|
15
|
+
|
|
16
|
+
export const emit = (...a) => ctx.bridge.emit(...a)
|
|
17
|
+
export const flat = (...a) => ctx.bridge.flat(...a)
|
|
18
|
+
export const body = (...a) => ctx.bridge.body(...a)
|
|
19
|
+
export const bool = (...a) => ctx.bridge.bool(...a)
|
|
20
|
+
/** Index expr → i32 IR. */
|
|
21
|
+
export const idx = (...a) => ctx.bridge.idx(...a)
|
|
22
|
+
export const spread = (...a) => ctx.bridge.spread(...a)
|
|
23
|
+
|
|
24
|
+
/** Attach a pre-built handler (e.g. from method/emitter) to ctx.core.emit. */
|
|
25
|
+
export const bind = (name, handler) => {
|
|
26
|
+
ctx.core.emit[name] = handler
|
|
27
|
+
return handler
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/** Register a host import once, idempotent on (module, name). Stdlib modules
|
|
31
|
+
* call this from each use site without re-adding the env/wasi import. */
|
|
32
|
+
export const hostImport = (mod, name, fn) => {
|
|
33
|
+
if (ctx.module.imports.some(i => i[1] === `"${mod}"` && i[2] === `"${name}"`)) return
|
|
34
|
+
ctx.module.imports.push(['import', `"${mod}"`, `"${name}"`, fn])
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
/** WAT stdlib→stdlib deps for `resolveIncludes()`. */
|
|
38
|
+
export const deps = (map) => Object.assign(ctx.core.stdlibDeps, map)
|
|
39
|
+
|
|
40
|
+
/** WAT stdlib body (+ optional deps edge for resolveIncludes). */
|
|
41
|
+
export const wat = (name, body, depNames = []) => {
|
|
42
|
+
ctx.core.stdlib[name] = body
|
|
43
|
+
if (depNames.length) deps({ [name]: depNames })
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/** Emit handler; optionally co-register WAT when `depsOrOpts.wat` is set.
|
|
47
|
+
* reg(name, deps, fn) — emit only
|
|
48
|
+
* reg(name, { deps, wat, emit }) — WAT key inferred from first `__…` dep
|
|
49
|
+
* reg(name, { watKey, deps, wat, emit }) — explicit WAT key when deps differ */
|
|
50
|
+
export const reg = (name, depsOrOpts, maybeFn) => {
|
|
51
|
+
if (typeof depsOrOpts === 'object' && depsOrOpts !== null && !Array.isArray(depsOrOpts)) {
|
|
52
|
+
const o = depsOrOpts
|
|
53
|
+
const depsList = o.deps ?? []
|
|
54
|
+
if (o.wat) {
|
|
55
|
+
const watKey = o.watKey ?? depsList.find(d => d.startsWith('__')) ?? name
|
|
56
|
+
wat(watKey, o.wat, o.watDeps ?? [])
|
|
57
|
+
}
|
|
58
|
+
if (o.emit) {
|
|
59
|
+
const h = emitter(depsList, o.emit)
|
|
60
|
+
ctx.core.emit[name] = h
|
|
61
|
+
return h
|
|
62
|
+
}
|
|
63
|
+
return
|
|
64
|
+
}
|
|
65
|
+
const h = emitter(depsOrOpts, maybeFn)
|
|
66
|
+
ctx.core.emit[name] = h
|
|
67
|
+
return h
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
/** Tag a hand-wrapped handler with `.deps` (pow/** dual lowering). */
|
|
71
|
+
export const tag = (handler, deps) => {
|
|
72
|
+
handler.deps = deps
|
|
73
|
+
return handler
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
/** `fast(firstArg)` → `core`, else `wrap`. Keeps wrap `.deps`. */
|
|
77
|
+
export const dual = (wrap, core, fast) => {
|
|
78
|
+
const h = (a, ...rest) => (fast(a) ? core(a, ...rest) : wrap(a, ...rest))
|
|
79
|
+
h.deps = wrap.deps
|
|
80
|
+
h.argc = wrap.argc ?? wrap.length
|
|
81
|
+
return h
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
const cast = { I: asI64, F: asF64, i: asI32 }
|
|
85
|
+
|
|
86
|
+
const coerce = (sig, nodes) =>
|
|
87
|
+
sig.split('').map((c, i) => cast[c](emit(nodes[i])))
|
|
88
|
+
|
|
89
|
+
const wrap = (fmt, call) => {
|
|
90
|
+
if (fmt === 'i64') return typed(['f64.reinterpret_i64', call], 'f64')
|
|
91
|
+
if (fmt === 'i32') return typed(['f64.convert_i32_s', call], 'f64')
|
|
92
|
+
return typed(call, 'f64')
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
/** `(…args) → call($stdlib, coerced…)`. fmt: f64 · i64 · i32 */
|
|
96
|
+
export const call = (stdlib, sig, fmt = 'f64') => {
|
|
97
|
+
const h = emitter([stdlib], (...nodes) =>
|
|
98
|
+
wrap(fmt, ['call', `$${stdlib}`, ...coerce(sig, nodes)]))
|
|
99
|
+
h.argc = sig.length
|
|
100
|
+
return h
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
/** method `(recv, …args) → call($stdlib, …)`. sig: I · F · i per arg. */
|
|
104
|
+
export const method = (stdlib, sig, ret = 'f64') => {
|
|
105
|
+
const h = emitter([stdlib], (...nodes) => {
|
|
106
|
+
const c = ['call', `$${stdlib}`, ...coerce(sig, nodes)]
|
|
107
|
+
return typed(ret === 'i32' ? ['f64.convert_i32_s', c] : c, 'f64')
|
|
108
|
+
})
|
|
109
|
+
h.argc = sig.length
|
|
110
|
+
return h
|
|
111
|
+
}
|