pub struct DecodedModule {Show 28 fields
pub functions: Vec<FunctionOps>,
pub memories: Vec<WasmMemory>,
pub data_segments: Vec<(u32, Vec<u8>)>,
pub extra_memory_data_segments: Vec<(u32, u32, Vec<u8>)>,
pub multi_memory_decline: Option<String>,
pub default_memory_nonconst_data: Option<String>,
pub imports: Vec<ImportEntry>,
pub num_imported_funcs: u32,
pub func_arg_counts: Vec<u32>,
pub type_arg_counts: Vec<u32>,
pub func_ret_i64: Vec<bool>,
pub type_ret_i64: Vec<bool>,
pub func_params_i64: Vec<Vec<bool>>,
pub func_params_f32: Vec<Vec<bool>>,
pub func_params_f64: Vec<Vec<bool>>,
pub func_ret_f32: Vec<bool>,
pub func_ret_f64: Vec<bool>,
pub type_ret_f32: Vec<bool>,
pub type_ret_f64: Vec<bool>,
pub globals: Vec<WasmGlobal>,
pub elem_func_indices: Vec<u32>,
pub table_size: Option<u32>,
pub table_sizes: Vec<Option<u32>>,
pub elem_segments: Vec<ElemSegmentInfo>,
pub func_type_indices: Vec<u32>,
pub func_result_counts: Vec<u32>,
pub type_signatures: Vec<String>,
pub wsc_facts: Vec<WscFact>,
}Expand description
Decoded WASM module with functions and memory
Fields§
§functions: Vec<FunctionOps>Decoded functions
memories: Vec<WasmMemory>Linear memories
data_segments: Vec<(u32, Vec<u8>)>Data segments (offset, data) for memory initialization.
MEMORY 0 ONLY — the legacy single-memory field every existing consumer
reads; its shape and contents are unchanged by multi-memory (#406).
Segments targeting memory > 0 live in
Self::extra_memory_data_segments.
extra_memory_data_segments: Vec<(u32, u32, Vec<u8>)>VCR-MEM-002 phase 1 (#406): active const-offset data segments on
NON-DEFAULT memories, as (memory_index, offset, bytes) with
memory_index > 0. Previously these were silently dropped (memory k
shipped uninitialized while its loads compiled). Declaration order.
multi_memory_decline: Option<String>VCR-MEM-002 phase 1 (#406): Some(reason) when the module contains a
multi-memory shape decode cannot lower (e.g. an active data segment on
memory > 0 with a non-constant offset). The multi-memory compile path
must decline LOUDLY with this reason; single-memory modules never set
it.
default_memory_nonconst_data: Option<String>#851 — Some(reason) when an active data segment on MEMORY 0 has a
NON-CONSTANT offset expression: such a segment cannot be placed at
compile time and is absent from Self::data_segments (the legacy
drop, kept frozen for the ARM/RV32 paths). Recording it lets a backend
with no runtime-offset placement (aarch64) decline LOUDLY instead of
shipping the region uninitialized — the segment would otherwise be
INVISIBLE to any post-decode honesty check.
imports: Vec<ImportEntry>Import entries (module name, field name, kind)
num_imported_funcs: u32Number of imported functions (for distinguishing import calls from local calls)
func_arg_counts: Vec<u32>AAPCS integer-argument count per function, indexed by the full WASM
function index (imported functions first, then locally-defined ones).
Used by the backend to marshal call arguments into R0–R3 (issue #195).
Counts every parameter as one slot (i64/f64 over-counted — see the
backend’s set_func_arg_counts scope note).
type_arg_counts: Vec<u32>AAPCS integer-argument count per function type, indexed by type index.
Used by call_indirect, whose callee arg count comes from the static
type index (issue #195).
func_ret_i64: Vec<bool>#311: whether each function (full index, imports first) returns i64 — the call lowering must tag the result as a register PAIR (r0:r1) or the hi half is invisible to liveness and the next constant clobbers it.
type_ret_i64: Vec<bool>#311: whether each function type returns i64 (for call_indirect).
func_params_i64: Vec<Vec<bool>>#359: declared parameter widths per function (full index, imports
first): func_params_i64[f][k] is true when param k is i64/f64. The
AAPCS stack-argument path needs the declared widths — op-stream inference
can’t see an unused i64 param that still shifts the incoming-stack layout.
func_params_f32: Vec<Vec<bool>>GI-FPU-002 (#619/#369): declared f32-param mask per function (full
index, imports first): func_params_f32[f][k] is true when param k is
f32. The direct selector homes hard-float f32 args in S0..S15 (AAPCS-VFP),
which op-stream inference cannot recover for a pure-passthrough f32 param.
func_params_f64: Vec<Vec<bool>>GI-FPU-002 phase 2 (#369): declared f64-param mask per function
(full index, imports first): func_params_f64[f][k] is true when param
k is f64. Hard-float targets decline such functions loudly (the
legacy width inference treats the param as an i64 CORE pair — wrong
registers under AAPCS-VFP). Distinct from func_params_i64, which
deliberately lumps i64 and f64 for frame-layout purposes.
func_ret_f32: Vec<bool>GI-FPU-002 phase 2 (#719/#369): whether each function (full index, imports first) returns f32. The direct selector’s epilogue homes an f32 result in S0 (AAPCS-VFP); when the result value transited a core register (e.g. it came from a call that returned f32 as an integer-tagged R0), the epilogue must loudly decline rather than emit the integer R0 return (a silent miscompile — the caller reads S0). Op-stream inference cannot see a pure-passthrough f32 return, so it is carried from the declared signature.
func_ret_f64: Vec<bool>GI-FPU-002 phase 2 (#719/#369): whether each function returns f64 (D0
under AAPCS-VFP). Same epilogue-soundness role as func_ret_f32.
type_ret_f32: Vec<bool>GI-FPU-002 phase 2 (#719/#369): whether each function type returns
f32 / f64 — the call_indirect analogue of func_ret_f32/func_ret_f64
(the selector loudly declines an indirect call whose static type returns
a float this increment does not marshal, rather than tag S0/D0 as R0).
type_ret_f64: Vec<bool>See Self::type_ret_f32.
globals: Vec<WasmGlobal>Defined globals with their initializers (#237). Empty if the module has
no global section. Used by the native-pointer ABI to make a global whose
initializer is a linear-memory address (e.g. $__stack_pointer)
self-contained rather than table-relative.
elem_func_indices: Vec<u32>Function indices that populate any table via an element segment (#275).
These are the possible call_indirect targets — a function reached only
through the table is invisible to direct-call reachability, so the
whole-graph closure must treat every table entry as reachable once any
reachable function performs a call_indirect. Empty for modules with no
element section (every leaf/direct-call module), keeping output identical.
table_size: Option<u32>#642: compile-time size (in entries) of table 0 — table_sizes[0],
kept as a convenience accessor. See Self::table_sizes.
table_sizes: Vec<Option<u32>>#650: compile-time size (in entries) per table, indexed by table index
(imported tables first, then the table section, in declaration order).
A DEFINED table’s size is exact: table.grow/table.set are
unsupported ops (their functions loud-skip at decode), so nothing
synth compiles can resize or retype a table. An imported table only
yields a sound bound when its limits pin the size (max == initial);
otherwise its entry is None and the call_indirect lowering
declines (for that table AND for any later table, whose base offset
within the contiguous R11 region is then unknown).
elem_segments: Vec<ElemSegmentInfo>#642: per element segment, everything the closed-world call_indirect
type check needs. offset is the const i32 placement of an ACTIVE
segment into table table_index (None = passive/declared/non-const
offset — statically unverifiable placement); funcs are the segment’s
function indices in slot order (None = an entry was not a plain
ref.func, e.g. ref.null — statically unverifiable contents).
func_type_indices: Vec<u32>#642: type index per function, indexed by the FULL function index (imports first, then locally-defined ones).
func_result_counts: Vec<u32>#851: result (return-value) count per function, indexed by the FULL
function index (imports first). 0 = void, 1 = single result, etc.
(saturated at 255 for pathological signatures). The aarch64 direct-call
lowering needs the 0-vs-1 distinction — func_ret_i64/f32/f64 carry the
result TYPE but conflate void and i32 (both all-false), so they cannot say
whether a value is pushed back after the call.
type_signatures: Vec<String>#642: canonical structural signature per type index (params/results
rendered as a string) — used for the closed-world call_indirect type
check, which must compare SIGNATURES, not raw type indices (a module
may carry structurally-identical duplicate types).
wsc_facts: Vec<WscFact>VCR-PERF-002 Phase 1 (#494): proven invariants from loom’s wsc.facts
custom section, keyed by (function index, value id) — see
docs/design/wsc-facts-encoding.md (schema v1) and
crate::wsc_facts::parse_wsc_facts. FAIL-SAFE by contract (loom#231
Q4): a missing/unparseable section or unknown version yields the empty
vec, unknown fact kinds are skipped — never a decode error. Phase 1 is
ingestion only: NO codegen path consumes these yet, so emitted bytes
are unchanged whether or not a module carries the section.
Implementations§
Source§impl DecodedModule
impl DecodedModule
Sourcepub fn call_indirect_guards(&self) -> CallIndirectGuards
pub fn call_indirect_guards(&self) -> CallIndirectGuards
#642/#650: compute the call_indirect guard inputs — per table, the
compile-time size for the runtime bounds check, the base byte offset
within the contiguous R11 region, and the per-expected-type
closed-world verdict that discharges the type check at compile time.
See CallIndirectGuards for the layout contract and soundness
argument.
Sourcepub fn funcref_region_slots(&self) -> Vec<Option<u32>>
pub fn funcref_region_slots(&self) -> Vec<Option<u32>>
#275: the STATIC image of the contiguous funcref region — one slot per
table entry across ALL tables in declaration order (the exact layout
CallIndirectGuards’ base_byte_offset contract describes), each
Some(full_function_index) for a statically-known initialized slot
and None for a null (or not statically attributable) slot. The
self-contained image builder resolves each Some to the laid-out
function address (Thumb bit set) and links every None as a ZERO
word, which the dispatch’s #664 null check / #676 id-0 compare traps.
Mirrors the reconstruction in Self::call_indirect_guards:
- stops at the first table with no compile-time size (later tables have no constant base offset, so no dispatch can reach them);
- a table whose segments are not statically verifiable (non-const
offset, non-
ref.funcentry, out-of-range write) contributes all-Noneslots — every dispatch into it declines at the lowering anyway, and a rogue read traps on the zero word rather than branch.
Trait Implementations§
Source§impl Clone for DecodedModule
impl Clone for DecodedModule
Source§fn clone(&self) -> DecodedModule
fn clone(&self) -> DecodedModule
1.0.0 (const: unstable) · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source. Read more