Skip to main content

DecodedModule

Struct DecodedModule 

Source
pub struct DecodedModule {
Show 27 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 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.

§imports: Vec<ImportEntry>

Import entries (module name, field name, kind)

§num_imported_funcs: u32

Number 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>§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

Source

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.

Source

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 CallIndirectGuardsbase_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.func entry, out-of-range write) contributes all-None slots — 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

Source§

fn clone(&self) -> DecodedModule

Returns a duplicate of the value. Read more
1.0.0 (const: unstable) · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Debug for DecodedModule

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.