1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
//! WebAssembly GC + tail-call backend.
//!
//! Parallel to `src/codegen/wasm/` until bench numbers decide which one
//! survives 0.16. See `README.md` for the design notes (why this exists,
//! type representation, what's deliberately out of scope).
//!
//! Status: Phase 1 — module scaffold. `compile_to_wasm_gc` returns a
//! placeholder error until a hello-world emitter lands in `module.rs`.
//!
//! ## Phase E (resolved AST) migration — shipped
//!
//! Issue #147 phase E migrates every backend from consuming
//! `crate::ast::Expr` / `FnBody` / `Pattern` to consuming the
//! resolved-HIR shapes in `crate::ir::hir`. The wasm-gc backend
//! shipped across five PRs:
//!
//! - **PR 9.0.1** — `body/infer.rs` type readers generic over
//! `Spanned<T: Debug>` so they work uniformly against
//! `Spanned<Expr>` and `Spanned<ResolvedExpr>`.
//! - **PR 9** (foundation) — shared `CodegenContext::resolve_fn_def`
//! / `resolve_expr` / `resolve_stmt` / `resolve_pattern` methods.
//! Behaviour-neutral one-line lookup boundary for follow-ups.
//! - **PR 9.1** — `body/emit.rs` (+ `body/{slots, builtins,
//! builtins_wasip2}.rs`) take `&Spanned<ResolvedExpr>`. The
//! `Expr::FnCall(Attr(Ident("X"), member), args)` recognition
//! tree collapses to `ResolvedCallee` / `ResolvedCtor` dispatch.
//! - **PR 9.2** — `types_discovery.rs` / `types.rs` / `module.rs`
//! program-level walkers consume `&ResolvedFnDef` /
//! `&Spanned<ResolvedExpr>`. After this PR every walker /
//! emitter reads identity off the resolved HIR; the source-shape
//! `&FnDef` borrows survive only for signature metadata
//! (`fd.return_type` / `fd.params` as source strings, kept
//! verbatim for WIT signature emission and param-annotation
//! passthrough).
//! - **PR 9.3a** — `CodegenContext::resolve_fn_def` keys lookup by
//! `FnKey`/`FnId` via `SymbolTable::fn_id_of`, not bare name.
//! Closes the bare-name-flat-search smell that worked only
//! because `flatten_multimodule` prefixes dep fn names.
//! - **PR 9.3b** — [`view::WasmGcLinkedView`] promotes the post-
//! flatten resolver rebuild to a first-class backend-link stage.
//! The pipeline stays module-aware; wasm-gc owns its single-
//! module link view as a legal codegen concept, not a transitional
//! hack. `fn_def_by_id(FnId)` mirrors the FnId-keyed pattern
//! from PR 9.3a.
//! - **PR 9.3c** — [`body::FnMap`] keyed by `FnId` only (was
//! `by_name: HashMap<String, FnEntry>` pre-9.3c). `Call(Fn(id))`
//! and `ResolvedExpr::TailCall { target }` dispatch through
//! `fn_map.by_id.get(&id)` so call lowering matches the FnId-
//! keyed identity layer end to end.
//!
//! The byte-identical gate for every wasm-gc snapshot
//! (`order_total.wasm` md5 `61e45b325279e17e1b0d8dce3fde43f9`, the
//! game suite, the wasip2 stress fixtures) held across each PR.
use crateTopLevel;
use crateAnalysisResult;
pub use ;
pub use flatten_multimodule;
/// Backend lowering mode — selects the host-bridge shape the wasm-gc
/// emitter targets.
///
/// `AverBridge` is the original single-target output: `aver/*` host
/// imports (e.g. `("aver", "console_print")`), `_start: () -> ()`
/// export, JS-host-visible `__rt_string_*` exports. Used by browsers,
/// Cloudflare Workers, embedded wasmtime via `aver run --wasm-gc`.
///
/// `Wasip2` is direct WIT lowering for `--target wasip2`: canonical-
/// ABI imports of `wasi:cli/*` and `wasi:io/streams`, an export
/// named `wasi:cli/run@0.2.4#run` with `() -> i32`, internal-only
/// linear memory. The wasm-gc core wrapped via
/// `wit_component::ComponentEncoder` becomes a WASI 0.2 component;
/// no preview-1 adapter, no compatibility bridge. See `docs/wasip2.md`
/// and `feedback_aver_no_preview1_adapter` for the architectural
/// decision.
///
/// Phase 1.2b1 of 0.18 "Span" introduces this enum as the single
/// hinge: every per-target branching call inside the wasm-gc
/// emitter consults it. Earlier phases shipped only `AverBridge`
/// (single-flavor output).
/// Compile post-pipeline IR (`items`) to a WebAssembly GC module
/// in the `AverBridge` target shape — `aver/*` host imports + the
/// `__rt_*` JS bridge + `_start` export. This is the path used by
/// `--target wasm-gc` (browsers, Workers, embedded wasmtime via
/// `aver run --wasm-gc`).
///
/// # Epic #170 Phase 6 contract — input shape
///
/// **Input is post-pipeline AST `&[TopLevel]`, not
/// `&ResolvedProgramView`**, and this is intentional. The wasm-gc
/// backend runs its own [`backend-link-stage`](self::view): a
/// `flatten_multimodule` pass collapses dep modules into the entry
/// items with module-prefixed names (`Fractal.render` →
/// `Fractal_render`), then [`WasmGcLinkedView`] runs a fresh resolver
/// pass against the flattened slice. The pre-link `ResolvedProgramView`
/// from the pipeline keyed against the pre-flatten `SymbolTable`
/// doesn't match the post-link namespace, so this backend builds
/// its own post-link view internally rather than consuming the
/// shared one.
///
/// **What this means for identity safety**: post-flatten lookups
/// inside the backend go through `WasmGcLinkedView::fn_def_by_id`
/// (opaque `FnId`), not bare-name walks over the flattened items.
/// Cross-module same-bare-name fns get distinct `FnId`s by virtue
/// of the prefix-mangle, and the link view's resolver pass
/// canonicalises them.
///
/// [`WasmGcLinkedView`]: self::view::WasmGcLinkedView
/// `compile_to_wasm_gc` returning the MIR-coverage count alongside the
/// module bytes. MIR is the only codegen path; the count is how many
/// fns the MIR body emitter actually rendered (the real
/// `emit_fn_body_via_mir` Some/None decision, not the structural
/// coverage predicate). Fns it doesn't cover get an `unreachable`
/// trap-stub body. The single-file differential test uses this to hold
/// a coverage floor — a covered construct silently regressing to a trap
/// stub drops the count below the floor and fails CI.
/// Same as `compile_to_wasm_gc` but exports a JS-callable
/// `aver_http_handle(method, url, query, body, country) ->
/// (status, body)` wrapper around the named user fn (whose
/// signature must be `(HttpRequest) -> HttpResponse`). Equivalent
/// to the legacy backend's `--bridge fetch`.
/// Compile post-pipeline IR (`items`) to a WebAssembly GC module
/// in the `Wasip2` target shape — canonical-ABI imports for
/// `wasi:cli/*` and `wasi:io/streams`, `wasi:cli/run@0.2.4#run`
/// export with `() -> i32`. The returned core bytes are intended
/// to be wrapped by `wit_component::ComponentEncoder` into a
/// `.component.wasm` (handled by `src/codegen/wasip2/wrap.rs`).
///
/// Phase 1.2b1 of 0.18 "Span" — at this commit the entry point
/// exists but `module::emit_module_with` does not yet branch on
/// the target, so the produced bytes are identical to
/// `compile_to_wasm_gc`. Subsequent commits in this phase wire
/// the actual canonical-ABI shape.
/// `--target wasip2 --world wasi:http/proxy` entry — Phase 3 / 0.19.
/// `handler` names the user-source fn `(HttpRequest) -> HttpResponse`
/// reachable from `main`'s trailing `HttpServer.listen(port, handler)`
/// call (extracted upstream by the CLI). The wasm-gc emitter swaps
/// the `wasi:cli/run` entry-point for `wasi:http/incoming-handler#
/// handle`, decodes the host-supplied incoming-request resource into
/// an Aver `HttpRequest`, runs `handler`, encodes the returned
/// `HttpResponse` into an outgoing-response, and calls
/// `response-outparam.set` — the host (`wasmtime serve` / Spin /
/// wasmCloud) then writes the response bytes back to the client.
///
/// `main` still gets emitted as a regular wasm fn but is never
/// invoked at runtime (the proxy world has no `_start`); the
/// `HttpServer.listen` call inside it lowers to a no-op so body
/// validation passes. The `port` arg is ignored at codegen time —
/// the host's listener flag (`--http=:N`) decides the bind socket.