@loopdive/js2 0.57.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 (233) hide show
  1. package/CHANGELOG.md +1425 -0
  2. package/LICENSE +189 -0
  3. package/README.md +451 -0
  4. package/dist/checker/index.d.ts +117 -0
  5. package/dist/checker/language-service.d.ts +39 -0
  6. package/dist/checker/node-capability-map.d.ts +63 -0
  7. package/dist/checker/type-mapper.d.ts +84 -0
  8. package/dist/cjs-rewrite.d.ts +19 -0
  9. package/dist/cli.d.ts +2 -0
  10. package/dist/cli.js +363 -0
  11. package/dist/codegen/accessor-driver.d.ts +97 -0
  12. package/dist/codegen/any-helpers.d.ts +72 -0
  13. package/dist/codegen/array-element-typing.d.ts +46 -0
  14. package/dist/codegen/array-holes.d.ts +69 -0
  15. package/dist/codegen/array-methods.d.ts +68 -0
  16. package/dist/codegen/array-object-proto.d.ts +64 -0
  17. package/dist/codegen/array-reduce-fusion.d.ts +31 -0
  18. package/dist/codegen/array-to-primitive.d.ts +28 -0
  19. package/dist/codegen/async-cps.d.ts +239 -0
  20. package/dist/codegen/async-scheduler.d.ts +349 -0
  21. package/dist/codegen/binary-ops.d.ts +78 -0
  22. package/dist/codegen/binding-info.d.ts +31 -0
  23. package/dist/codegen/builtin-scaffold.d.ts +98 -0
  24. package/dist/codegen/builtin-static-globals.d.ts +8 -0
  25. package/dist/codegen/builtin-tags.d.ts +189 -0
  26. package/dist/codegen/case-convert-native.d.ts +12 -0
  27. package/dist/codegen/case-tables.d.ts +4 -0
  28. package/dist/codegen/class-bodies.d.ts +41 -0
  29. package/dist/codegen/class-member-keys.d.ts +33 -0
  30. package/dist/codegen/class-to-primitive.d.ts +39 -0
  31. package/dist/codegen/closed-method-dispatch.d.ts +42 -0
  32. package/dist/codegen/closures.d.ts +285 -0
  33. package/dist/codegen/coercion-engine.d.ts +154 -0
  34. package/dist/codegen/coercion-plan.d.ts +29 -0
  35. package/dist/codegen/context/bodies.d.ts +4 -0
  36. package/dist/codegen/context/create-context.d.ts +4 -0
  37. package/dist/codegen/context/errors.d.ts +39 -0
  38. package/dist/codegen/context/locals.d.ts +69 -0
  39. package/dist/codegen/context/source-pos.d.ts +5 -0
  40. package/dist/codegen/context/speculative.d.ts +95 -0
  41. package/dist/codegen/context/types.d.ts +1936 -0
  42. package/dist/codegen/custom-iterable.d.ts +34 -0
  43. package/dist/codegen/dataview-native.d.ts +51 -0
  44. package/dist/codegen/date-parse-native.d.ts +13 -0
  45. package/dist/codegen/dead-elimination.d.ts +26 -0
  46. package/dist/codegen/declarations.d.ts +147 -0
  47. package/dist/codegen/deno-api.d.ts +11 -0
  48. package/dist/codegen/destructuring-params.d.ts +102 -0
  49. package/dist/codegen/dyn-read.d.ts +26 -0
  50. package/dist/codegen/eval-tiering.d.ts +19 -0
  51. package/dist/codegen/expressions/assignment.d.ts +61 -0
  52. package/dist/codegen/expressions/builtins.d.ts +26 -0
  53. package/dist/codegen/expressions/calls-closures.d.ts +54 -0
  54. package/dist/codegen/expressions/calls-guards.d.ts +49 -0
  55. package/dist/codegen/expressions/calls-optional.d.ts +4 -0
  56. package/dist/codegen/expressions/calls.d.ts +83 -0
  57. package/dist/codegen/expressions/eval-inline.d.ts +24 -0
  58. package/dist/codegen/expressions/extern.d.ts +67 -0
  59. package/dist/codegen/expressions/fnctor-prototype.d.ts +52 -0
  60. package/dist/codegen/expressions/helpers.d.ts +212 -0
  61. package/dist/codegen/expressions/identifiers.d.ts +57 -0
  62. package/dist/codegen/expressions/late-imports.d.ts +81 -0
  63. package/dist/codegen/expressions/logical-ops.d.ts +18 -0
  64. package/dist/codegen/expressions/misc.d.ts +27 -0
  65. package/dist/codegen/expressions/new-super.d.ts +25 -0
  66. package/dist/codegen/expressions/promise-subclass.d.ts +38 -0
  67. package/dist/codegen/expressions/proto-override.d.ts +63 -0
  68. package/dist/codegen/expressions/unary-updates.d.ts +21 -0
  69. package/dist/codegen/expressions/unary.d.ts +6 -0
  70. package/dist/codegen/expressions.d.ts +31 -0
  71. package/dist/codegen/fallback-telemetry.d.ts +53 -0
  72. package/dist/codegen/fixups.d.ts +80 -0
  73. package/dist/codegen/fmod.d.ts +10 -0
  74. package/dist/codegen/fnctor-escape-gate.d.ts +92 -0
  75. package/dist/codegen/function-body.d.ts +52 -0
  76. package/dist/codegen/generators-native.d.ts +92 -0
  77. package/dist/codegen/helpers/body-references-own-this.d.ts +22 -0
  78. package/dist/codegen/helpers/body-uses-arguments.d.ts +12 -0
  79. package/dist/codegen/helpers/is-strict-function.d.ts +52 -0
  80. package/dist/codegen/host-import-allowlist.d.ts +140 -0
  81. package/dist/codegen/index.d.ts +500 -0
  82. package/dist/codegen/ir-tail-call.d.ts +8 -0
  83. package/dist/codegen/iterator-native.d.ts +44 -0
  84. package/dist/codegen/json-codec-native.d.ts +78 -0
  85. package/dist/codegen/json-runtime.d.ts +35 -0
  86. package/dist/codegen/json-standalone.d.ts +25 -0
  87. package/dist/codegen/linear-uint8-analysis.d.ts +46 -0
  88. package/dist/codegen/linear-uint8-arena.d.ts +7 -0
  89. package/dist/codegen/linear-uint8-codegen.d.ts +103 -0
  90. package/dist/codegen/linear-uint8-signatures.d.ts +26 -0
  91. package/dist/codegen/literals.d.ts +115 -0
  92. package/dist/codegen/map-runtime.d.ts +142 -0
  93. package/dist/codegen/math-helpers.d.ts +7 -0
  94. package/dist/codegen/member-get-dispatch.d.ts +42 -0
  95. package/dist/codegen/member-set-dispatch.d.ts +28 -0
  96. package/dist/codegen/native-proto.d.ts +98 -0
  97. package/dist/codegen/native-regex.d.ts +158 -0
  98. package/dist/codegen/native-strings.d.ts +146 -0
  99. package/dist/codegen/new-target.d.ts +30 -0
  100. package/dist/codegen/node-fs-api.d.ts +47 -0
  101. package/dist/codegen/number-format-native.d.ts +9 -0
  102. package/dist/codegen/number-ryu.d.ts +27 -0
  103. package/dist/codegen/object-ops.d.ts +94 -0
  104. package/dist/codegen/object-runtime.d.ts +171 -0
  105. package/dist/codegen/parse-number-native.d.ts +10 -0
  106. package/dist/codegen/peephole.d.ts +6 -0
  107. package/dist/codegen/property-access.d.ts +294 -0
  108. package/dist/codegen/raw-wasi-api.d.ts +13 -0
  109. package/dist/codegen/regex/bytecode.d.ts +140 -0
  110. package/dist/codegen/regex/casefold.d.ts +41 -0
  111. package/dist/codegen/regex/compile.d.ts +51 -0
  112. package/dist/codegen/regex/parse.d.ts +76 -0
  113. package/dist/codegen/regex/unicode.d.ts +42 -0
  114. package/dist/codegen/regex/vm.d.ts +24 -0
  115. package/dist/codegen/regexp-standalone.d.ts +350 -0
  116. package/dist/codegen/registry/error-types.d.ts +38 -0
  117. package/dist/codegen/registry/imports.d.ts +46 -0
  118. package/dist/codegen/registry/types.d.ts +59 -0
  119. package/dist/codegen/set-algebra.d.ts +17 -0
  120. package/dist/codegen/set-runtime.d.ts +74 -0
  121. package/dist/codegen/shared.d.ts +111 -0
  122. package/dist/codegen/stack-balance.d.ts +43 -0
  123. package/dist/codegen/statements/control-flow.d.ts +25 -0
  124. package/dist/codegen/statements/destructuring.d.ts +177 -0
  125. package/dist/codegen/statements/exceptions.d.ts +11 -0
  126. package/dist/codegen/statements/functions.d.ts +1 -0
  127. package/dist/codegen/statements/index.d.ts +1 -0
  128. package/dist/codegen/statements/loops.d.ts +7 -0
  129. package/dist/codegen/statements/nested-declarations.d.ts +78 -0
  130. package/dist/codegen/statements/shared.d.ts +38 -0
  131. package/dist/codegen/statements/tdz.d.ts +43 -0
  132. package/dist/codegen/statements/variables.d.ts +3 -0
  133. package/dist/codegen/statements.d.ts +9 -0
  134. package/dist/codegen/string-builder.d.ts +131 -0
  135. package/dist/codegen/string-ops.d.ts +87 -0
  136. package/dist/codegen/struct-accessor-closure.d.ts +36 -0
  137. package/dist/codegen/symbol-native.d.ts +55 -0
  138. package/dist/codegen/temporal-native.d.ts +8 -0
  139. package/dist/codegen/timsort.d.ts +2 -0
  140. package/dist/codegen/type-coercion.d.ts +123 -0
  141. package/dist/codegen/typeof-delete.d.ts +38 -0
  142. package/dist/codegen/uri-encoding-native.d.ts +33 -0
  143. package/dist/codegen/value-tags.d.ts +74 -0
  144. package/dist/codegen/walk-instructions.d.ts +20 -0
  145. package/dist/codegen/weak-collections-runtime.d.ts +16 -0
  146. package/dist/codegen/with-scope.d.ts +106 -0
  147. package/dist/codegen-linear/c-abi.d.ts +74 -0
  148. package/dist/codegen-linear/context.d.ts +86 -0
  149. package/dist/codegen-linear/index.d.ts +28 -0
  150. package/dist/codegen-linear/layout.d.ts +39 -0
  151. package/dist/codegen-linear/runtime.d.ts +161 -0
  152. package/dist/codegen-linear/simd.d.ts +7 -0
  153. package/dist/compiler/define-substitution.d.ts +27 -0
  154. package/dist/compiler/early-errors/assignment.d.ts +26 -0
  155. package/dist/compiler/early-errors/context.d.ts +17 -0
  156. package/dist/compiler/early-errors/duplicates.d.ts +20 -0
  157. package/dist/compiler/early-errors/index.d.ts +11 -0
  158. package/dist/compiler/early-errors/labels.d.ts +13 -0
  159. package/dist/compiler/early-errors/module-rules.d.ts +36 -0
  160. package/dist/compiler/early-errors/node-checks.d.ts +7 -0
  161. package/dist/compiler/early-errors/predicates.d.ts +140 -0
  162. package/dist/compiler/early-errors/tdz.d.ts +17 -0
  163. package/dist/compiler/import-manifest.d.ts +18 -0
  164. package/dist/compiler/output.d.ts +46 -0
  165. package/dist/compiler/validation.d.ts +45 -0
  166. package/dist/compiler.d.ts +48 -0
  167. package/dist/define-substitution-BcUeKC2A.js +109 -0
  168. package/dist/emit/binary.d.ts +50 -0
  169. package/dist/emit/c-header.d.ts +23 -0
  170. package/dist/emit/canonical-recgroup.d.ts +86 -0
  171. package/dist/emit/encoder.d.ts +28 -0
  172. package/dist/emit/object.d.ts +14 -0
  173. package/dist/emit/opcodes.d.ts +464 -0
  174. package/dist/emit/sourcemap.d.ts +33 -0
  175. package/dist/emit/wat.d.ts +6 -0
  176. package/dist/env.d.ts +46 -0
  177. package/dist/import-resolver.d.ts +68 -0
  178. package/dist/index.d.ts +486 -0
  179. package/dist/index.js +755 -0
  180. package/dist/ir/alloc-registry.d.ts +75 -0
  181. package/dist/ir/analysis/encoding.d.ts +38 -0
  182. package/dist/ir/analysis/escape.d.ts +32 -0
  183. package/dist/ir/analysis/lattice.d.ts +72 -0
  184. package/dist/ir/analysis/ownership.d.ts +31 -0
  185. package/dist/ir/analysis/stack-alloc.d.ts +20 -0
  186. package/dist/ir/backend/bytecode-emitter.d.ts +237 -0
  187. package/dist/ir/backend/bytecode-vm.d.ts +74 -0
  188. package/dist/ir/backend/emitter.d.ts +121 -0
  189. package/dist/ir/backend/handles.d.ts +133 -0
  190. package/dist/ir/backend/legality.d.ts +9 -0
  191. package/dist/ir/backend/linear-emitter.d.ts +41 -0
  192. package/dist/ir/backend/wasmgc-emitter.d.ts +43 -0
  193. package/dist/ir/builder.d.ts +401 -0
  194. package/dist/ir/from-ast.d.ts +192 -0
  195. package/dist/ir/index.d.ts +16 -0
  196. package/dist/ir/integration.d.ts +27 -0
  197. package/dist/ir/lower.d.ts +203 -0
  198. package/dist/ir/nodes.d.ts +1452 -0
  199. package/dist/ir/passes/alloc-discipline.d.ts +19 -0
  200. package/dist/ir/passes/constant-fold.d.ts +7 -0
  201. package/dist/ir/passes/dead-code.d.ts +18 -0
  202. package/dist/ir/passes/inline-small.d.ts +7 -0
  203. package/dist/ir/passes/monomorphize.d.ts +21 -0
  204. package/dist/ir/passes/simplify-cfg.d.ts +19 -0
  205. package/dist/ir/passes/tagged-union-types.d.ts +45 -0
  206. package/dist/ir/passes/tagged-unions.d.ts +22 -0
  207. package/dist/ir/propagate.d.ts +135 -0
  208. package/dist/ir/select.d.ts +81 -0
  209. package/dist/ir/types.d.ts +832 -0
  210. package/dist/ir/verify-alloc.d.ts +18 -0
  211. package/dist/ir/verify.d.ts +7 -0
  212. package/dist/link/index.d.ts +11 -0
  213. package/dist/link/isolation.d.ts +24 -0
  214. package/dist/link/linker.d.ts +37 -0
  215. package/dist/link/reader.d.ts +158 -0
  216. package/dist/link/resolver.d.ts +19 -0
  217. package/dist/optimize.d.ts +54 -0
  218. package/dist/optimize.js +262 -0
  219. package/dist/position-map.d.ts +64 -0
  220. package/dist/process-stdin-prelude.d.ts +16 -0
  221. package/dist/resolve.d.ts +82 -0
  222. package/dist/runtime/builtins.d.ts +1 -0
  223. package/dist/runtime-C-4q_KwU.js +164438 -0
  224. package/dist/runtime-containment.d.ts +6 -0
  225. package/dist/runtime-eval.d.ts +132 -0
  226. package/dist/runtime-instantiate.d.ts +16 -0
  227. package/dist/runtime.d.ts +128 -0
  228. package/dist/runtime.js +12 -0
  229. package/dist/shape-inference.d.ts +20 -0
  230. package/dist/treeshake.d.ts +17 -0
  231. package/dist/ts-api.d.ts +30 -0
  232. package/dist/wit-generator.d.ts +18 -0
  233. package/package.json +187 -0
@@ -0,0 +1,1452 @@
1
+ import { ValType } from './types.js';
2
+ export interface IrFuncRef {
3
+ readonly kind: "func";
4
+ /** Unique function name (same namespace as `ctx.funcMap`). */
5
+ readonly name: string;
6
+ }
7
+ export interface IrGlobalRef {
8
+ readonly kind: "global";
9
+ /** Unique global name (same namespace as `ctx.globalMap` or similar). */
10
+ readonly name: string;
11
+ }
12
+ export interface IrTypeRef {
13
+ readonly kind: "type";
14
+ /** Unique WasmGC type name (same namespace as `ctx.typeNames`). */
15
+ readonly name: string;
16
+ }
17
+ export type IrSymRef = IrFuncRef | IrGlobalRef | IrTypeRef;
18
+ /**
19
+ * A canonical object shape — a sorted list of named fields with their IR
20
+ * types. Equal shapes (same names, same types in the same canonical order)
21
+ * resolve to the same WasmGC struct via the lowerer's resolver. Carrying
22
+ * the field types as `IrType` (not `ValType`) lets a struct-of-string or
23
+ * struct-of-object compose cleanly: the resolver recursively materializes
24
+ * field types when registering the WasmGC struct.
25
+ *
26
+ * Names must be unique. The constructor in `from-ast.ts` sorts by name
27
+ * before constructing the IrType so structurally-identical shapes compare
28
+ * equal regardless of source order.
29
+ */
30
+ export interface IrObjectShape {
31
+ readonly fields: readonly {
32
+ readonly name: string;
33
+ readonly type: IrType;
34
+ }[];
35
+ }
36
+ /**
37
+ * Slice 3 (#1169c) — a closure's caller-visible signature. Used both as
38
+ * the IR-level type discriminator for closure values and as the resolver
39
+ * lookup key for the supertype struct + lifted func type. The implicit
40
+ * `__self` struct param at index 0 of the lifted body is NOT present in
41
+ * `params` — it's added by the resolver when synthesizing the func type.
42
+ */
43
+ export interface IrClosureSignature {
44
+ readonly params: readonly IrType[];
45
+ readonly returnType: IrType;
46
+ }
47
+ /**
48
+ * Slice 4 (#1169d) — descriptor for one field on a class.
49
+ */
50
+ export interface IrClassFieldDescriptor {
51
+ readonly name: string;
52
+ readonly type: IrType;
53
+ }
54
+ /**
55
+ * Slice 4 (#1169d) — descriptor for one instance method on a class. The
56
+ * implicit `this` receiver is NOT listed in `params` — the lowerer
57
+ * prepends it when emitting the call. A void method has
58
+ * `returnType: null`.
59
+ */
60
+ export interface IrClassMethodDescriptor {
61
+ readonly name: string;
62
+ readonly params: readonly IrType[];
63
+ readonly returnType: IrType | null;
64
+ }
65
+ /**
66
+ * Slice 4 (#1169d) — symbolic descriptor for a class declared in the
67
+ * compilation unit. Carries the structural info the IR builder needs to
68
+ * type-check `new`/field-access/method-call expressions on instances of
69
+ * this class without consulting the lowering resolver.
70
+ *
71
+ * - `className` unique discriminator (one class per name per unit)
72
+ * - `fields` user fields in canonical order (alphabetical)
73
+ * — the lowerer maps each field `name` to a Wasm
74
+ * struct field index via `resolveClass`, which knows
75
+ * about the legacy `__tag` prefix at field 0.
76
+ * - `methods` instance methods with caller-visible signatures.
77
+ * Static methods are out of slice 4 scope and are
78
+ * not listed.
79
+ * - `constructorParams` user-visible param list for `new C(...)`.
80
+ *
81
+ * Class methods themselves are NOT IR-claimable in slice 4 — they remain
82
+ * on the legacy class-bodies path. The IR only references them by name
83
+ * (`<className>_<methodName>`) at call-site lowering, where the resolver
84
+ * maps the name to the legacy-allocated funcIdx.
85
+ */
86
+ export interface IrClassShape {
87
+ readonly className: string;
88
+ readonly fields: readonly IrClassFieldDescriptor[];
89
+ readonly methods: readonly IrClassMethodDescriptor[];
90
+ readonly constructorParams: readonly IrType[];
91
+ }
92
+ export type IrType = {
93
+ readonly kind: "val";
94
+ readonly val: ValType;
95
+ readonly signed?: boolean;
96
+ } | {
97
+ readonly kind: "string";
98
+ } | {
99
+ readonly kind: "object";
100
+ readonly shape: IrObjectShape;
101
+ } | {
102
+ readonly kind: "closure";
103
+ readonly signature: IrClosureSignature;
104
+ } | {
105
+ readonly kind: "class";
106
+ readonly shape: IrClassShape;
107
+ } | {
108
+ readonly kind: "extern";
109
+ readonly className: string;
110
+ } | {
111
+ readonly kind: "union";
112
+ readonly members: readonly IrType[];
113
+ } | {
114
+ readonly kind: "boxed";
115
+ readonly inner: IrType;
116
+ };
117
+ /** Wrap a plain ValType as an IrType — the common path for Phase 1/2 callers. */
118
+ export declare function irVal(v: ValType): IrType;
119
+ /**
120
+ * Wrap a ValType as an IrType with an explicit signedness fact (#1126 Stage 1).
121
+ * Use this only for `i32` ValTypes where the value-domain (signed `int32` vs
122
+ * unsigned `uint32`) is known. For non-i32 ValTypes the `signed` flag is
123
+ * meaningless; callers should use `irVal()` instead.
124
+ *
125
+ * The flag is read by Stage 3 emit decisions (signed vs unsigned shifts,
126
+ * comparisons, conversions back to f64). For Stage 1 it is purely additive —
127
+ * no existing emitter consults it yet.
128
+ */
129
+ export declare function irValSigned(v: ValType, signed: boolean): IrType;
130
+ /**
131
+ * Return the single underlying ValType for a `val`-kind IrType, else `null`.
132
+ * Call sites that previously did `t.kind === "f64"` against an `IrType` now
133
+ * do `asVal(t)?.kind === "f64"`.
134
+ */
135
+ export declare function asVal(t: IrType): ValType | null;
136
+ /**
137
+ * Structural equality for IrType. Two types are equal iff they have the same
138
+ * shape and their underlying ValType members compare structurally equal.
139
+ *
140
+ * Used by the verifier and by migration assertions. We keep the implementation
141
+ * local to avoid pulling a full deep-equal dep into the IR layer.
142
+ */
143
+ export declare function irTypeEquals(a: IrType, b: IrType): boolean;
144
+ /**
145
+ * Slice 4 (#1169d): structural equality for class shapes. `className` is
146
+ * the discriminator — every class is unique within a compilation unit, so
147
+ * two `IrClassShape` values with the same `className` represent the same
148
+ * class. We don't recurse into `fields` / `methods` / `constructorParams`
149
+ * because they're a deterministic projection of `className` (one
150
+ * declaration per class per unit). Cross-unit class types are out of
151
+ * slice 4 scope.
152
+ */
153
+ export declare function classShapeEquals(a: IrClassShape, b: IrClassShape): boolean;
154
+ /**
155
+ * Structural equality for closure signatures. Recurses through param /
156
+ * return IrTypes via `irTypeEquals` so a closure-of-closure or a
157
+ * closure-of-object compares correctly.
158
+ */
159
+ export declare function closureSignatureEquals(a: IrClosureSignature, b: IrClosureSignature): boolean;
160
+ /**
161
+ * Structural equality for object shapes. Field lists must be parallel
162
+ * (same length, same order, same name and IrType per slot). Recursing
163
+ * via `irTypeEquals` lets nested object fields compare correctly.
164
+ */
165
+ export declare function objectShapeEquals(a: IrObjectShape, b: IrObjectShape): boolean;
166
+ /**
167
+ * An SSA value ID — uniquely identifies one defining instruction or block arg
168
+ * within one IrFunction. Values are NOT shared across functions.
169
+ *
170
+ * Represented as a branded number for cheap comparison + map-key use. `-1`
171
+ * is reserved as an intentionally invalid sentinel and must never appear in
172
+ * an emitted IR graph.
173
+ */
174
+ export type IrValueId = number & {
175
+ readonly __brand: "IrValueId";
176
+ };
177
+ export declare function asValueId(n: number): IrValueId;
178
+ /**
179
+ * Stable identity of an allocation site (#1586).
180
+ *
181
+ * Unlike {@link IrValueId} — which is a per-function SSA index that inlining
182
+ * and monomorphization renumber — an `AllocSiteId` is **module-global** and
183
+ * travels on the instruction itself (`IrInstrBase.alloc`). It survives every
184
+ * IR transformation: passes preserve it through value-preserving rewrites,
185
+ * alias it through fusion, and retire it on deletion (see the pass-discipline
186
+ * rules in docs/adr/0013-ir-allocation-sites.md).
187
+ *
188
+ * Identity MUST NOT be keyed on `IrValueId` — that breaks under renumbering.
189
+ */
190
+ export type AllocSiteId = number & {
191
+ readonly __brand: "AllocSiteId";
192
+ };
193
+ export declare function asAllocSiteId(n: number): AllocSiteId;
194
+ /**
195
+ * The category of value an allocation site brings into existence. Mirrors the
196
+ * value-creating IR instr kinds (object.new, closure.new, …). Black-box
197
+ * built-in internal allocations are out of scope (#1586 non-goals).
198
+ */
199
+ export type AllocKind = "object" | "array" | "string" | "closure" | "refcell" | "box" | "extern" | "iterator" | "generator";
200
+ /** Allocate sequential IrValueIds within a function. */
201
+ export declare class IrValueIdAllocator {
202
+ private next;
203
+ fresh(): IrValueId;
204
+ get count(): number;
205
+ }
206
+ export type IrConst = {
207
+ readonly kind: "i32";
208
+ readonly value: number;
209
+ } | {
210
+ readonly kind: "i64";
211
+ readonly value: bigint;
212
+ } | {
213
+ readonly kind: "f32";
214
+ readonly value: number;
215
+ } | {
216
+ readonly kind: "f64";
217
+ readonly value: number;
218
+ } | {
219
+ readonly kind: "bool";
220
+ readonly value: boolean;
221
+ } | {
222
+ readonly kind: "null";
223
+ readonly ty: IrType;
224
+ } | {
225
+ readonly kind: "undefined";
226
+ };
227
+ export interface IrSiteId {
228
+ readonly line: number;
229
+ readonly column: number;
230
+ }
231
+ export interface IrInstrBase {
232
+ /** SSA def produced by this instr. `null` for void instrs. */
233
+ readonly result: IrValueId | null;
234
+ /** Static type of the result, if any. Redundant w/ `result`'s type but kept local for verifier speed. */
235
+ readonly resultType: IrType | null;
236
+ /** Source location for diagnostics. Optional in Phase 1. */
237
+ readonly site?: IrSiteId;
238
+ /**
239
+ * Stable allocation-site identity (#1586). Present iff this instr is a
240
+ * value-creating (allocation) site — see {@link AllocKind} and the audit
241
+ * table in docs/adr/0013-ir-allocation-sites.md. Distinct from `result`
242
+ * (an `IrValueId`, which inlining/monomorphize renumber). Inert at
243
+ * lowering, so the emitted Wasm is byte-identical whether or not it is set.
244
+ */
245
+ readonly alloc?: AllocSiteId;
246
+ }
247
+ /** Materialize a constant into an SSA value. */
248
+ export interface IrInstrConst extends IrInstrBase {
249
+ readonly kind: "const";
250
+ readonly value: IrConst;
251
+ }
252
+ /** Call a function by symbolic reference. Return value (if any) is `result`. */
253
+ export interface IrInstrCall extends IrInstrBase {
254
+ readonly kind: "call";
255
+ readonly target: IrFuncRef;
256
+ readonly args: readonly IrValueId[];
257
+ }
258
+ /** Read a global by symbolic reference. */
259
+ export interface IrInstrGlobalGet extends IrInstrBase {
260
+ readonly kind: "global.get";
261
+ readonly target: IrGlobalRef;
262
+ }
263
+ /** Write a global by symbolic reference. Void-result. */
264
+ export interface IrInstrGlobalSet extends IrInstrBase {
265
+ readonly kind: "global.set";
266
+ readonly target: IrGlobalRef;
267
+ readonly value: IrValueId;
268
+ }
269
+ /**
270
+ * Typed binary primitive. The `op` tag encodes both operand type(s) and the
271
+ * operation, so the lowerer can map 1:1 to a Wasm instruction without
272
+ * re-inferring types. Phase 1 covers the numeric/bool subset.
273
+ */
274
+ export type IrBinop = "f64.add" | "f64.sub" | "f64.mul" | "f64.div" | "f64.eq" | "f64.ne" | "f64.lt" | "f64.le" | "f64.gt" | "f64.ge" | "i32.eq" | "i32.ne" | "i32.and" | "i32.or" | "i32.lt_s" | "i32.le_s" | "i32.gt_s" | "i32.ge_s" | "i32.lt_u" | "i32.le_u" | "i32.gt_u" | "i32.ge_u" | "js.bitand" | "js.bitor" | "js.bitxor" | "js.shl" | "js.shr_s" | "js.shr_u";
275
+ /**
276
+ * Typed unary primitive. `f64.neg` negates a number. `i32.eqz` implements
277
+ * bool negation (`!x` where x is bool — 0↔1).
278
+ *
279
+ * Slice 12 (#1169o) adds `i32.trunc_sat_f64_s` — saturating f64 → i32
280
+ * truncation. Used to convert a JS-style f64 array index into the i32
281
+ * the backend `vec.get` instruction expects. Saturation handles
282
+ * NaN→0 and out-of-range values gracefully (no trap), matching what
283
+ * test262's array-indexing patterns expect.
284
+ */
285
+ export type IrUnop = "f64.neg" | "i32.eqz" | "i32.trunc_sat_f64_s" | "f64.abs" | "f64.sqrt" | "f64.floor" | "f64.ceil" | "f64.trunc" | "ref.is_null";
286
+ export interface IrInstrBinary extends IrInstrBase {
287
+ readonly kind: "binary";
288
+ readonly op: IrBinop;
289
+ readonly lhs: IrValueId;
290
+ readonly rhs: IrValueId;
291
+ }
292
+ export interface IrInstrUnary extends IrInstrBase {
293
+ readonly kind: "unary";
294
+ readonly op: IrUnop;
295
+ readonly rand: IrValueId;
296
+ }
297
+ /**
298
+ * Conditional expression — lowers to Wasm `select`. Both arms are evaluated;
299
+ * this is safe for pure Phase 1 expressions (no calls, no side effects).
300
+ * Branching control flow (for statements with side effects) comes in Phase 2
301
+ * via `br_if` terminators.
302
+ */
303
+ export interface IrInstrSelect extends IrInstrBase {
304
+ readonly kind: "select";
305
+ readonly condition: IrValueId;
306
+ readonly whenTrue: IrValueId;
307
+ readonly whenFalse: IrValueId;
308
+ }
309
+ /**
310
+ * (#1392) Value-producing if/else expression. UNLIKE `select`, this
311
+ * SHORT-CIRCUITS — only one branch's instructions are executed. Used by
312
+ * the optional-chain lowering (`recv?.prop`) where the right-hand side
313
+ * (`recv.prop`) MUST NOT execute when `recv` is null.
314
+ *
315
+ * The two arm buffers (`then` / `else`) are self-contained instruction
316
+ * lists collected via `IrFunctionBuilder.collectBodyInstrs(...)`. They
317
+ * may reference SSA values defined OUTSIDE the if-instr (those are
318
+ * available through Wasm locals), but values defined INSIDE one arm are
319
+ * NOT visible to the other arm or to instructions following the if.
320
+ *
321
+ * The carrier values are `thenValue` / `elseValue` — IrValueIds defined
322
+ * inside the corresponding arm. The lowerer emits a Wasm
323
+ * `if (result T) ... else ... end` block where each arm leaves its
324
+ * carrier value on the stack; the post-block `local.set` binds the
325
+ * result to the if-instr's `result` SSA value.
326
+ *
327
+ * Both arms must produce values of `resultType`. The verifier rejects
328
+ * shape mismatches.
329
+ */
330
+ export interface IrInstrIf extends IrInstrBase {
331
+ readonly kind: "if";
332
+ readonly cond: IrValueId;
333
+ readonly then: readonly IrInstr[];
334
+ readonly thenValue: IrValueId;
335
+ readonly else: readonly IrInstr[];
336
+ readonly elseValue: IrValueId;
337
+ }
338
+ /**
339
+ * (#1373 Phase B) `await <expr>` — suspend the current async function until
340
+ * `expr`'s Promise settles, then resume with the resolved value. The IR
341
+ * node carries the operand whose evaluation produces a Promise (or a
342
+ * non-Promise value that must be wrapped in `Promise.resolve` before
343
+ * suspension per spec §27.2.1.4).
344
+ *
345
+ * Phase B (this slice) defines the type only — no lowering. Phase C
346
+ * (CPS transform, follow-up #1373b) splits the function at each await
347
+ * point, lifts the post-await tail into a continuation closure, and
348
+ * emits microtask-queue calls (`__promise_then(promise, continuation)`)
349
+ * to schedule resumption.
350
+ *
351
+ * The result IrValueId carries the resolved value. Its IrType must
352
+ * match the surrounding expression context (typically the unwrapped
353
+ * `T` from `Promise<T>`).
354
+ */
355
+ export interface IrInstrAwait extends IrInstrBase {
356
+ readonly kind: "await";
357
+ readonly operand: IrValueId;
358
+ }
359
+ /**
360
+ * (#1373 Phase B) `return <value>` from an async function body. UNLIKE
361
+ * `IrTerminatorReturn`, which produces the bare value, this wraps the
362
+ * value in `Promise.resolve(value)` per the async function spec
363
+ * §15.8.5.5. The IR node defines the wrap intent; lowering (Phase C)
364
+ * emits the wrap via the existing `Promise_resolve` host import in
365
+ * JS-host mode or via the standalone `$Promise` struct.new in WASI
366
+ * mode (the latter wired in #1326 Phase 1B).
367
+ *
368
+ * Used in tail position only — non-tail `return` inside an async
369
+ * function flows through the IR's normal block terminator, which the
370
+ * Phase C lowerer recognises and routes through the same wrap.
371
+ */
372
+ export interface IrInstrAsyncReturn extends IrInstrBase {
373
+ readonly kind: "async.return";
374
+ readonly value: IrValueId;
375
+ }
376
+ /**
377
+ * (#1373 Phase B) Synchronous throw inside an async function body.
378
+ * UNLIKE `IrInstrThrow`, which propagates as a Wasm exception, this
379
+ * wraps the thrown value in `Promise.reject(reason)` so the async
380
+ * function's outer Promise settles in the rejected state. Lowering
381
+ * (Phase C) emits the wrap via `Promise_reject` (host) or `$Promise`
382
+ * struct.new with `state = REJECTED` (standalone, #1326 Phase 1B).
383
+ *
384
+ * Currently NOT emitted by from-ast — Phase C wires it from
385
+ * `ts.ThrowStatement` nodes inside async function bodies.
386
+ */
387
+ export interface IrInstrAsyncThrow extends IrInstrBase {
388
+ readonly kind: "async.throw";
389
+ readonly reason: IrValueId;
390
+ }
391
+ /**
392
+ * Escape hatch: a raw backend instruction sequence with no SSA structure.
393
+ * Phase 1 uses this as a bridge so we can describe any function without
394
+ * re-encoding the whole Wasm opcode set in IR. Phase 2 will narrow uses.
395
+ * The verifier treats it as an opaque block: stack contract must match.
396
+ */
397
+ export interface IrInstrRawWasm extends IrInstrBase {
398
+ readonly kind: "raw.wasm";
399
+ /** Backend ops to emit verbatim. */
400
+ readonly ops: readonly import('./types.js').Instr[];
401
+ /** Wasm value-stack delta after running `ops` (positive = pushes). */
402
+ readonly stackDelta: number;
403
+ }
404
+ /**
405
+ * Box a scalar into a tagged-union struct. `toType` must be an `IrType.union`
406
+ * whose `members` contains `value`'s static ValType. Lowering emits
407
+ * `struct.new $union_<members>` with the matching tag constant + the value
408
+ * in the `$val` field. Result is `(ref $union_<members>)` / the `toType`.
409
+ */
410
+ export interface IrInstrBox extends IrInstrBase {
411
+ readonly kind: "box";
412
+ readonly value: IrValueId;
413
+ readonly toType: IrType;
414
+ }
415
+ /**
416
+ * Unbox a tagged-union value to one of its member ValTypes. The caller must
417
+ * have proved the tag already (via `tag.test` earlier in the same IR path);
418
+ * lowering emits a plain `struct.get $val` without a tag check at runtime.
419
+ * A debug-mode assertion can still verify the tag.
420
+ */
421
+ export interface IrInstrUnbox extends IrInstrBase {
422
+ readonly kind: "unbox";
423
+ readonly value: IrValueId;
424
+ readonly tag: ValType;
425
+ }
426
+ /**
427
+ * Runtime tag discriminator — result (via `IrInstrBase.result`) is `i32`,
428
+ * 1 if `value`'s runtime tag matches `tag`, else 0. `value` must be a
429
+ * tagged-union type containing `tag` as a member. Lowers to
430
+ * `struct.get $tag; i32.const <N>; i32.eq`.
431
+ */
432
+ export interface IrInstrTagTest extends IrInstrBase {
433
+ readonly kind: "tag.test";
434
+ readonly value: IrValueId;
435
+ readonly tag: ValType;
436
+ }
437
+ /**
438
+ * Materialize a string literal as an SSA value of `IrType.string`. The
439
+ * backend representation is determined by `IrLowerResolver.emitStringConst`:
440
+ * - host strings → register a `string_constants.<value>` global import,
441
+ * emit `global.get`.
442
+ * - native → emit inline `array.new_fixed` of the WTF-16 code units,
443
+ * then `struct.new $NativeString`.
444
+ */
445
+ export interface IrInstrStringConst extends IrInstrBase {
446
+ readonly kind: "string.const";
447
+ /** Raw JS string; the lowerer treats `value.length` as UTF-16 code units. */
448
+ readonly value: string;
449
+ }
450
+ /**
451
+ * Concatenate two strings — the ECMAScript `s1 + s2` operator restricted to
452
+ * the case where both operands are statically known to be strings. Result
453
+ * type: `IrType.string`.
454
+ */
455
+ export interface IrInstrStringConcat extends IrInstrBase {
456
+ readonly kind: "string.concat";
457
+ readonly lhs: IrValueId;
458
+ readonly rhs: IrValueId;
459
+ }
460
+ /**
461
+ * String equality. `===` and `!==` are both modeled via this single instr —
462
+ * `negate: true` ↔ `!==`. Result type: `i32` (bool).
463
+ */
464
+ export interface IrInstrStringEq extends IrInstrBase {
465
+ readonly kind: "string.eq";
466
+ readonly lhs: IrValueId;
467
+ readonly rhs: IrValueId;
468
+ readonly negate: boolean;
469
+ }
470
+ /**
471
+ * String length — corresponds to the JS `s.length` property access. Despite
472
+ * the underlying Wasm op returning `i32`, the IR result is `f64` to match
473
+ * JS Number semantics, so consumers can compose with the rest of the
474
+ * numeric IR without an extra coercion step. Lowering inserts the
475
+ * `f64.convert_i32_s` after the backend's length op.
476
+ */
477
+ export interface IrInstrStringLen extends IrInstrBase {
478
+ readonly kind: "string.len";
479
+ readonly value: IrValueId;
480
+ }
481
+ /**
482
+ * Materialize an object literal as a WasmGC struct. `shape` declares the
483
+ * struct's field layout (already canonically sorted by name); `values` is
484
+ * parallel to `shape.fields` and must have the same length. Lowering emits
485
+ * each value in canonical order followed by `struct.new $obj_<shape>`.
486
+ *
487
+ * Result type: `{ kind: "object", shape }`.
488
+ */
489
+ export interface IrInstrObjectNew extends IrInstrBase {
490
+ readonly kind: "object.new";
491
+ readonly shape: IrObjectShape;
492
+ readonly values: readonly IrValueId[];
493
+ }
494
+ /**
495
+ * Read a named field from an object. `value` must be of `IrType.object`
496
+ * with a shape whose `fields` contain `name`. Lowering emits
497
+ * `struct.get $obj_<shape> <fieldIdx>`.
498
+ *
499
+ * Result type: the field's IrType (must match `resultType`).
500
+ */
501
+ export interface IrInstrObjectGet extends IrInstrBase {
502
+ readonly kind: "object.get";
503
+ readonly value: IrValueId;
504
+ readonly name: string;
505
+ }
506
+ /**
507
+ * Write a named field on an object. `value` must be `IrType.object`,
508
+ * `newValue` must match the field's IrType. Void result. Lowering emits
509
+ * `struct.set $obj_<shape> <fieldIdx>`.
510
+ */
511
+ export interface IrInstrObjectSet extends IrInstrBase {
512
+ readonly kind: "object.set";
513
+ readonly value: IrValueId;
514
+ readonly name: string;
515
+ readonly newValue: IrValueId;
516
+ }
517
+ /**
518
+ * Materialize a closure value. `liftedFunc` names the lifted top-level
519
+ * function (registered in the IR module as a synthesized BuiltFn).
520
+ * `signature` is the caller-visible signature (used to look up the
521
+ * supertype struct + funcref type). `captures` populates the subtype's
522
+ * capture fields parallel to `captureFieldTypes`.
523
+ *
524
+ * Lowering emits:
525
+ * ref.func $lifted
526
+ * <push each capture>
527
+ * struct.new $closure_<signature>_<captureSig>
528
+ *
529
+ * Result type: `{ kind: "closure"; signature }`. The Wasm-level value
530
+ * type is the supertype struct so call_ref against the base func type
531
+ * accepts any subtype.
532
+ */
533
+ export interface IrInstrClosureNew extends IrInstrBase {
534
+ readonly kind: "closure.new";
535
+ readonly liftedFunc: IrFuncRef;
536
+ readonly signature: IrClosureSignature;
537
+ /** Capture-field IrTypes in struct field order (post-funcref). */
538
+ readonly captureFieldTypes: readonly IrType[];
539
+ /** SSA values populating the capture fields, parallel to captureFieldTypes. */
540
+ readonly captures: readonly IrValueId[];
541
+ }
542
+ /**
543
+ * Read a capture field from the implicit `__self` closure struct. Only
544
+ * valid inside a lifted closure body whose IrFunction carries
545
+ * `closureSubtype` metadata. `index` is the 0-based capture position
546
+ * (post-funcref).
547
+ *
548
+ * Lowering emits:
549
+ * <self>
550
+ * ref.cast $self_subtype
551
+ * struct.get $self_subtype (index+1)
552
+ */
553
+ export interface IrInstrClosureCap extends IrInstrBase {
554
+ readonly kind: "closure.cap";
555
+ /** SSA value of the closure-typed __self param (the lifted func's param 0). */
556
+ readonly self: IrValueId;
557
+ readonly index: number;
558
+ }
559
+ /**
560
+ * Invoke a closure value. `callee` must be `IrType.closure`. `args` must
561
+ * match the signature's params arity and types.
562
+ *
563
+ * Lowering emits:
564
+ * <emit callee> ;; pushes self
565
+ * <emit args>
566
+ * <emit callee> ;; pushes self again — second use forces a Wasm local
567
+ * struct.get $base_struct $func
568
+ * call_ref $base_funcType
569
+ *
570
+ * Result type: `signature.returnType`.
571
+ */
572
+ export interface IrInstrClosureCall extends IrInstrBase {
573
+ readonly kind: "closure.call";
574
+ readonly callee: IrValueId;
575
+ readonly args: readonly IrValueId[];
576
+ }
577
+ /**
578
+ * Wrap a primitive value in a fresh ref cell. Lowering:
579
+ * <emit value>
580
+ * struct.new $refcell_<inner>
581
+ *
582
+ * Result type: `{ kind: "boxed"; inner: <ValType of value> }`.
583
+ */
584
+ export interface IrInstrRefCellNew extends IrInstrBase {
585
+ readonly kind: "refcell.new";
586
+ readonly value: IrValueId;
587
+ }
588
+ /**
589
+ * Read the inner value out of a ref cell. `cell` must be `IrType.boxed`.
590
+ * Result type is `irVal(cell.inner)`.
591
+ *
592
+ * Lowering: `<emit cell>; struct.get $refcell 0`.
593
+ */
594
+ export interface IrInstrRefCellGet extends IrInstrBase {
595
+ readonly kind: "refcell.get";
596
+ readonly cell: IrValueId;
597
+ }
598
+ /**
599
+ * Write a new value through a ref cell. `cell` must be `IrType.boxed`,
600
+ * `value` ValType must equal `cell.inner`. Void result.
601
+ *
602
+ * Lowering: `<emit cell>; <emit value>; struct.set $refcell 0`.
603
+ */
604
+ export interface IrInstrRefCellSet extends IrInstrBase {
605
+ readonly kind: "refcell.set";
606
+ readonly cell: IrValueId;
607
+ readonly value: IrValueId;
608
+ }
609
+ /**
610
+ * Construct a class instance via the legacy-registered constructor.
611
+ *
612
+ * Lowering:
613
+ * <emit each arg in order>
614
+ * call $<className>_new
615
+ *
616
+ * Result type: `{ kind: "class"; shape }`. The Wasm-level value type is
617
+ * `(ref $ClassStruct)` (non-null) — `<className>_new` is registered with
618
+ * a non-null ref result by `collectClassDeclaration`.
619
+ */
620
+ export interface IrInstrClassNew extends IrInstrBase {
621
+ readonly kind: "class.new";
622
+ readonly shape: IrClassShape;
623
+ readonly args: readonly IrValueId[];
624
+ }
625
+ /**
626
+ * Read a named field from a class instance. `value` must be `IrType.class`
627
+ * with a shape containing `fieldName`. Lowering emits:
628
+ * <emit value>
629
+ * struct.get $<className> <wasmFieldIdx>
630
+ *
631
+ * The wasm field index accounts for the legacy `__tag` prefix at field 0
632
+ * — see `IrLowerResolver.resolveClass`.
633
+ *
634
+ * Result type: the field's IrType (also placed in `resultType`).
635
+ */
636
+ export interface IrInstrClassGet extends IrInstrBase {
637
+ readonly kind: "class.get";
638
+ readonly value: IrValueId;
639
+ readonly fieldName: string;
640
+ }
641
+ /**
642
+ * Write a named field on a class instance. Void result. Lowering emits:
643
+ * <emit value>
644
+ * <emit newValue>
645
+ * struct.set $<className> <wasmFieldIdx>
646
+ *
647
+ * The legacy `collectClassDeclaration` pass widens all class fields to
648
+ * `mutable: true`, so `struct.set` is always valid.
649
+ */
650
+ export interface IrInstrClassSet extends IrInstrBase {
651
+ readonly kind: "class.set";
652
+ readonly value: IrValueId;
653
+ readonly fieldName: string;
654
+ readonly newValue: IrValueId;
655
+ }
656
+ /**
657
+ * Invoke an instance method. `receiver` must be `IrType.class` whose
658
+ * shape contains `methodName`. The implicit `this` is prepended as the
659
+ * first call argument. Lowering emits:
660
+ * <emit receiver>
661
+ * <emit each arg in order>
662
+ * call $<className>_<methodName>
663
+ *
664
+ * Result type: the method descriptor's `returnType`. A void method has
665
+ * `result: null` and `resultType: null`; the AST→IR lowerer rejects
666
+ * such calls in expression position so we never see a void method as
667
+ * `lowerExpr` output.
668
+ */
669
+ export interface IrInstrClassCall extends IrInstrBase {
670
+ readonly kind: "class.call";
671
+ readonly receiver: IrValueId;
672
+ readonly methodName: string;
673
+ readonly args: readonly IrValueId[];
674
+ }
675
+ /**
676
+ * Read a Wasm-local slot. `index` is the function-level slot index assigned
677
+ * at IR build time (allocated via `IrFunctionBuilder.declareSlot`). The slot's
678
+ * declared type must be a primitive ValType; the result IrType is `irVal`
679
+ * of that ValType.
680
+ *
681
+ * Lowering: `local.get <slotIndex>`.
682
+ */
683
+ export interface IrInstrSlotRead extends IrInstrBase {
684
+ readonly kind: "slot.read";
685
+ readonly slotIndex: number;
686
+ }
687
+ /**
688
+ * Write a value to a Wasm-local slot. The value's IrType must be `val` with
689
+ * a ValType matching the slot's declared type. Void result.
690
+ *
691
+ * Lowering: `<emit value>; local.set <slotIndex>`.
692
+ */
693
+ export interface IrInstrSlotWrite extends IrInstrBase {
694
+ readonly kind: "slot.write";
695
+ readonly slotIndex: number;
696
+ readonly value: IrValueId;
697
+ }
698
+ /**
699
+ * Read `vec.length` (i32) from a vec struct. The vec must have an IrType
700
+ * that the lowerer's resolver recognises as a vec (typeIdx with a layout of
701
+ * `{ length: i32, data: (ref $arr) }`). Result is f64 (matching JS Number
702
+ * semantics — same approach as `string.len`); lowering inserts the
703
+ * `f64.convert_i32_s` after the i32 read.
704
+ */
705
+ export interface IrInstrVecLen extends IrInstrBase {
706
+ readonly kind: "vec.len";
707
+ readonly vec: IrValueId;
708
+ }
709
+ /**
710
+ * Index into a vec struct's data array. `index` must be an SSA value of
711
+ * IrType `irVal({ kind: "i32" })` (f64-to-i32 conversion happens at the
712
+ * caller — for-of always uses an i32 counter so this is always already i32).
713
+ *
714
+ * `resultType` carries the vec element's IrType (the lowerer matches it
715
+ * against the vec struct's data array's element type).
716
+ *
717
+ * Lowering: `<emit vec>; struct.get $vec data; <emit index>; array.get $arr`.
718
+ */
719
+ export interface IrInstrVecGet extends IrInstrBase {
720
+ readonly kind: "vec.get";
721
+ readonly vec: IrValueId;
722
+ readonly index: IrValueId;
723
+ }
724
+ /**
725
+ * #1804 — Construct a vec from a fixed, statically-known set of element SSA
726
+ * values. All `elements` share the IrType `elementType` (the from-ast lowerer
727
+ * coerces each element to this type before emitting). `resultType` is the vec
728
+ * ref IrType (a `ref` to the registered vec struct for `elementType`).
729
+ *
730
+ * Lowering (WasmGC): push e0…eN, `array.new_fixed $arr N`, stash the data ref
731
+ * in a scratch local, push `i32.const N` (length, field 0), re-load the data
732
+ * ref (field 1), `struct.new $vec`. The backend emitter owns the exact op
733
+ * sequence (see `emitVecNewFixed`) so the linear backend can realize the same
734
+ * node over its `[header][len][cap][elements…]` layout.
735
+ *
736
+ * Empty literals (`[]`) carry `elements: []`; the `elementType` is supplied by
737
+ * the from-ast layer from the declared/inferred array type (it cannot be
738
+ * inferred from zero elements).
739
+ */
740
+ export interface IrInstrVecNewFixed extends IrInstrBase {
741
+ readonly kind: "vec.new_fixed";
742
+ readonly elements: readonly IrValueId[];
743
+ readonly elementType: IrType;
744
+ }
745
+ /**
746
+ * Statement-level `for (const <bind> of <vec>) <body>` loop instruction.
747
+ *
748
+ * Encodes the array fast path declaratively. The lowerer emits:
749
+ * <emit vec>
750
+ * local.set <vecSlot>
751
+ * local.get <vecSlot>
752
+ * struct.get $vec data
753
+ * local.set <dataSlot>
754
+ * local.get <vecSlot>
755
+ * struct.get $vec length
756
+ * local.set <lenSlot>
757
+ * i32.const 0
758
+ * local.set <counterSlot>
759
+ * block
760
+ * loop
761
+ * local.get <counterSlot>
762
+ * local.get <lenSlot>
763
+ * i32.ge_s
764
+ * br_if 1 ;; exit loop
765
+ * local.get <dataSlot>
766
+ * local.get <counterSlot>
767
+ * array.get $arr
768
+ * local.set <elementSlot>
769
+ * <body instrs>
770
+ * local.get <counterSlot>
771
+ * i32.const 1
772
+ * i32.add
773
+ * local.set <counterSlot>
774
+ * br 0 ;; continue
775
+ * end
776
+ * end
777
+ *
778
+ * The vec must have a non-null ref type pointing to a registered vec struct
779
+ * (the resolver's `resolveVec` resolves it to typeIdx + length/data field
780
+ * indices + element array typeIdx + element ValType). Nullable vec types
781
+ * are not in slice 6 — the selector keeps them on the legacy path.
782
+ *
783
+ * Slot indices are pre-allocated via `IrFunctionBuilder.declareSlot` before
784
+ * the from-ast layer emits this instr.
785
+ *
786
+ * Result: void (`result: null`).
787
+ */
788
+ export interface IrInstrForOfVec extends IrInstrBase {
789
+ readonly kind: "forof.vec";
790
+ /** SSA value of the iterable. Lowered as the vec ref. */
791
+ readonly vec: IrValueId;
792
+ /** Element type — must match the vec's data array's element ValType. */
793
+ readonly elementType: IrType;
794
+ /** Pre-allocated slot indices (Wasm local indices) for the loop's state. */
795
+ readonly counterSlot: number;
796
+ readonly lengthSlot: number;
797
+ readonly vecSlot: number;
798
+ readonly dataSlot: number;
799
+ readonly elementSlot: number;
800
+ /** Body instrs emitted inside the loop. */
801
+ readonly body: readonly IrInstr[];
802
+ }
803
+ /**
804
+ * Coerce a reference-typed IR value to externref. Used by the iterator-
805
+ * protocol arm of `lowerForOfStatement` to feed an arbitrary iterable
806
+ * into the externref-typed `__iterator` host import.
807
+ *
808
+ * The input value must have a reference IrType (val/ref, val/ref_null,
809
+ * val/externref, object, class, closure, or string). Numeric values
810
+ * (i32, f64, etc.) cannot be coerced — the from-ast layer rejects them
811
+ * upstream.
812
+ *
813
+ * Lowering:
814
+ * - val/externref input → no-op (input already externref)
815
+ * - any other ref input → `extern.convert_any` after pushing the value.
816
+ *
817
+ * Result type: `irVal({ kind: "externref" })`.
818
+ */
819
+ export interface IrInstrCoerceToExternref extends IrInstrBase {
820
+ readonly kind: "coerce.to_externref";
821
+ readonly value: IrValueId;
822
+ }
823
+ /**
824
+ * Slice 7a (#1169f) — push a yielded value onto the generator function's
825
+ * `__gen_buffer` Wasm-local. The lowerer dispatches on the value's IrType:
826
+ * - `irVal({ kind: "f64" })` → `__gen_push_f64(buffer, value)`
827
+ * - (later slices: `i32` → `__gen_push_i32`; `externref` → `__gen_push_ref`)
828
+ *
829
+ * Result is void (`result: null`, `resultType: null`). Only valid inside
830
+ * functions whose `funcKind === "generator"`. The lowerer reads the
831
+ * `IrFunction.generatorBufferSlot` for the `local.get` of the buffer.
832
+ *
833
+ * Lowering pattern (slice 7a — f64 only):
834
+ * local.get $__gen_buffer
835
+ * <emit value>
836
+ * call $__gen_push_f64
837
+ */
838
+ export interface IrInstrGenPush extends IrInstrBase {
839
+ readonly kind: "gen.push";
840
+ readonly value: IrValueId;
841
+ }
842
+ /**
843
+ * Slice 6 part 3 (#1182) — opaque iterator handle for the host iterator
844
+ * protocol. Calls `__iterator(iterable)` to obtain the iterator object.
845
+ *
846
+ * Lowering:
847
+ * <emit iterable> ;; pushes externref
848
+ * call $__iterator ;; -> externref (the iterator)
849
+ *
850
+ * Result type: `irVal({ kind: "externref" })`.
851
+ */
852
+ export interface IrInstrIterNew extends IrInstrBase {
853
+ readonly kind: "iter.new";
854
+ readonly iterable: IrValueId;
855
+ /** True if this is a `for await` loop — calls `__async_iterator` instead. False for slice 6. */
856
+ readonly async: boolean;
857
+ }
858
+ /**
859
+ * Call iter.next() and return the result object handle (externref).
860
+ * The result is later split into `done` / `value` via separate instrs
861
+ * so the optimizer can decide whether to evaluate `value` (skip if done).
862
+ *
863
+ * Lowering: <emit iter>; call $__iterator_next -> externref
864
+ *
865
+ * Result type: `irVal({ kind: "externref" })`. Side-effecting (advances
866
+ * the iterator) — DCE must not eliminate it.
867
+ */
868
+ export interface IrInstrIterNext extends IrInstrBase {
869
+ readonly kind: "iter.next";
870
+ readonly iter: IrValueId;
871
+ }
872
+ /**
873
+ * Test whether an iterator-result object's `.done` is true.
874
+ *
875
+ * Lowering: <emit resultObj>; call $__iterator_done -> i32
876
+ *
877
+ * Result type: `irVal({ kind: "i32" })`. The operand field is named
878
+ * `resultObj` (not `result`) to avoid colliding with the SSA-def
879
+ * `result` field inherited from `IrInstrBase`.
880
+ */
881
+ export interface IrInstrIterDone extends IrInstrBase {
882
+ readonly kind: "iter.done";
883
+ readonly resultObj: IrValueId;
884
+ }
885
+ /**
886
+ * Read the `.value` slot of an iterator-result object.
887
+ *
888
+ * Lowering: <emit resultObj>; call $__iterator_value -> externref
889
+ *
890
+ * Result type: `irVal({ kind: "externref" })`. See `IrInstrIterDone`
891
+ * for the `resultObj` naming rationale.
892
+ */
893
+ export interface IrInstrIterValue extends IrInstrBase {
894
+ readonly kind: "iter.value";
895
+ readonly resultObj: IrValueId;
896
+ }
897
+ /**
898
+ * Call `iter.return()` if defined. Used by the iterator-close try/finally
899
+ * so abrupt exits notify the iterator (slice 6 step E, deferred to a
900
+ * try/finally-aware follow-up).
901
+ *
902
+ * Lowering: <emit iter>; call $__iterator_return
903
+ *
904
+ * Result type: void (`result: null`). Side-effecting.
905
+ */
906
+ export interface IrInstrIterReturn extends IrInstrBase {
907
+ readonly kind: "iter.return";
908
+ readonly iter: IrValueId;
909
+ }
910
+ /**
911
+ * Statement-level `for (const <bind> of <iterable>) <body>` loop using
912
+ * the host iterator protocol. The lowerer emits:
913
+ *
914
+ * <emit iterable>
915
+ * call $__iterator
916
+ * local.set <iterSlot>
917
+ * block
918
+ * loop
919
+ * local.get <iterSlot>
920
+ * call $__iterator_next
921
+ * local.tee <resultSlot>
922
+ * call $__iterator_done
923
+ * br_if 1 ;; exit loop on done=true
924
+ * local.get <resultSlot>
925
+ * call $__iterator_value
926
+ * local.set <elementSlot>
927
+ * <body instrs>
928
+ * br 0 ;; continue
929
+ * end
930
+ * end
931
+ * local.get <iterSlot>
932
+ * call $__iterator_return ;; normal-exit close
933
+ *
934
+ * The iterable must be an IR value of externref type (the from-ast
935
+ * layer inserts a `coerce.to_externref` if the source value isn't
936
+ * already externref). Slot indices are pre-allocated via
937
+ * `IrFunctionBuilder.declareSlot`.
938
+ *
939
+ * Result: void (`result: null`).
940
+ */
941
+ export interface IrInstrForOfIter extends IrInstrBase {
942
+ readonly kind: "forof.iter";
943
+ /** SSA value of the iterable as externref (caller pre-coerces). */
944
+ readonly iterable: IrValueId;
945
+ /** Pre-allocated externref slot for the iterator handle. */
946
+ readonly iterSlot: number;
947
+ /** Pre-allocated externref slot for the iterator-result object. */
948
+ readonly resultSlot: number;
949
+ /** Pre-allocated externref slot for the current element value. */
950
+ readonly elementSlot: number;
951
+ /** Body instrs emitted inside the loop. */
952
+ readonly body: readonly IrInstr[];
953
+ }
954
+ /**
955
+ * Slice 7a (#1169f) — generator function epilogue. Pushes the buffer + the
956
+ * pending-throw cell (always `ref.null.extern` in slice 7a) and calls
957
+ * `__create_generator(buffer, pendingThrow)` to produce the Generator-like
958
+ * object the function returns.
959
+ *
960
+ * Lowering pattern (slice 7a — synchronous-throw subset):
961
+ * local.get $__gen_buffer
962
+ * ref.null.extern ;; pendingThrow always null in 7a
963
+ * call $__create_generator
964
+ * ;; result: externref Generator object — left on stack for the
965
+ * ;; surrounding `return` terminator.
966
+ *
967
+ * Slice 7a does NOT yet emit the try/catch wrapping that legacy uses for
968
+ * deferred-throw semantics (#928). Throws inside the body propagate
969
+ * immediately (matches V8 generators on the FIRST `.next()` call but
970
+ * differs from spec on subsequent calls). A future slice (7-throw) will
971
+ * add the wrapping by carrying the preceding body instrs in this instr,
972
+ * similar to `forof.vec.body`.
973
+ *
974
+ * Result type: `irVal({ kind: "externref" })` — the Generator object.
975
+ * The function's terminator should be `return [result]`.
976
+ */
977
+ export interface IrInstrGenEpilogue extends IrInstrBase {
978
+ readonly kind: "gen.epilogue";
979
+ }
980
+ /**
981
+ * Slice 7b (#1169f) — `yield* <iterable>` delegation. Drains the inner
982
+ * iterable into the outer generator's `__gen_buffer` by calling the
983
+ * `__gen_yield_star(buf, iterable)` host import (signature
984
+ * `(externref, externref) → void`; the host iterates the inner via
985
+ * `Symbol.iterator` and pushes each value).
986
+ *
987
+ * The `inner` operand MUST already be coerced to externref by the
988
+ * caller (`lowerYield` in `from-ast.ts` inserts a `coerce.to_externref`
989
+ * upstream). The lowerer just emits the buffer-load, value, and call.
990
+ *
991
+ * Result is void. Only valid inside `funcKind === "generator"`. The
992
+ * lowerer reads `IrFunction.generatorBufferSlot` for the buffer
993
+ * `local.get`.
994
+ *
995
+ * Lowering pattern:
996
+ * local.get $__gen_buffer
997
+ * <emit inner> ;; already externref
998
+ * call $__gen_yield_star
999
+ *
1000
+ * Spec divergence note: ECMA-262 §27.5.3.7 says `yield*` evaluates to
1001
+ * the inner iterator's `return` value (the `IteratorResult.value` when
1002
+ * `done` becomes true). Under the eager-buffer model this is discarded;
1003
+ * `yield*` evaluates to `undefined`. Matches the legacy compiler's
1004
+ * behaviour (`misc.ts:177-202`).
1005
+ */
1006
+ export interface IrInstrGenYieldStar extends IrInstrBase {
1007
+ readonly kind: "gen.yieldStar";
1008
+ readonly inner: IrValueId;
1009
+ }
1010
+ /**
1011
+ * Slice 10 (#1169i) — `new ExternClass(arg1, arg2, ...)` where
1012
+ * `ExternClass` is a host-provided builtin (RegExp, Uint8Array, …). The
1013
+ * Wasm-level result is opaque externref; downstream code accesses it
1014
+ * via `extern.call` / `extern.prop`.
1015
+ *
1016
+ * Lowering:
1017
+ * <emit each arg>
1018
+ * call $<className>_new
1019
+ *
1020
+ * Result type: `{ kind: "extern", className }`.
1021
+ */
1022
+ export interface IrInstrExternNew extends IrInstrBase {
1023
+ readonly kind: "extern.new";
1024
+ readonly className: string;
1025
+ readonly args: readonly IrValueId[];
1026
+ }
1027
+ /**
1028
+ * Slice 10 (#1169i) — method call on an extern-class value. `receiver`
1029
+ * is the externref handle; `method` names a method registered on the
1030
+ * class via `ctx.externClasses`.
1031
+ *
1032
+ * Lowering:
1033
+ * <emit receiver>
1034
+ * <emit each arg>
1035
+ * call $<className>_<method>
1036
+ *
1037
+ * Result type: matches the registered method's first result. Void
1038
+ * methods carry `result: null` and `resultType: null`.
1039
+ */
1040
+ export interface IrInstrExternCall extends IrInstrBase {
1041
+ readonly kind: "extern.call";
1042
+ readonly className: string;
1043
+ readonly method: string;
1044
+ readonly receiver: IrValueId;
1045
+ readonly args: readonly IrValueId[];
1046
+ }
1047
+ /**
1048
+ * Slice 10 (#1169i) — property read on an extern-class value.
1049
+ *
1050
+ * Lowering:
1051
+ * <emit receiver>
1052
+ * call $<className>_get_<property>
1053
+ *
1054
+ * Result type: the property's registered ValType, wrapped as `IrType.val`.
1055
+ */
1056
+ export interface IrInstrExternProp extends IrInstrBase {
1057
+ readonly kind: "extern.prop";
1058
+ readonly className: string;
1059
+ readonly property: string;
1060
+ readonly receiver: IrValueId;
1061
+ }
1062
+ /**
1063
+ * Slice 10 (#1169i) — property write on an extern-class value (for
1064
+ * non-readonly props).
1065
+ *
1066
+ * Lowering:
1067
+ * <emit receiver>
1068
+ * <emit value>
1069
+ * call $<className>_set_<property>
1070
+ */
1071
+ export interface IrInstrExternPropSet extends IrInstrBase {
1072
+ readonly kind: "extern.propSet";
1073
+ readonly className: string;
1074
+ readonly property: string;
1075
+ readonly receiver: IrValueId;
1076
+ readonly value: IrValueId;
1077
+ }
1078
+ /**
1079
+ * Slice 10 (#1169i) — RegExp literal `/pattern/flags`. Lowers to
1080
+ * `RegExp_new(pattern, flags)`. The pattern + flags are registered as
1081
+ * string-literal globals (the legacy `collectStringLiterals` pass
1082
+ * already collects RegExp pattern/flags as string literals — see
1083
+ * `src/codegen/index.ts:3274-3278` — so by the time the IR emits this
1084
+ * instr the corresponding string globals exist).
1085
+ *
1086
+ * Result type: `{ kind: "extern", className: "RegExp" }`.
1087
+ */
1088
+ export interface IrInstrRegExpLiteral extends IrInstrBase {
1089
+ readonly kind: "extern.regex";
1090
+ readonly pattern: string;
1091
+ readonly flags: string;
1092
+ }
1093
+ /**
1094
+ * Statement-level `for (const c of <string>) <body>` loop using the
1095
+ * native-strings counter pattern. Emitted only when the resolver
1096
+ * reports `nativeStrings(): true` — host-strings mode falls through
1097
+ * to `forof.iter` upstream in `lowerForOfStatement`.
1098
+ *
1099
+ * The lowerer emits:
1100
+ * <emit str>
1101
+ * local.set <strSlot>
1102
+ * local.get <strSlot>
1103
+ * struct.get $AnyString $len
1104
+ * local.set <lengthSlot>
1105
+ * i32.const 0
1106
+ * local.set <counterSlot>
1107
+ * block
1108
+ * loop
1109
+ * local.get <counterSlot>
1110
+ * local.get <lengthSlot>
1111
+ * i32.ge_s
1112
+ * br_if 1
1113
+ * local.get <strSlot>
1114
+ * local.get <counterSlot>
1115
+ * call $__str_charAt
1116
+ * local.set <elementSlot>
1117
+ * <body instrs>
1118
+ * local.get <counterSlot>
1119
+ * i32.const 1
1120
+ * i32.add
1121
+ * local.set <counterSlot>
1122
+ * br 0
1123
+ * end
1124
+ * end
1125
+ *
1126
+ * Slot types (set by from-ast):
1127
+ * counterSlot — i32
1128
+ * lengthSlot — i32
1129
+ * strSlot — `(ref $AnyString)` (resolver.resolveString())
1130
+ * elementSlot — `(ref $AnyString)` — each iteration produces a
1131
+ * single-char string
1132
+ *
1133
+ * Result: void (`result: null`).
1134
+ */
1135
+ export interface IrInstrForOfString extends IrInstrBase {
1136
+ readonly kind: "forof.string";
1137
+ /** SSA value of the string (IrType.string). */
1138
+ readonly str: IrValueId;
1139
+ readonly counterSlot: number;
1140
+ readonly lengthSlot: number;
1141
+ readonly strSlot: number;
1142
+ readonly elementSlot: number;
1143
+ /** Body instrs emitted inside the loop. */
1144
+ readonly body: readonly IrInstr[];
1145
+ }
1146
+ /**
1147
+ * Slice 9 (#1169h) — throw an exception. The `value` is coerced to externref
1148
+ * upstream (the `__exn` tag's signature is `(externref)`). After throw,
1149
+ * control transfers to the nearest enclosing catch matching the tag, or
1150
+ * unwinds out of the function.
1151
+ *
1152
+ * The instr produces NO SSA value (control doesn't fall through), so
1153
+ * `result` and `resultType` are always null. The verifier treats it as a
1154
+ * "stop" instr — instructions after it in the same block are unreachable
1155
+ * in source but still validated structurally.
1156
+ *
1157
+ * Lowering:
1158
+ * <emit value> ;; pushes externref
1159
+ * throw $__exn
1160
+ */
1161
+ export interface IrInstrThrow extends IrInstrBase {
1162
+ readonly kind: "throw";
1163
+ readonly value: IrValueId;
1164
+ }
1165
+ /**
1166
+ * Slice 12 (#1280) — `while (cond) body` loop.
1167
+ *
1168
+ * Lowering pattern:
1169
+ * block
1170
+ * loop
1171
+ * <cond instrs> ;; computes condValue
1172
+ * <emit condValue> ;; pushes the i32 boolean
1173
+ * i32.eqz
1174
+ * br_if 1 ;; exit on falsy
1175
+ * <body instrs>
1176
+ * br 0 ;; continue
1177
+ * end
1178
+ * end
1179
+ *
1180
+ * `condValue` MUST be the SSA result of an instruction in `cond` (or
1181
+ * an outer-scope value that's loaded into `cond`'s last instr). The
1182
+ * resolver coerces non-i32 values to i32 via the standard truthy
1183
+ * lowering path — for now the from-ast layer enforces an i32 result.
1184
+ *
1185
+ * Result: void (`result: null`).
1186
+ */
1187
+ export interface IrInstrWhileLoop extends IrInstrBase {
1188
+ readonly kind: "while.loop";
1189
+ /** Instructions that compute the condition. Re-evaluated per iteration. */
1190
+ readonly cond: readonly IrInstr[];
1191
+ /** SSA value of the condition (an i32 boolean). */
1192
+ readonly condValue: IrValueId;
1193
+ /** Body instructions executed each iteration when the cond is truthy. */
1194
+ readonly body: readonly IrInstr[];
1195
+ }
1196
+ /**
1197
+ * Slice 12 (#1280) — `for (init; cond; update) body` loop.
1198
+ *
1199
+ * The init clause is emitted by the from-ast layer as ordinary IR
1200
+ * statements BEFORE the `for.loop` instr (init is just a let-decl or
1201
+ * an assignment expression statement, no special encoding needed).
1202
+ * The instr carries cond, body, update.
1203
+ *
1204
+ * Lowering pattern:
1205
+ * block
1206
+ * loop
1207
+ * <cond instrs>
1208
+ * <emit condValue>
1209
+ * i32.eqz
1210
+ * br_if 1
1211
+ * <body instrs>
1212
+ * <update instrs> ;; runs after body, before re-evaluating cond
1213
+ * br 0
1214
+ * end
1215
+ * end
1216
+ *
1217
+ * Result: void (`result: null`).
1218
+ */
1219
+ export interface IrInstrForLoop extends IrInstrBase {
1220
+ readonly kind: "for.loop";
1221
+ /** Instructions that compute the condition. Re-evaluated per iteration. */
1222
+ readonly cond: readonly IrInstr[];
1223
+ /** SSA value of the condition (an i32 boolean). */
1224
+ readonly condValue: IrValueId;
1225
+ /** Body instructions executed each iteration when the cond is truthy. */
1226
+ readonly body: readonly IrInstr[];
1227
+ /** Update instructions executed after the body each iteration. */
1228
+ readonly update: readonly IrInstr[];
1229
+ }
1230
+ /**
1231
+ * Slice 9 (#1169h) — try / catch / finally as a declarative statement-level
1232
+ * instr. Mirrors the slice-6 `forof.vec` shape: the body / catch handler /
1233
+ * finally are self-contained Instr[] buffers, and the lowerer emits the
1234
+ * structured Wasm `try`/`catch`/`catch_all` op directly without
1235
+ * restructuring the IR's block graph.
1236
+ *
1237
+ * Encoding:
1238
+ * - `body` the try block's instructions.
1239
+ * - `catchClause` optional. When present, encodes a source-level
1240
+ * `catch (e) { ... }` (or `catch { ... }`).
1241
+ * * `payloadSlot` — slot of `(externref)` that
1242
+ * receives the thrown value at handler entry
1243
+ * (or -1 when there is no source binding).
1244
+ * * `body` — handler instructions.
1245
+ * - `finallyBody` optional. When present, the lowerer inlines this
1246
+ * buffer at every "abrupt completion" path:
1247
+ * * normal exit of try body
1248
+ * * normal exit of catch body
1249
+ * * a synthesized catch_all that re-throws
1250
+ *
1251
+ * Acceptable shapes (selector-enforced):
1252
+ * try { ... } catch (e) { ... } catchClause set
1253
+ * try { ... } catch { ... } catchClause set, payloadSlot=-1
1254
+ * try { ... } finally { ... } finallyBody set
1255
+ * try { ... } catch (e) { ... } finally { ... } both set
1256
+ *
1257
+ * Result is void (`result: null`).
1258
+ */
1259
+ export interface IrInstrTry extends IrInstrBase {
1260
+ readonly kind: "try";
1261
+ /** Try block instructions. */
1262
+ readonly body: readonly IrInstr[];
1263
+ /** Optional source-level catch handler. */
1264
+ readonly catchClause?: {
1265
+ /**
1266
+ * Externref-typed slot index that the lowerer writes the caught
1267
+ * exception into at handler entry. `-1` when the source has no
1268
+ * binding (`catch { ... }`).
1269
+ */
1270
+ readonly payloadSlot: number;
1271
+ readonly body: readonly IrInstr[];
1272
+ };
1273
+ /** Optional finally body, inlined at every exit path. */
1274
+ readonly finallyBody?: readonly IrInstr[];
1275
+ }
1276
+ export type IrInstr = IrInstrConst | IrInstrCall | IrInstrGlobalGet | IrInstrGlobalSet | IrInstrBinary | IrInstrUnary | IrInstrSelect | IrInstrIf | IrInstrRawWasm | IrInstrBox | IrInstrUnbox | IrInstrTagTest | IrInstrStringConst | IrInstrStringConcat | IrInstrStringEq | IrInstrStringLen | IrInstrObjectNew | IrInstrObjectGet | IrInstrObjectSet | IrInstrClosureNew | IrInstrClosureCap | IrInstrClosureCall | IrInstrRefCellNew | IrInstrRefCellGet | IrInstrRefCellSet | IrInstrClassNew | IrInstrClassGet | IrInstrClassSet | IrInstrClassCall | IrInstrSlotRead | IrInstrSlotWrite | IrInstrVecLen | IrInstrVecGet | IrInstrVecNewFixed | IrInstrForOfVec | IrInstrCoerceToExternref | IrInstrIterNew | IrInstrIterNext | IrInstrIterDone | IrInstrIterValue | IrInstrIterReturn | IrInstrForOfIter | IrInstrGenPush | IrInstrGenEpilogue | IrInstrGenYieldStar | IrInstrForOfString | IrInstrThrow | IrInstrTry | IrInstrExternNew | IrInstrExternCall | IrInstrExternProp | IrInstrExternPropSet | IrInstrRegExpLiteral | IrInstrWhileLoop | IrInstrForLoop | IrInstrAwait | IrInstrAsyncReturn | IrInstrAsyncThrow;
1277
+ /**
1278
+ * Slice 6 (#1169e) — declaration of one Wasm-local slot used for cross-
1279
+ * iteration mutable state. Slots are allocated by the IR builder and
1280
+ * surface in the lowered Wasm function as additional locals appended
1281
+ * after the params and the SSA-driven locals.
1282
+ *
1283
+ * - `index` stable slot index, used by `slot.read` / `slot.write`.
1284
+ * NOT a Wasm local index — the lowerer translates slot
1285
+ * index N to Wasm local index `params + ssaLocals + N`.
1286
+ * - `name` debug name for the local.
1287
+ * - `type` primitive ValType (i32 / f64 / etc.) — slots only
1288
+ * carry primitives; reference-typed cross-iteration
1289
+ * state is rare in slice-6 loop bodies.
1290
+ */
1291
+ export interface IrSlotDef {
1292
+ readonly index: number;
1293
+ readonly name: string;
1294
+ readonly type: ValType;
1295
+ }
1296
+ export interface IrBranch {
1297
+ readonly target: IrBlockId;
1298
+ readonly args: readonly IrValueId[];
1299
+ }
1300
+ export type IrBlockId = number & {
1301
+ readonly __brand: "IrBlockId";
1302
+ };
1303
+ export declare function asBlockId(n: number): IrBlockId;
1304
+ export interface IrTerminatorReturn {
1305
+ readonly kind: "return";
1306
+ readonly values: readonly IrValueId[];
1307
+ readonly site?: IrSiteId;
1308
+ }
1309
+ export interface IrTerminatorBr {
1310
+ readonly kind: "br";
1311
+ readonly branch: IrBranch;
1312
+ readonly site?: IrSiteId;
1313
+ }
1314
+ export interface IrTerminatorBrIf {
1315
+ readonly kind: "br_if";
1316
+ readonly condition: IrValueId;
1317
+ readonly ifTrue: IrBranch;
1318
+ readonly ifFalse: IrBranch;
1319
+ readonly site?: IrSiteId;
1320
+ }
1321
+ export interface IrTerminatorUnreachable {
1322
+ readonly kind: "unreachable";
1323
+ readonly site?: IrSiteId;
1324
+ }
1325
+ export type IrTerminator = IrTerminatorReturn | IrTerminatorBr | IrTerminatorBrIf | IrTerminatorUnreachable;
1326
+ export interface IrBlock {
1327
+ readonly id: IrBlockId;
1328
+ /** SSA values bound on entry (replace phi nodes). Types are parallel to `blockArgTypes`. */
1329
+ readonly blockArgs: readonly IrValueId[];
1330
+ readonly blockArgTypes: readonly IrType[];
1331
+ readonly instrs: readonly IrInstr[];
1332
+ readonly terminator: IrTerminator;
1333
+ }
1334
+ export interface IrParam {
1335
+ readonly value: IrValueId;
1336
+ readonly type: IrType;
1337
+ readonly name: string;
1338
+ }
1339
+ export interface IrFunction {
1340
+ readonly name: string;
1341
+ readonly params: readonly IrParam[];
1342
+ readonly resultTypes: readonly IrType[];
1343
+ /** Entry block is always `blocks[0]`. */
1344
+ readonly blocks: readonly IrBlock[];
1345
+ readonly exported: boolean;
1346
+ /** Highest IrValueId allocated + 1 (useful for re-entering the builder). */
1347
+ readonly valueCount: number;
1348
+ /**
1349
+ * Slice 3 (#1169c): for closure-lifted bodies only, identifies the
1350
+ * subtype struct that captures live on. Set by `liftClosureBody` in
1351
+ * `from-ast.ts`. The lowerer reads this when emitting `closure.cap`
1352
+ * to compute the correct ref.cast target. Absent for nested function
1353
+ * declarations (which don't take a __self param) and for outer
1354
+ * functions.
1355
+ */
1356
+ readonly closureSubtype?: {
1357
+ readonly signature: IrClosureSignature;
1358
+ readonly captureFieldTypes: readonly IrType[];
1359
+ };
1360
+ /**
1361
+ * Slice 6 (#1169e): Wasm-local slots used for cross-iteration mutable
1362
+ * state in for-of loops. Empty for functions that don't contain a
1363
+ * for-of (or any other slot user). Slot indices are stable; the
1364
+ * lowerer maps slot index N to Wasm local index
1365
+ * `params.length + ssaLocalCount + N`
1366
+ * — i.e. slots come AFTER the SSA-driven locals.
1367
+ */
1368
+ readonly slots?: readonly IrSlotDef[];
1369
+ /**
1370
+ * Slice 7a (#1169f) — distinguishes regular / generator / async
1371
+ * functions. Set by `lowerFunctionAstToIr` from the AST node's
1372
+ * `asteriskToken` and `async` modifier. The lowerer reads this to:
1373
+ * - `"generator"`: select the externref Wasm-result type regardless
1374
+ * of the source-level annotation (the function returns a
1375
+ * Generator-like object, not the source-declared yield element
1376
+ * type), AND register the function name in `ctx.generatorFunctions`
1377
+ * downstream (for any name-based dispatch the legacy already wires).
1378
+ * - `"async"`: register in `ctx.asyncFunctions` so the export glue's
1379
+ * `wrapAsyncReturn` wraps the result in `Promise.resolve`. (Slice
1380
+ * 7d, not 7a.)
1381
+ * - `"regular"`: no special treatment (default if absent).
1382
+ */
1383
+ readonly funcKind?: "regular" | "generator" | "async";
1384
+ /**
1385
+ * Slice 7a (#1169f) — for `funcKind === "generator"` functions only,
1386
+ * the slot index (in `slots`) of the `__gen_buffer` Wasm-local. The
1387
+ * lowerer reads this when emitting `gen.push` / `gen.epilogue` to
1388
+ * produce the `local.get $__gen_buffer` op.
1389
+ */
1390
+ readonly generatorBufferSlot?: number;
1391
+ }
1392
+ export interface IrModule {
1393
+ readonly functions: readonly IrFunction[];
1394
+ }
1395
+ export declare function isIrFuncRef(x: unknown): x is IrFuncRef;
1396
+ export declare function isIrGlobalRef(x: unknown): x is IrGlobalRef;
1397
+ export declare function isIrTypeRef(x: unknown): x is IrTypeRef;
1398
+ /**
1399
+ * Invoke `fn` once per nested `IrInstr[]` buffer carried directly by `instr`
1400
+ * (NOT recursively — see `forEachInstrDeep` for the deep walk). The exhaustive
1401
+ * switch is the authoritative list of buffer-bearing kinds; the trailing
1402
+ * `never` assignment makes a missing case a compile error, so a new
1403
+ * buffer-bearing instr kind cannot be added without extending this one place.
1404
+ *
1405
+ * Buffer order is the lowering/evaluation order (cond before body before
1406
+ * update; then before else; body/catch/finally) so callers that care about
1407
+ * order (def registration) get it for free.
1408
+ */
1409
+ export declare function forEachNestedBuffer(instr: IrInstr, fn: (buffer: readonly IrInstr[]) => void): void;
1410
+ /**
1411
+ * Visit `instr` and every instruction nested within its buffers, recursively
1412
+ * (pre-order: the containing instr before its buffer contents). The single
1413
+ * deep-walk primitive shared by the verifier (def registration) and the
1414
+ * alloc-discipline pass (allocation retirement).
1415
+ */
1416
+ export declare function forEachInstrDeep(instr: IrInstr, visit: (i: IrInstr) => void): void;
1417
+ /**
1418
+ * Rebuild `instr` with each nested buffer replaced by `mapBuffer(buffer)` — the
1419
+ * write-side companion to `forEachNestedBuffer`, used by the hygiene passes
1420
+ * (#1925) to fold / DCE *inside* control-flow buffers. Buffers are passed in the
1421
+ * same evaluation order `forEachNestedBuffer` yields them.
1422
+ *
1423
+ * Reference-equality preserving: when `mapBuffer` returns each buffer unchanged
1424
+ * (same array reference), the original `instr` is returned as-is, so callers can
1425
+ * detect "no change" by `===` and keep their fixpoint contract. A non-buffer
1426
+ * instr is always returned unchanged.
1427
+ */
1428
+ export declare function mapNestedBuffers(instr: IrInstr, mapBuffer: (buffer: readonly IrInstr[]) => readonly IrInstr[]): IrInstr;
1429
+ /**
1430
+ * The direct SSA-value operands of `instr` — the values it reads at its own
1431
+ * level, NOT including operands buried in nested buffers. This is the canonical
1432
+ * single-count mapping used by the verifier and DCE (so e.g. `closure.call`'s
1433
+ * callee is counted once; the lowering use-counter's intentional double-count
1434
+ * for Wasm-local materialisation stays local to lower.ts).
1435
+ *
1436
+ * For buffer-bearing control-flow instrs, the operands surfaced here are only
1437
+ * the ones evaluated at the instr's own level: `if` → cond; `while/for` →
1438
+ * condValue; `forof.*` → the iterable/vec/str; `try` → none. Buffer-interior
1439
+ * uses are reached via `collectUses(instr, { deep: true })`.
1440
+ */
1441
+ export declare function directUses(instr: IrInstr): readonly IrValueId[];
1442
+ /**
1443
+ * Collect the SSA-value uses of `instr`. Shallow by default (== `directUses`);
1444
+ * with `{ deep: true }` it also walks every nested buffer via
1445
+ * `forEachNestedBuffer`, surfacing buffer-interior uses too. The deep form is
1446
+ * what DCE needs so values referenced only inside a loop/if/for-of/try buffer
1447
+ * survive liveness — the exact bug (#1922) the per-kind ad-hoc walkers caused
1448
+ * for `while.loop`/`for.loop`.
1449
+ */
1450
+ export declare function collectUses(instr: IrInstr, opts?: {
1451
+ readonly deep?: boolean;
1452
+ }): readonly IrValueId[];