Wado

WEP: Wasm Plan Phase

Context

codegen.rs (12,000+ lines) mixes two concerns:

  1. Analysis: Scanning type tables, querying WASI registries, topological sorting, dependency resolution — deciding what to generate
  2. Encoding: Allocating Wasm indices, calling wasm_encoder APIs, emitting instructions — how to generate it

The compiler's principle states: "codegen.rs emits the Package as is, which does not have the knowledge of the previous phases." But in practice, codegen performs significant analysis before it can emit anything.

Decision

Incrementally move analysis out of codegen into wasm_plan. The wasm_plan phase analyzes the Package and attaches metadata and plans that codegen consumes.

lower → link → optimize → wasm_plan → codegen
                              ↓
                          FlatPackage {
                              component_plan: ComponentPlan,
                              // CmExportInfo attached to TirFunctions
                          }

What Lives in wasm_plan

ComponentPlan

ComponentPlan captures the structural decisions for the Component Model component:

Codegen reads ComponentPlan instead of scanning TIR imports and querying the world registry directly.

CmExportInfo

Already computed by wasm_plan and attached to TirFunction. Tells codegen how to generate CM glue code for world exports (scratch locals, required imports, async flag).

CM Converter Analysis

CmConverterRequirements centralizes analysis of which CM converters are needed for WASI function return types. Used by both optimize (DCE) and codegen.

Type Ordering Analysis

Pure analysis functions for type registration ordering:

These are pure functions that don't depend on codegen state. Codegen delegates to them for ordering decisions.

What Stays in Codegen

Type Registration

The type registration logic (15+ phases in build_main_module) stays in codegen because it is tightly coupled to codegen's index management state (struct_types, array_types, tuple_types, etc.). The "skip if not yet registered" checks depend on knowing what Wasm types have been allocated so far, which is encoding state.

Moving this to wasm_plan would require duplicating codegen's state tracking (shadow HashSet<StructName> etc.), creating a maintenance burden without improving separation of concerns.

Codegen calls the pure analysis functions from wasm_plan for ordering decisions (topo sort, self-ref detection) but manages the registration phases itself.

Component Encoding

Codegen reads ComponentPlan and mechanically encodes the component structure using ComponentBuilder. WASI import generation, function lowering, and type definitions remain in codegen as they are pure encoding.

Instruction Emission

generate_expr(), generate_function(), etc. remain in codegen.

Design Principles

wasm_plan answers "what", codegen answers "how"

Pure analysis functions live in wasm_plan

Migration Path

Consequences

Benefits

Trade-offs