Modules¶
For modules, the execution semantics primarily defines instantiation, which allocates instances for a module and its contained definitions, initializes tables and memories from contained element and data segments, and invokes the start function if present. It also includes invocation of exported functions.
Instantiation depends on a number of auxiliary notions for type-checking imports and allocating instances.
External Typing¶
For the purpose of checking external values against imports, such values are classified by external types. The following auxiliary typing rules specify this typing relation relative to a store \(S\) in which the referenced instances live.
\(\href{../exec/runtime.html#syntax-externval}{\mathsf{func}}~a\)¶
The store entry \(S.\href{../exec/runtime.html#syntax-store}{\mathsf{funcs}}[a]\) must exist.
Then \(\href{../exec/runtime.html#syntax-externval}{\mathsf{func}}~a\) is valid with external type \(\href{../syntax/types.html#syntax-externtype}{\mathsf{func}}~S.\href{../exec/runtime.html#syntax-store}{\mathsf{funcs}}[a].\href{../exec/runtime.html#syntax-funcinst}{\mathsf{type}}\).
\(\href{../exec/runtime.html#syntax-externval}{\mathsf{table}}~a\)¶
The store entry \(S.\href{../exec/runtime.html#syntax-store}{\mathsf{tables}}[a]\) must exist.
Then \(\href{../exec/runtime.html#syntax-externval}{\mathsf{table}}~a\) is valid with external type \(\href{../syntax/types.html#syntax-externtype}{\mathsf{table}}~S.\href{../exec/runtime.html#syntax-store}{\mathsf{tables}}[a].\href{../exec/runtime.html#syntax-tableinst}{\mathsf{type}}\).
\(\href{../exec/runtime.html#syntax-externval}{\mathsf{mem}}~a\)¶
The store entry \(S.\href{../exec/runtime.html#syntax-store}{\mathsf{mems}}[a]\) must exist.
Then \(\href{../exec/runtime.html#syntax-externval}{\mathsf{mem}}~a\) is valid with external type \(\href{../syntax/types.html#syntax-externtype}{\mathsf{mem}}~S.\href{../exec/runtime.html#syntax-store}{\mathsf{mems}}[a].\href{../exec/runtime.html#syntax-meminst}{\mathsf{type}}\).
\(\href{../exec/runtime.html#syntax-externval}{\mathsf{global}}~a\)¶
The store entry \(S.\href{../exec/runtime.html#syntax-store}{\mathsf{globals}}[a]\) must exist.
Then \(\href{../exec/runtime.html#syntax-externval}{\mathsf{global}}~a\) is valid with external type \(\href{../syntax/types.html#syntax-externtype}{\mathsf{global}}~S.\href{../exec/runtime.html#syntax-store}{\mathsf{globals}}[a].\href{../exec/runtime.html#syntax-globalinst}{\mathsf{type}}\).
Value Typing¶
For the purpose of checking argument values against the parameter types of exported functions, values are classified by value types. The following auxiliary typing rules specify this typing relation relative to a store \(S\) in which possibly referenced addresses live.
Numeric Values \(t.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~c\)¶
The value is valid with number type \(t\).
Null References \(\href{../syntax/instructions.html#syntax-instr-ref}{\mathsf{ref{.}null}}~t\)¶
The value is valid with reference type \(t\).
Function References \(\href{../exec/runtime.html#syntax-ref}{\mathsf{ref}}~a\)¶
The external value \(\href{../exec/runtime.html#syntax-externval}{\mathsf{func}}~a\) must be valid.
Then the value is valid with reference type \(\href{../syntax/types.html#syntax-reftype}{\mathsf{funcref}}\).
External References \(\href{../exec/runtime.html#syntax-ref.extern}{\mathsf{ref{.}extern}}~a\)¶
The value is valid with reference type \(\href{../syntax/types.html#syntax-reftype}{\mathsf{externref}}\).
Allocation¶
New instances of functions, tables, memories, and globals are allocated in a store \(S\), as defined by the following auxiliary functions.
Functions¶
Let \(\href{../syntax/modules.html#syntax-func}{\mathit{func}}\) be the function to allocate and \(\href{../exec/runtime.html#syntax-moduleinst}{\mathit{moduleinst}}\) its module instance.
Let \(a\) be the first free function address in \(S\).
Let \(\href{../syntax/types.html#syntax-functype}{\mathit{functype}}\) be the function type \(\href{../exec/runtime.html#syntax-moduleinst}{\mathit{moduleinst}}.\href{../exec/runtime.html#syntax-moduleinst}{\mathsf{types}}[\href{../syntax/modules.html#syntax-func}{\mathit{func}}.\href{../syntax/modules.html#syntax-func}{\mathsf{type}}]\).
Let \(\href{../exec/runtime.html#syntax-funcinst}{\mathit{funcinst}}\) be the function instance \(\{ \href{../exec/runtime.html#syntax-funcinst}{\mathsf{type}}~\href{../syntax/types.html#syntax-functype}{\mathit{functype}}, \href{../exec/runtime.html#syntax-funcinst}{\mathsf{module}}~\href{../exec/runtime.html#syntax-moduleinst}{\mathit{moduleinst}}, \href{../exec/runtime.html#syntax-funcinst}{\mathsf{code}}~\href{../syntax/modules.html#syntax-func}{\mathit{func}} \}\).
Append \(\href{../exec/runtime.html#syntax-funcinst}{\mathit{funcinst}}\) to the \(\href{../exec/runtime.html#syntax-store}{\mathsf{funcs}}\) of \(S\).
Return \(a\).
Host Functions¶
Let \(\href{../exec/runtime.html#syntax-hostfunc}{\mathit{hostfunc}}\) be the host function to allocate and \(\href{../syntax/types.html#syntax-functype}{\mathit{functype}}\) its function type.
Let \(a\) be the first free function address in \(S\).
Let \(\href{../exec/runtime.html#syntax-funcinst}{\mathit{funcinst}}\) be the function instance \(\{ \href{../exec/runtime.html#syntax-funcinst}{\mathsf{type}}~\href{../syntax/types.html#syntax-functype}{\mathit{functype}}, \href{../exec/runtime.html#syntax-funcinst}{\mathsf{hostcode}}~\href{../exec/runtime.html#syntax-hostfunc}{\mathit{hostfunc}} \}\).
Append \(\href{../exec/runtime.html#syntax-funcinst}{\mathit{funcinst}}\) to the \(\href{../exec/runtime.html#syntax-store}{\mathsf{funcs}}\) of \(S\).
Return \(a\).
Note
Host functions are never allocated by the WebAssembly semantics itself, but may be allocated by the embedder.
Tables¶
Let \(\href{../syntax/types.html#syntax-tabletype}{\mathit{tabletype}}\) be the table type to allocate and \(\href{../exec/runtime.html#syntax-ref}{\mathit{ref}}\) the initialization value.
Let \((\{\href{../syntax/types.html#syntax-limits}{\mathsf{min}}~n, \href{../syntax/types.html#syntax-limits}{\mathsf{max}}~m^?\}~\href{../syntax/types.html#syntax-reftype}{\mathit{reftype}})\) be the structure of table type \(\href{../syntax/types.html#syntax-tabletype}{\mathit{tabletype}}\).
Let \(a\) be the first free table address in \(S\).
Let \(\href{../exec/runtime.html#syntax-tableinst}{\mathit{tableinst}}\) be the table instance \(\{ \href{../exec/runtime.html#syntax-tableinst}{\mathsf{type}}~\href{../syntax/types.html#syntax-tabletype}{\mathit{tabletype}}, \href{../exec/runtime.html#syntax-tableinst}{\mathsf{elem}}~\href{../exec/runtime.html#syntax-ref}{\mathit{ref}}^n \}\) with \(n\) elements set to \(\href{../exec/runtime.html#syntax-ref}{\mathit{ref}}\).
Append \(\href{../exec/runtime.html#syntax-tableinst}{\mathit{tableinst}}\) to the \(\href{../exec/runtime.html#syntax-store}{\mathsf{tables}}\) of \(S\).
Return \(a\).
Memories¶
Let \(\href{../syntax/types.html#syntax-memtype}{\mathit{memtype}}\) be the memory type to allocate.
Let \(\{\href{../syntax/types.html#syntax-limits}{\mathsf{min}}~n, \href{../syntax/types.html#syntax-limits}{\mathsf{max}}~m^?\}\) be the structure of memory type \(\href{../syntax/types.html#syntax-memtype}{\mathit{memtype}}\).
Let \(a\) be the first free memory address in \(S\).
Let \(\href{../exec/runtime.html#syntax-meminst}{\mathit{meminst}}\) be the memory instance \(\{ \href{../exec/runtime.html#syntax-meminst}{\mathsf{type}}~\href{../syntax/types.html#syntax-memtype}{\mathit{memtype}}, \href{../exec/runtime.html#syntax-meminst}{\mathsf{data}}~(\def\mathdef2205#1{\mathtt{0x#1}}\mathdef2205{00})^{n \cdot 64\,\mathrm{Ki}} \}\) that contains \(n\) pages of zeroed bytes.
Append \(\href{../exec/runtime.html#syntax-meminst}{\mathit{meminst}}\) to the \(\href{../exec/runtime.html#syntax-store}{\mathsf{mems}}\) of \(S\).
Return \(a\).
Globals¶
Let \(\href{../syntax/types.html#syntax-globaltype}{\mathit{globaltype}}\) be the global type to allocate and \(\href{../exec/runtime.html#syntax-val}{\mathit{val}}\) the value to initialize the global with.
Let \(a\) be the first free global address in \(S\).
Let \(\href{../exec/runtime.html#syntax-globalinst}{\mathit{globalinst}}\) be the global instance \(\{ \href{../exec/runtime.html#syntax-globalinst}{\mathsf{type}}~\href{../syntax/types.html#syntax-globaltype}{\mathit{globaltype}}, \href{../exec/runtime.html#syntax-globalinst}{\mathsf{value}}~\href{../exec/runtime.html#syntax-val}{\mathit{val}} \}\).
Append \(\href{../exec/runtime.html#syntax-globalinst}{\mathit{globalinst}}\) to the \(\href{../exec/runtime.html#syntax-store}{\mathsf{globals}}\) of \(S\).
Return \(a\).
Element segments¶
Let \(\href{../syntax/types.html#syntax-reftype}{\mathit{reftype}}\) be the elements’ type and \(\href{../exec/runtime.html#syntax-ref}{\mathit{ref}}^\ast\) the vector of references to allocate.
Let \(a\) be the first free element address in \(S\).
Let \(\href{../exec/runtime.html#syntax-eleminst}{\mathit{eleminst}}\) be the element instance \(\{ \href{../exec/runtime.html#syntax-eleminst}{\mathsf{type}}~\href{../syntax/types.html#syntax-reftype}{\mathit{reftype}}, \href{../exec/runtime.html#syntax-eleminst}{\mathsf{elem}}~\href{../exec/runtime.html#syntax-ref}{\mathit{ref}}^\ast \}\).
Append \(\href{../exec/runtime.html#syntax-eleminst}{\mathit{eleminst}}\) to the \(\href{../exec/runtime.html#syntax-store}{\mathsf{elems}}\) of \(S\).
Return \(a\).
Data segments¶
Let \(\href{../exec/numerics.html#aux-bytes}{\mathrm{bytes}}\) be the vector of bytes to allocate.
Let \(a\) be the first free data address in \(S\).
Let \(\href{../exec/runtime.html#syntax-datainst}{\mathit{datainst}}\) be the data instance \(\{ \href{../exec/runtime.html#syntax-datainst}{\mathsf{data}}~\href{../exec/numerics.html#aux-bytes}{\mathrm{bytes}} \}\).
Append \(\href{../exec/runtime.html#syntax-datainst}{\mathit{datainst}}\) to the \(\href{../exec/runtime.html#syntax-store}{\mathsf{datas}}\) of \(S\).
Return \(a\).
Growing tables¶
Let \(\href{../exec/runtime.html#syntax-tableinst}{\mathit{tableinst}}\) be the table instance to grow, \(n\) the number of elements by which to grow it, and \(\href{../exec/runtime.html#syntax-ref}{\mathit{ref}}\) the initialization value.
Let \(\mathit{len}\) be \(n\) added to the length of \(\href{../exec/runtime.html#syntax-tableinst}{\mathit{tableinst}}.\href{../exec/runtime.html#syntax-tableinst}{\mathsf{elem}}\).
If \(\mathit{len}\) is larger than or equal to \(2^{32}\), then fail.
Let \(\href{../syntax/types.html#syntax-limits}{\mathit{limits}}~t\) be the structure of table type \(\href{../exec/runtime.html#syntax-tableinst}{\mathit{tableinst}}.\href{../exec/runtime.html#syntax-tableinst}{\mathsf{type}}\).
Let \(\href{../syntax/types.html#syntax-limits}{\mathit{limits}}'\) be \(\href{../syntax/types.html#syntax-limits}{\mathit{limits}}\) with \(\href{../syntax/types.html#syntax-limits}{\mathsf{min}}\) updated to \(\mathit{len}\).
If \(\href{../syntax/types.html#syntax-limits}{\mathit{limits}}'\) is not valid, then fail.
Append \(\href{../exec/runtime.html#syntax-ref}{\mathit{ref}}^n\) to \(\href{../exec/runtime.html#syntax-tableinst}{\mathit{tableinst}}.\href{../exec/runtime.html#syntax-tableinst}{\mathsf{elem}}\).
Set \(\href{../exec/runtime.html#syntax-tableinst}{\mathit{tableinst}}.\href{../exec/runtime.html#syntax-tableinst}{\mathsf{type}}\) to the table type \(\href{../syntax/types.html#syntax-limits}{\mathit{limits}}'~t\).
Growing memories¶
Let \(\href{../exec/runtime.html#syntax-meminst}{\mathit{meminst}}\) be the memory instance to grow and \(n\) the number of pages by which to grow it.
Assert: The length of \(\href{../exec/runtime.html#syntax-meminst}{\mathit{meminst}}.\href{../exec/runtime.html#syntax-meminst}{\mathsf{data}}\) is divisible by the page size \(64\,\mathrm{Ki}\).
Let \(\mathit{len}\) be \(n\) added to the length of \(\href{../exec/runtime.html#syntax-meminst}{\mathit{meminst}}.\href{../exec/runtime.html#syntax-meminst}{\mathsf{data}}\) divided by the page size \(64\,\mathrm{Ki}\).
If \(\mathit{len}\) is larger than \(2^{16}\), then fail.
Let \(\href{../syntax/types.html#syntax-limits}{\mathit{limits}}\) be the structure of memory type \(\href{../exec/runtime.html#syntax-meminst}{\mathit{meminst}}.\href{../exec/runtime.html#syntax-meminst}{\mathsf{type}}\).
Let \(\href{../syntax/types.html#syntax-limits}{\mathit{limits}}'\) be \(\href{../syntax/types.html#syntax-limits}{\mathit{limits}}\) with \(\href{../syntax/types.html#syntax-limits}{\mathsf{min}}\) updated to \(\mathit{len}\).
If \(\href{../syntax/types.html#syntax-limits}{\mathit{limits}}'\) is not valid, then fail.
Append \(n\) times \(64\,\mathrm{Ki}\) bytes with value \(\def\mathdef2207#1{\mathtt{0x#1}}\mathdef2207{00}\) to \(\href{../exec/runtime.html#syntax-meminst}{\mathit{meminst}}.\href{../exec/runtime.html#syntax-meminst}{\mathsf{data}}\).
Set \(\href{../exec/runtime.html#syntax-meminst}{\mathit{meminst}}.\href{../exec/runtime.html#syntax-meminst}{\mathsf{type}}\) to the memory type \(\href{../syntax/types.html#syntax-limits}{\mathit{limits}}'\).
Modules¶
The allocation function for modules requires a suitable list of external values that are assumed to match the import vector of the module, a list of initialization values for the module’s globals, and list of reference vectors for the module’s element segments.
Let \(\href{../syntax/modules.html#syntax-module}{\mathit{module}}\) be the module to allocate and \(\href{../exec/runtime.html#syntax-externval}{\mathit{externval}}_{\mathrm{im}}^\ast\) the vector of external values providing the module’s imports, \(\href{../exec/runtime.html#syntax-val}{\mathit{val}}^\ast\) the initialization values of the module’s globals, and \((\href{../exec/runtime.html#syntax-ref}{\mathit{ref}}^\ast)^\ast\) the reference vectors of the module’s element segments.
For each function \(\href{../syntax/modules.html#syntax-func}{\mathit{func}}_i\) in \(\href{../syntax/modules.html#syntax-module}{\mathit{module}}.\href{../syntax/modules.html#syntax-module}{\mathsf{funcs}}\), do:
Let \(\href{../exec/runtime.html#syntax-funcaddr}{\mathit{funcaddr}}_i\) be the function address resulting from allocating \(\href{../syntax/modules.html#syntax-func}{\mathit{func}}_i\) for the module instance \(\href{../exec/runtime.html#syntax-moduleinst}{\mathit{moduleinst}}\) defined below.
For each table \(\href{../syntax/modules.html#syntax-table}{\mathit{table}}_i\) in \(\href{../syntax/modules.html#syntax-module}{\mathit{module}}.\href{../syntax/modules.html#syntax-module}{\mathsf{tables}}\), do:
Let \(\href{../syntax/types.html#syntax-limits}{\mathit{limits}}_i~t_i\) be the table type \(\href{../syntax/modules.html#syntax-table}{\mathit{table}}_i.\href{../syntax/modules.html#syntax-table}{\mathsf{type}}\).
Let \(\href{../exec/runtime.html#syntax-tableaddr}{\mathit{tableaddr}}_i\) be the table address resulting from allocating \(\href{../syntax/modules.html#syntax-table}{\mathit{table}}_i.\href{../syntax/modules.html#syntax-table}{\mathsf{type}}\) with initialization value \(\href{../syntax/instructions.html#syntax-instr-ref}{\mathsf{ref{.}null}}~t_i\).
For each memory \(\href{../syntax/modules.html#syntax-mem}{\mathit{mem}}_i\) in \(\href{../syntax/modules.html#syntax-module}{\mathit{module}}.\href{../syntax/modules.html#syntax-module}{\mathsf{mems}}\), do:
Let \(\href{../exec/runtime.html#syntax-memaddr}{\mathit{memaddr}}_i\) be the memory address resulting from allocating \(\href{../syntax/modules.html#syntax-mem}{\mathit{mem}}_i.\href{../syntax/modules.html#syntax-mem}{\mathsf{type}}\).
For each global \(\href{../syntax/modules.html#syntax-global}{\mathit{global}}_i\) in \(\href{../syntax/modules.html#syntax-module}{\mathit{module}}.\href{../syntax/modules.html#syntax-module}{\mathsf{globals}}\), do:
Let \(\href{../exec/runtime.html#syntax-globaladdr}{\mathit{globaladdr}}_i\) be the global address resulting from allocating \(\href{../syntax/modules.html#syntax-global}{\mathit{global}}_i.\href{../syntax/modules.html#syntax-global}{\mathsf{type}}\) with initializer value \(\href{../exec/runtime.html#syntax-val}{\mathit{val}}^\ast[i]\).
For each element segment \(\href{../syntax/modules.html#syntax-elem}{\mathit{elem}}_i\) in \(\href{../syntax/modules.html#syntax-module}{\mathit{module}}.\href{../syntax/modules.html#syntax-module}{\mathsf{elems}}\), do:
Let \(\href{../exec/runtime.html#syntax-elemaddr}{\mathit{elemaddr}}_i\) be the element address resulting from allocating an element instance of reference type \(\href{../syntax/modules.html#syntax-elem}{\mathit{elem}}_i.\href{../syntax/modules.html#syntax-elem}{\mathsf{type}}\) with contents \((\href{../exec/runtime.html#syntax-ref}{\mathit{ref}}^\ast)^\ast[i]\).
For each data segment \(\href{../syntax/modules.html#syntax-data}{\mathit{data}}_i\) in \(\href{../syntax/modules.html#syntax-module}{\mathit{module}}.\href{../syntax/modules.html#syntax-module}{\mathsf{datas}}\), do:
Let \(\href{../exec/runtime.html#syntax-dataaddr}{\mathit{dataaddr}}_i\) be the data address resulting from allocating a data instance with contents \(\href{../syntax/modules.html#syntax-data}{\mathit{data}}_i.\href{../syntax/modules.html#syntax-data}{\mathsf{init}}\).
Let \(\href{../exec/runtime.html#syntax-funcaddr}{\mathit{funcaddr}}^\ast\) be the concatenation of the function addresses \(\href{../exec/runtime.html#syntax-funcaddr}{\mathit{funcaddr}}_i\) in index order.
Let \(\href{../exec/runtime.html#syntax-tableaddr}{\mathit{tableaddr}}^\ast\) be the concatenation of the table addresses \(\href{../exec/runtime.html#syntax-tableaddr}{\mathit{tableaddr}}_i\) in index order.
Let \(\href{../exec/runtime.html#syntax-memaddr}{\mathit{memaddr}}^\ast\) be the concatenation of the memory addresses \(\href{../exec/runtime.html#syntax-memaddr}{\mathit{memaddr}}_i\) in index order.
Let \(\href{../exec/runtime.html#syntax-globaladdr}{\mathit{globaladdr}}^\ast\) be the concatenation of the global addresses \(\href{../exec/runtime.html#syntax-globaladdr}{\mathit{globaladdr}}_i\) in index order.
Let \(\href{../exec/runtime.html#syntax-elemaddr}{\mathit{elemaddr}}^\ast\) be the concatenation of the element addresses \(\href{../exec/runtime.html#syntax-elemaddr}{\mathit{elemaddr}}_i\) in index order.
Let \(\href{../exec/runtime.html#syntax-dataaddr}{\mathit{dataaddr}}^\ast\) be the concatenation of the data addresses \(\href{../exec/runtime.html#syntax-dataaddr}{\mathit{dataaddr}}_i\) in index order.
Let \(\href{../exec/runtime.html#syntax-funcaddr}{\mathit{funcaddr}}_{\mathrm{mod}}^\ast\) be the list of function addresses extracted from \(\href{../exec/runtime.html#syntax-externval}{\mathit{externval}}_{\mathrm{im}}^\ast\), concatenated with \(\href{../exec/runtime.html#syntax-funcaddr}{\mathit{funcaddr}}^\ast\).
Let \(\href{../exec/runtime.html#syntax-tableaddr}{\mathit{tableaddr}}_{\mathrm{mod}}^\ast\) be the list of table addresses extracted from \(\href{../exec/runtime.html#syntax-externval}{\mathit{externval}}_{\mathrm{im}}^\ast\), concatenated with \(\href{../exec/runtime.html#syntax-tableaddr}{\mathit{tableaddr}}^\ast\).
Let \(\href{../exec/runtime.html#syntax-memaddr}{\mathit{memaddr}}_{\mathrm{mod}}^\ast\) be the list of memory addresses extracted from \(\href{../exec/runtime.html#syntax-externval}{\mathit{externval}}_{\mathrm{im}}^\ast\), concatenated with \(\href{../exec/runtime.html#syntax-memaddr}{\mathit{memaddr}}^\ast\).
Let \(\href{../exec/runtime.html#syntax-globaladdr}{\mathit{globaladdr}}_{\mathrm{mod}}^\ast\) be the list of global addresses extracted from \(\href{../exec/runtime.html#syntax-externval}{\mathit{externval}}_{\mathrm{im}}^\ast\), concatenated with \(\href{../exec/runtime.html#syntax-globaladdr}{\mathit{globaladdr}}^\ast\).
For each export \(\href{../syntax/modules.html#syntax-export}{\mathit{export}}_i\) in \(\href{../syntax/modules.html#syntax-module}{\mathit{module}}.\href{../syntax/modules.html#syntax-module}{\mathsf{exports}}\), do:
If \(\href{../syntax/modules.html#syntax-export}{\mathit{export}}_i\) is a function export for function index \(x\), then let \(\href{../exec/runtime.html#syntax-externval}{\mathit{externval}}_i\) be the external value \(\href{../exec/runtime.html#syntax-externval}{\mathsf{func}}~(\href{../exec/runtime.html#syntax-funcaddr}{\mathit{funcaddr}}_{\mathrm{mod}}^\ast[x])\).
Else, if \(\href{../syntax/modules.html#syntax-export}{\mathit{export}}_i\) is a table export for table index \(x\), then let \(\href{../exec/runtime.html#syntax-externval}{\mathit{externval}}_i\) be the external value \(\href{../exec/runtime.html#syntax-externval}{\mathsf{table}}~(\href{../exec/runtime.html#syntax-tableaddr}{\mathit{tableaddr}}_{\mathrm{mod}}^\ast[x])\).
Else, if \(\href{../syntax/modules.html#syntax-export}{\mathit{export}}_i\) is a memory export for memory index \(x\), then let \(\href{../exec/runtime.html#syntax-externval}{\mathit{externval}}_i\) be the external value \(\href{../exec/runtime.html#syntax-externval}{\mathsf{mem}}~(\href{../exec/runtime.html#syntax-memaddr}{\mathit{memaddr}}_{\mathrm{mod}}^\ast[x])\).
Else, if \(\href{../syntax/modules.html#syntax-export}{\mathit{export}}_i\) is a global export for global index \(x\), then let \(\href{../exec/runtime.html#syntax-externval}{\mathit{externval}}_i\) be the external value \(\href{../exec/runtime.html#syntax-externval}{\mathsf{global}}~(\href{../exec/runtime.html#syntax-globaladdr}{\mathit{globaladdr}}_{\mathrm{mod}}^\ast[x])\).
Let \(\href{../exec/runtime.html#syntax-exportinst}{\mathit{exportinst}}_i\) be the export instance \(\{\href{../exec/runtime.html#syntax-exportinst}{\mathsf{name}}~(\href{../syntax/modules.html#syntax-export}{\mathit{export}}_i.\href{../syntax/modules.html#syntax-export}{\mathsf{name}}), \href{../exec/runtime.html#syntax-exportinst}{\mathsf{value}}~\href{../exec/runtime.html#syntax-externval}{\mathit{externval}}_i\}\).
Let \(\href{../exec/runtime.html#syntax-exportinst}{\mathit{exportinst}}^\ast\) be the concatenation of the export instances \(\href{../exec/runtime.html#syntax-exportinst}{\mathit{exportinst}}_i\) in index order.
Let \(\href{../exec/runtime.html#syntax-moduleinst}{\mathit{moduleinst}}\) be the module instance \(\{\href{../exec/runtime.html#syntax-moduleinst}{\mathsf{types}}~(\href{../syntax/modules.html#syntax-module}{\mathit{module}}.\href{../syntax/modules.html#syntax-module}{\mathsf{types}}),\) \(\href{../exec/runtime.html#syntax-moduleinst}{\mathsf{funcaddrs}}~\href{../exec/runtime.html#syntax-funcaddr}{\mathit{funcaddr}}_{\mathrm{mod}}^\ast,\) \(\href{../exec/runtime.html#syntax-moduleinst}{\mathsf{tableaddrs}}~\href{../exec/runtime.html#syntax-tableaddr}{\mathit{tableaddr}}_{\mathrm{mod}}^\ast,\) \(\href{../exec/runtime.html#syntax-moduleinst}{\mathsf{memaddrs}}~\href{../exec/runtime.html#syntax-memaddr}{\mathit{memaddr}}_{\mathrm{mod}}^\ast,\) \(\href{../exec/runtime.html#syntax-moduleinst}{\mathsf{globaladdrs}}~\href{../exec/runtime.html#syntax-globaladdr}{\mathit{globaladdr}}_{\mathrm{mod}}^\ast,\) \(\href{../exec/runtime.html#syntax-moduleinst}{\mathsf{exports}}~\href{../exec/runtime.html#syntax-exportinst}{\mathit{exportinst}}^\ast\}\).
Return \(\href{../exec/runtime.html#syntax-moduleinst}{\mathit{moduleinst}}\).
where:
Here, the notation \(\mathrm{allocx}^\ast\) is shorthand for multiple allocations of object kind \(X\), defined as follows:
Moreover, if the dots \(\dots\) are a sequence \(A^n\) (as for globals or tables), then the elements of this sequence are passed to the allocation function pointwise.
Note
The definition of module allocation is mutually recursive with the allocation of its associated functions, because the resulting module instance \(\href{../exec/runtime.html#syntax-moduleinst}{\mathit{moduleinst}}\) is passed to the function allocator as an argument, in order to form the necessary closures. In an implementation, this recursion is easily unraveled by mutating one or the other in a secondary step.
Instantiation¶
Given a store \(S\), a module \(\href{../syntax/modules.html#syntax-module}{\mathit{module}}\) is instantiated with a list of external values \(\href{../exec/runtime.html#syntax-externval}{\mathit{externval}}^n\) supplying the required imports as follows.
Instantiation checks that the module is valid and the provided imports match the declared types, and may fail with an error otherwise. Instantiation can also result in a trap from initializing a table or memory from an active segment or from executing the start function. It is up to the embedder to define how such conditions are reported.
If \(\href{../syntax/modules.html#syntax-module}{\mathit{module}}\) is not valid, then:
Fail.
Assert: \(\href{../syntax/modules.html#syntax-module}{\mathit{module}}\) is valid with external types \(\href{../syntax/types.html#syntax-externtype}{\mathit{externtype}}_{\mathrm{im}}^m\) classifying its imports.
If the number \(m\) of imports is not equal to the number \(n\) of provided external values, then:
Fail.
For each external value \(\href{../exec/runtime.html#syntax-externval}{\mathit{externval}}_i\) in \(\href{../exec/runtime.html#syntax-externval}{\mathit{externval}}^n\) and external type \(\href{../syntax/types.html#syntax-externtype}{\mathit{externtype}}'_i\) in \(\href{../syntax/types.html#syntax-externtype}{\mathit{externtype}}_{\mathrm{im}}^n\), do:
If \(\href{../exec/runtime.html#syntax-externval}{\mathit{externval}}_i\) is not valid with an external type \(\href{../syntax/types.html#syntax-externtype}{\mathit{externtype}}_i\) in store \(S\), then:
Fail.
If \(\href{../syntax/types.html#syntax-externtype}{\mathit{externtype}}_i\) does not match \(\href{../syntax/types.html#syntax-externtype}{\mathit{externtype}}'_i\), then:
Fail.
Let \(\href{../exec/runtime.html#syntax-moduleinst}{\mathit{moduleinst}}_{\mathrm{init}}\) be the auxiliary module instance \(\{\href{../exec/runtime.html#syntax-moduleinst}{\mathsf{globaladdrs}}~\href{../exec/runtime.html#syntax-externval}{\mathrm{globals}}(\href{../exec/runtime.html#syntax-externval}{\mathit{externval}}^n), \href{../exec/runtime.html#syntax-moduleinst}{\mathsf{funcaddrs}}~\href{../exec/runtime.html#syntax-moduleinst}{\mathit{moduleinst}}.\href{../exec/runtime.html#syntax-moduleinst}{\mathsf{funcaddrs}}\}\) that only consists of the imported globals and the imported and allocated functions from the final module instance \(\href{../exec/runtime.html#syntax-moduleinst}{\mathit{moduleinst}}\), defined below.
Let \(F_{\mathrm{init}}\) be the auxiliary frame \(\{ \href{../exec/runtime.html#syntax-frame}{\mathsf{module}}~\href{../exec/runtime.html#syntax-moduleinst}{\mathit{moduleinst}}_{\mathrm{init}}, \href{../exec/runtime.html#syntax-frame}{\mathsf{locals}}~\epsilon \}\).
Push the frame \(F_{\mathrm{init}}\) to the stack.
Let \(\href{../exec/runtime.html#syntax-val}{\mathit{val}}^\ast\) be the vector of global initialization values determined by \(\href{../syntax/modules.html#syntax-module}{\mathit{module}}\) and \(\href{../exec/runtime.html#syntax-externval}{\mathit{externval}}^n\). These may be calculated as follows.
For each global \(\href{../syntax/modules.html#syntax-global}{\mathit{global}}_i\) in \(\href{../syntax/modules.html#syntax-module}{\mathit{module}}.\href{../syntax/modules.html#syntax-module}{\mathsf{globals}}\), do:
Let \(\href{../exec/runtime.html#syntax-val}{\mathit{val}}_i\) be the result of evaluating the initializer expression \(\href{../syntax/modules.html#syntax-global}{\mathit{global}}_i.\href{../syntax/modules.html#syntax-global}{\mathsf{init}}\).
Assert: due to validation, the frame \(F_{\mathrm{init}}\) is now on the top of the stack.
Let \(\href{../exec/runtime.html#syntax-val}{\mathit{val}}^\ast\) be the concatenation of \(\href{../exec/runtime.html#syntax-val}{\mathit{val}}_i\) in index order.
Let \((\href{../exec/runtime.html#syntax-ref}{\mathit{ref}}^\ast)^\ast\) be the list of reference vectors determined by the element segments in \(\href{../syntax/modules.html#syntax-module}{\mathit{module}}\). These may be calculated as follows.
For each element segment \(\href{../syntax/modules.html#syntax-elem}{\mathit{elem}}_i\) in \(\href{../syntax/modules.html#syntax-module}{\mathit{module}}.\href{../syntax/modules.html#syntax-module}{\mathsf{elems}}\), and for each element expression \(\href{../syntax/instructions.html#syntax-expr}{\mathit{expr}}_{ij}\) in \(\href{../syntax/modules.html#syntax-elem}{\mathit{elem}}_i.\href{../syntax/modules.html#syntax-elem}{\mathsf{init}}\), do:
Let \(\href{../exec/runtime.html#syntax-ref}{\mathit{ref}}_{ij}\) be the result of evaluating the initializer expression \(\href{../syntax/instructions.html#syntax-expr}{\mathit{expr}}_{ij}\).
Let \(\href{../exec/runtime.html#syntax-ref}{\mathit{ref}}^\ast_i\) be the concatenation of function elements \(\href{../exec/runtime.html#syntax-ref}{\mathit{ref}}_{ij}\) in order of index \(j\).
Let \((\href{../exec/runtime.html#syntax-ref}{\mathit{ref}}^\ast)^\ast\) be the concatenation of function element vectors \(\href{../exec/runtime.html#syntax-ref}{\mathit{ref}}^\ast_i\) in order of index \(i\).
Pop the frame \(F_{\mathrm{init}}\) from the stack.
Let \(\href{../exec/runtime.html#syntax-moduleinst}{\mathit{moduleinst}}\) be a new module instance allocated from \(\href{../syntax/modules.html#syntax-module}{\mathit{module}}\) in store \(S\) with imports \(\href{../exec/runtime.html#syntax-externval}{\mathit{externval}}^n\), global initializer values \(\href{../exec/runtime.html#syntax-val}{\mathit{val}}^\ast\), and element segment contents \((\href{../exec/runtime.html#syntax-ref}{\mathit{ref}}^\ast)^\ast\), and let \(S'\) be the extended store produced by module allocation.
Let \(F\) be the auxiliary frame \(\{ \href{../exec/runtime.html#syntax-frame}{\mathsf{module}}~\href{../exec/runtime.html#syntax-moduleinst}{\mathit{moduleinst}}, \href{../exec/runtime.html#syntax-frame}{\mathsf{locals}}~\epsilon \}\).
Push the frame \(F\) to the stack.
For each element segment \(\href{../syntax/modules.html#syntax-elem}{\mathit{elem}}_i\) in \(\href{../syntax/modules.html#syntax-module}{\mathit{module}}.\href{../syntax/modules.html#syntax-module}{\mathsf{elems}}\) whose mode is of the form \(\href{../syntax/modules.html#syntax-elemmode}{\mathsf{active}}~\{ \href{../syntax/modules.html#syntax-elem}{\mathsf{table}}~\href{../syntax/modules.html#syntax-tableidx}{\mathit{tableidx}}_i, \href{../syntax/modules.html#syntax-elem}{\mathsf{offset}}~\mathit{einstr}^\ast_i~\href{../syntax/instructions.html#syntax-instr-control}{\mathsf{end}} \}\), do:
Let \(n\) be the length of the vector \(\href{../syntax/modules.html#syntax-elem}{\mathit{elem}}_i.\href{../syntax/modules.html#syntax-elem}{\mathsf{init}}\).
Execute the instruction sequence \(\mathit{einstr}^\ast_i\).
Execute the instruction \(\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~0\).
Execute the instruction \(\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~n\).
Execute the instruction \(\href{../syntax/instructions.html#syntax-instr-table}{\mathsf{table.init}}~\href{../syntax/modules.html#syntax-tableidx}{\mathit{tableidx}}_i~i\).
Execute the instruction \(\href{../syntax/instructions.html#syntax-instr-table}{\mathsf{elem.drop}}~i\).
For each element segment \(\href{../syntax/modules.html#syntax-elem}{\mathit{elem}}_i\) in \(\href{../syntax/modules.html#syntax-module}{\mathit{module}}.\href{../syntax/modules.html#syntax-module}{\mathsf{elems}}\) whose mode is of the form \(\href{../syntax/modules.html#syntax-elemmode}{\mathsf{declarative}}\), do:
Execute the instruction \(\href{../syntax/instructions.html#syntax-instr-table}{\mathsf{elem.drop}}~i\).
For each data segment \(\href{../syntax/modules.html#syntax-data}{\mathit{data}}_i\) in \(\href{../syntax/modules.html#syntax-module}{\mathit{module}}.\href{../syntax/modules.html#syntax-module}{\mathsf{datas}}\) whose mode is of the form \(\href{../syntax/modules.html#syntax-datamode}{\mathsf{active}}~\{ \href{../syntax/modules.html#syntax-data}{\mathsf{memory}}~\href{../syntax/modules.html#syntax-memidx}{\mathit{memidx}}_i, \href{../syntax/modules.html#syntax-data}{\mathsf{offset}}~\mathit{dinstr}^\ast_i~\href{../syntax/instructions.html#syntax-instr-control}{\mathsf{end}} \}\), do:
Assert: \(\href{../syntax/modules.html#syntax-memidx}{\mathit{memidx}}_i\) is \(0\).
Let \(n\) be the length of the vector \(\href{../syntax/modules.html#syntax-data}{\mathit{data}}_i.\href{../syntax/modules.html#syntax-data}{\mathsf{init}}\).
Execute the instruction sequence \(\mathit{dinstr}^\ast_i\).
Execute the instruction \(\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~0\).
Execute the instruction \(\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~n\).
Execute the instruction \(\href{../syntax/instructions.html#syntax-instr-memory}{\mathsf{memory.init}}~i\).
Execute the instruction \(\href{../syntax/instructions.html#syntax-instr-memory}{\mathsf{data.drop}}~i\).
If the start function \(\href{../syntax/modules.html#syntax-module}{\mathit{module}}.\href{../syntax/modules.html#syntax-module}{\mathsf{start}}\) is not empty, then:
Let \(\href{../syntax/modules.html#syntax-start}{\mathit{start}}\) be the start function \(\href{../syntax/modules.html#syntax-module}{\mathit{module}}.\href{../syntax/modules.html#syntax-module}{\mathsf{start}}\).
Execute the instruction \(\href{../syntax/instructions.html#syntax-instr-control}{\mathsf{call}}~\href{../syntax/modules.html#syntax-start}{\mathit{start}}.\href{../syntax/modules.html#syntax-start}{\mathsf{func}}\).
Assert: due to validation, the frame \(F\) is now on the top of the stack.
Pop the frame \(F\) from the stack.
where:
Note
Module allocation and the evaluation of global initializers and element segments are mutually recursive because the global initialization values \(\href{../exec/runtime.html#syntax-val}{\mathit{val}}^\ast\) and element segment contents \((\href{../exec/runtime.html#syntax-ref}{\mathit{ref}}^\ast)^\ast\) are passed to the module allocator while depending on the module instance \(\href{../exec/runtime.html#syntax-moduleinst}{\mathit{moduleinst}}\) and store \(S'\) returned by allocation. However, this recursion is just a specification device. In practice, the initialization values can be determined beforehand by staging module allocation such that first, the module’s own function instances are pre-allocated in the store, then the initializer expressions are evaluated, then the rest of the module instance is allocated, and finally the new function instances’ \(\href{../exec/runtime.html#syntax-frame}{\mathsf{module}}\) fields are set to that module instance. This is possible because validation ensures that initialization expressions cannot actually call a function, only take their reference.
All failure conditions are checked before any observable mutation of the store takes place. Store mutation is not atomic; it happens in individual steps that may be interleaved with other threads.
Evaluation of constant expressions does not affect the store.
Invocation¶
Once a module has been instantiated, any exported function can be invoked externally via its function address \(\href{../exec/runtime.html#syntax-funcaddr}{\mathit{funcaddr}}\) in the store \(S\) and an appropriate list \(\href{../exec/runtime.html#syntax-val}{\mathit{val}}^\ast\) of argument values.
Invocation may fail with an error if the arguments do not fit the function type. Invocation can also result in a trap. It is up to the embedder to define how such conditions are reported.
Note
If the embedder API performs type checks itself, either statically or dynamically, before performing an invocation, then no failure other than traps can occur.
The following steps are performed:
Assert: \(S.\href{../exec/runtime.html#syntax-store}{\mathsf{funcs}}[\href{../exec/runtime.html#syntax-funcaddr}{\mathit{funcaddr}}]\) exists.
Let \(\href{../exec/runtime.html#syntax-funcinst}{\mathit{funcinst}}\) be the function instance \(S.\href{../exec/runtime.html#syntax-store}{\mathsf{funcs}}[\href{../exec/runtime.html#syntax-funcaddr}{\mathit{funcaddr}}]\).
Let \([t_1^n] \href{../syntax/types.html#syntax-functype}{\rightarrow} [t_2^m]\) be the function type \(\href{../exec/runtime.html#syntax-funcinst}{\mathit{funcinst}}.\href{../exec/runtime.html#syntax-funcinst}{\mathsf{type}}\).
If the length \(|\href{../exec/runtime.html#syntax-val}{\mathit{val}}^\ast|\) of the provided argument values is different from the number \(n\) of expected arguments, then:
Fail.
For each value type \(t_i\) in \(t_1^n\) and corresponding value \(val_i\) in \(\href{../exec/runtime.html#syntax-val}{\mathit{val}}^\ast\), do:
If \(\href{../exec/runtime.html#syntax-val}{\mathit{val}}_i\) is not valid with value type \(t_i\), then:
Fail.
Let \(F\) be the dummy frame \(\{ \href{../exec/runtime.html#syntax-frame}{\mathsf{module}}~\{\}, \href{../exec/runtime.html#syntax-frame}{\mathsf{locals}}~\epsilon \}\).
Push the frame \(F\) to the stack.
Push the values \(\href{../exec/runtime.html#syntax-val}{\mathit{val}}^\ast\) to the stack.
Invoke the function instance at address \(\href{../exec/runtime.html#syntax-funcaddr}{\mathit{funcaddr}}\).
Once the function has returned, the following steps are executed:
Assert: due to validation, \(m\) values are on the top of the stack.
Pop \(\href{../exec/runtime.html#syntax-val}{\mathit{val}}_{\mathrm{res}}^m\) from the stack.
The values \(\href{../exec/runtime.html#syntax-val}{\mathit{val}}_{\mathrm{res}}^m\) are returned as the results of the invocation.