jz 0.1.0 → 0.1.1
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 +64 -72
- package/index.js +38 -8
- package/module/array.js +7 -2
- package/module/collection.js +3 -1
- package/module/console.js +3 -1
- package/module/core.js +3 -1
- package/module/function.js +4 -3
- package/module/json.js +3 -1
- package/module/math.js +2 -1
- package/module/number.js +3 -7
- package/module/object.js +3 -1
- package/module/regex.js +2 -1
- package/module/schema.js +3 -1
- package/module/string.js +63 -6
- package/module/symbol.js +2 -1
- package/module/timer.js +2 -2
- package/module/typedarray.js +3 -1
- package/package.json +4 -2
- package/src/analyze.js +28 -7
- package/src/autoload.js +175 -0
- package/src/compile.js +58 -1022
- package/src/ctx.js +1 -0
- package/src/emit.js +16 -6
- package/src/host.js +38 -26
- package/src/jzify.js +45 -18
- package/src/key.js +73 -0
- package/src/narrow.js +928 -0
- package/src/plan.js +105 -0
- package/src/prepare.js +151 -215
- package/src/source.js +76 -0
- package/wasi.js +10 -4
package/src/plan.js
ADDED
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
/** Pre-emit compile planning: collect facts, resolve ABIs, and run narrowing. */
|
|
2
|
+
|
|
3
|
+
import { ctx } from './ctx.js'
|
|
4
|
+
import { VAL, valTypeOf, typedElemCtor, typedElemAux, updateGlobalRep, collectProgramFacts } from './analyze.js'
|
|
5
|
+
import { MAX_CLOSURE_ARITY } from './ir.js'
|
|
6
|
+
import narrowSignatures, { specializeBimorphicTyped, refineDynKeys } from './narrow.js'
|
|
7
|
+
|
|
8
|
+
const scanGlobalValueFacts = (root) => {
|
|
9
|
+
if (!root) return
|
|
10
|
+
const stmts = Array.isArray(root) && root[0] === ';' ? root.slice(1) : [root]
|
|
11
|
+
for (const stmt of stmts) {
|
|
12
|
+
if (!Array.isArray(stmt) || (stmt[0] !== 'const' && stmt[0] !== 'let')) continue
|
|
13
|
+
for (const decl of stmt.slice(1)) {
|
|
14
|
+
if (!Array.isArray(decl) || decl[0] !== '=' || typeof decl[1] !== 'string') continue
|
|
15
|
+
const vt = valTypeOf(decl[2])
|
|
16
|
+
if (vt) {
|
|
17
|
+
if (!ctx.scope.globalValTypes) ctx.scope.globalValTypes = new Map()
|
|
18
|
+
ctx.scope.globalValTypes.set(decl[1], vt)
|
|
19
|
+
if (vt === VAL.REGEX && ctx.runtime.regex) ctx.runtime.regex.vars.set(decl[1], decl[2])
|
|
20
|
+
}
|
|
21
|
+
const ctor = typedElemCtor(decl[2])
|
|
22
|
+
if (ctor) {
|
|
23
|
+
if (!ctx.scope.globalTypedElem) ctx.scope.globalTypedElem = new Map()
|
|
24
|
+
ctx.scope.globalTypedElem.set(decl[1], ctor)
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
const unboxConstTypedGlobals = () => {
|
|
31
|
+
if (!ctx.scope.globalTypedElem || !ctx.scope.consts) return
|
|
32
|
+
for (const [name, ctor] of ctx.scope.globalTypedElem) {
|
|
33
|
+
if (!ctx.scope.consts.has(name)) continue
|
|
34
|
+
if (ctx.scope.globalValTypes?.get(name) !== VAL.TYPED) continue
|
|
35
|
+
const aux = typedElemAux(ctor)
|
|
36
|
+
if (aux == null) continue
|
|
37
|
+
const decl = ctx.scope.globals.get(name)
|
|
38
|
+
if (typeof decl !== 'string' || !decl.includes('mut f64')) continue
|
|
39
|
+
ctx.scope.globals.set(name, `(global $${name} (mut i32) (i32.const 0))`)
|
|
40
|
+
ctx.scope.globalTypes.set(name, 'i32')
|
|
41
|
+
updateGlobalRep(name, { ptrKind: VAL.TYPED, ptrAux: aux })
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
const materializeAutoBoxSchemas = (programFacts) => {
|
|
46
|
+
if (!ctx.schema.register) return
|
|
47
|
+
for (const [name, props] of programFacts.propMap) {
|
|
48
|
+
if (ctx.schema.vars.has(name)) {
|
|
49
|
+
const existing = ctx.schema.resolve(name)
|
|
50
|
+
const newProps = [...props].filter(prop => !existing.includes(prop))
|
|
51
|
+
if (newProps.length) {
|
|
52
|
+
const merged = [...existing, ...newProps]
|
|
53
|
+
const mergedId = ctx.schema.register(merged)
|
|
54
|
+
ctx.schema.vars.set(name, mergedId)
|
|
55
|
+
}
|
|
56
|
+
continue
|
|
57
|
+
}
|
|
58
|
+
const valueProps = [...props].filter(prop => !ctx.func.names.has(`${name}$${prop}`))
|
|
59
|
+
if (!valueProps.length) continue
|
|
60
|
+
const allProps = [...props]
|
|
61
|
+
const schema = ['__inner__', ...allProps]
|
|
62
|
+
const schemaId = ctx.schema.register(schema)
|
|
63
|
+
ctx.schema.vars.set(name, schemaId)
|
|
64
|
+
if (ctx.func.names.has(name) && !ctx.scope.globals.has(name))
|
|
65
|
+
ctx.scope.globals.set(name, `(global $${name} (mut f64) (f64.const 0))`)
|
|
66
|
+
if (!ctx.schema.autoBox) ctx.schema.autoBox = new Map()
|
|
67
|
+
ctx.schema.autoBox.set(name, { schemaId, schema })
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
const resolveClosureWidth = (programFacts) => {
|
|
72
|
+
if (!ctx.closure.make) return
|
|
73
|
+
const { hasSpread, hasRest, maxCall, maxDef } = programFacts
|
|
74
|
+
const floor = ctx.closure.floor ?? 0
|
|
75
|
+
ctx.closure.width = (hasSpread && hasRest)
|
|
76
|
+
? MAX_CLOSURE_ARITY
|
|
77
|
+
: Math.min(MAX_CLOSURE_ARITY, Math.max(maxCall, maxDef + (hasRest ? 1 : 0), floor))
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
const canSkipWholeProgramNarrowing = (programFacts) =>
|
|
81
|
+
programFacts.callSites.length === 0 &&
|
|
82
|
+
programFacts.valueUsed.size === 0 &&
|
|
83
|
+
!programFacts.anyDyn &&
|
|
84
|
+
programFacts.propMap.size === 0 &&
|
|
85
|
+
!programFacts.hasSchemaLiterals &&
|
|
86
|
+
!ctx.closure.make
|
|
87
|
+
|
|
88
|
+
export default function plan(ast) {
|
|
89
|
+
scanGlobalValueFacts(ast)
|
|
90
|
+
unboxConstTypedGlobals()
|
|
91
|
+
|
|
92
|
+
const programFacts = collectProgramFacts(ast)
|
|
93
|
+
ctx.types.dynKeyVars = programFacts.dynVars
|
|
94
|
+
ctx.types.anyDynKey = programFacts.anyDyn
|
|
95
|
+
|
|
96
|
+
materializeAutoBoxSchemas(programFacts)
|
|
97
|
+
resolveClosureWidth(programFacts)
|
|
98
|
+
if (canSkipWholeProgramNarrowing(programFacts)) return programFacts
|
|
99
|
+
|
|
100
|
+
narrowSignatures(programFacts, ast)
|
|
101
|
+
specializeBimorphicTyped(programFacts)
|
|
102
|
+
refineDynKeys(programFacts)
|
|
103
|
+
|
|
104
|
+
return programFacts
|
|
105
|
+
}
|