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 be a function instance \(\{\href{../exec/runtime.html#syntax-funcinst}{\mathsf{type}}~\href{../syntax/types.html#syntax-functype}{\mathit{functype}}, \dots\}\).
Then \(\href{../exec/runtime.html#syntax-externval}{\mathsf{func}}~a\) is valid with external type \(\href{../syntax/types.html#syntax-externtype}{\mathsf{func}}~\href{../syntax/types.html#syntax-functype}{\mathit{functype}}\).
\(\href{../exec/runtime.html#syntax-externval}{\mathsf{table}}~a\)¶
The store entry \(S.\href{../exec/runtime.html#syntax-store}{\mathsf{tables}}[a]\) must be a table instance \(\{\href{../exec/runtime.html#syntax-tableinst}{\mathsf{elem}}~(\mathit{fa}^?)^n, \href{../exec/runtime.html#syntax-tableinst}{\mathsf{max}}~m^?\}\).
Then \(\href{../exec/runtime.html#syntax-externval}{\mathsf{table}}~a\) is valid with external type \(\href{../syntax/types.html#syntax-externtype}{\mathsf{table}}~(\{\href{../syntax/types.html#syntax-limits}{\mathsf{min}}~n, \href{../syntax/types.html#syntax-limits}{\mathsf{max}}~m^?\}~\href{../syntax/types.html#syntax-elemtype}{\mathsf{funcref}})\).
\(\href{../exec/runtime.html#syntax-externval}{\mathsf{mem}}~a\)¶
The store entry \(S.\href{../exec/runtime.html#syntax-store}{\mathsf{mems}}[a]\) must be a memory instance \(\{\href{../exec/runtime.html#syntax-meminst}{\mathsf{data}}~b^{n\cdot64\,\mathrm{Ki}}, \href{../exec/runtime.html#syntax-meminst}{\mathsf{max}}~m^?\}\), for some \(n\).
Then \(\href{../exec/runtime.html#syntax-externval}{\mathsf{mem}}~a\) is valid with external type \(\href{../syntax/types.html#syntax-externtype}{\mathsf{mem}}~(\{\href{../syntax/types.html#syntax-limits}{\mathsf{min}}~n, \href{../syntax/types.html#syntax-limits}{\mathsf{max}}~m^?\})\).
\(\href{../exec/runtime.html#syntax-externval}{\mathsf{global}}~a\)¶
The store entry \(S.\href{../exec/runtime.html#syntax-store}{\mathsf{globals}}[a]\) must be a global instance \(\{\href{../exec/runtime.html#syntax-globalinst}{\mathsf{value}}~(t.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~c), \href{../exec/runtime.html#syntax-globalinst}{\mathsf{mut}}~\href{../syntax/types.html#syntax-mut}{\mathit{mut}}\}\).
Then \(\href{../exec/runtime.html#syntax-externval}{\mathsf{global}}~a\) is valid with external type \(\href{../syntax/types.html#syntax-externtype}{\mathsf{global}}~(\href{../syntax/types.html#syntax-mut}{\mathit{mut}}~t)\).
Import Matching¶
When instantiating a module, external values must be provided whose types are matched against the respective external types classifying each import. In some cases, this allows for a simple form of subtyping, as defined below.
Limits¶
Limits \(\{ \href{../syntax/types.html#syntax-limits}{\mathsf{min}}~n_1, \href{../syntax/types.html#syntax-limits}{\mathsf{max}}~m_1^? \}\) match limits \(\{ \href{../syntax/types.html#syntax-limits}{\mathsf{min}}~n_2, \href{../syntax/types.html#syntax-limits}{\mathsf{max}}~m_2^? \}\) if and only if:
\(n_1\) is larger than or equal to \(n_2\).
Either:
\(m_2^?\) is empty.
Or:
Both \(m_1^?\) and \(m_2^?\) are non-empty.
\(m_1\) is smaller than or equal to \(m_2\).
Functions¶
An external type \(\href{../syntax/types.html#syntax-externtype}{\mathsf{func}}~\href{../syntax/types.html#syntax-functype}{\mathit{functype}}_1\) matches \(\href{../syntax/types.html#syntax-externtype}{\mathsf{func}}~\href{../syntax/types.html#syntax-functype}{\mathit{functype}}_2\) if and only if:
Both \(\href{../syntax/types.html#syntax-functype}{\mathit{functype}}_1\) and \(\href{../syntax/types.html#syntax-functype}{\mathit{functype}}_2\) are the same.
Tables¶
An external type \(\href{../syntax/types.html#syntax-externtype}{\mathsf{table}}~(\href{../syntax/types.html#syntax-limits}{\mathit{limits}}_1~\href{../syntax/types.html#syntax-elemtype}{\mathit{elemtype}}_1)\) matches \(\href{../syntax/types.html#syntax-externtype}{\mathsf{table}}~(\href{../syntax/types.html#syntax-limits}{\mathit{limits}}_2~\href{../syntax/types.html#syntax-elemtype}{\mathit{elemtype}}_2)\) if and only if:
Limits \(\href{../syntax/types.html#syntax-limits}{\mathit{limits}}_1\) match \(\href{../syntax/types.html#syntax-limits}{\mathit{limits}}_2\).
Both \(\href{../syntax/types.html#syntax-elemtype}{\mathit{elemtype}}_1\) and \(\href{../syntax/types.html#syntax-elemtype}{\mathit{elemtype}}_2\) are the same.
Memories¶
An external type \(\href{../syntax/types.html#syntax-externtype}{\mathsf{mem}}~\href{../syntax/types.html#syntax-limits}{\mathit{limits}}_1\) matches \(\href{../syntax/types.html#syntax-externtype}{\mathsf{mem}}~\href{../syntax/types.html#syntax-limits}{\mathit{limits}}_2\) if and only if:
Limits \(\href{../syntax/types.html#syntax-limits}{\mathit{limits}}_1\) match \(\href{../syntax/types.html#syntax-limits}{\mathit{limits}}_2\).
Globals¶
An external type \(\href{../syntax/types.html#syntax-externtype}{\mathsf{global}}~\href{../syntax/types.html#syntax-globaltype}{\mathit{globaltype}}_1\) matches \(\href{../syntax/types.html#syntax-externtype}{\mathsf{global}}~\href{../syntax/types.html#syntax-globaltype}{\mathit{globaltype}}_2\) if and only if:
Both \(\href{../syntax/types.html#syntax-globaltype}{\mathit{globaltype}}_1\) and \(\href{../syntax/types.html#syntax-globaltype}{\mathit{globaltype}}_2\) are the same.
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.
Let \((\{\href{../syntax/types.html#syntax-limits}{\mathsf{min}}~n, \href{../syntax/types.html#syntax-limits}{\mathsf{max}}~m^?\}~\href{../syntax/types.html#syntax-elemtype}{\mathit{elemtype}})\) 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{elem}}~(\epsilon)^n, \href{../exec/runtime.html#syntax-tableinst}{\mathsf{max}}~m^? \}\) with \(n\) empty elements.
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{data}}~(\def\mathdef1177#1{\mathtt{0x#1}}\mathdef1177{00})^{n \cdot 64\,\mathrm{Ki}}, \href{../exec/runtime.html#syntax-meminst}{\mathsf{max}}~m^? \}\) 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 \(\href{../syntax/types.html#syntax-mut}{\mathit{mut}}~t\) be the structure of global type \(\href{../syntax/types.html#syntax-globaltype}{\mathit{globaltype}}\).
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{value}}~\href{../exec/runtime.html#syntax-val}{\mathit{val}}, \href{../exec/runtime.html#syntax-globalinst}{\mathsf{mut}}~\href{../syntax/types.html#syntax-mut}{\mathit{mut}} \}\).
Append \(\href{../exec/runtime.html#syntax-globalinst}{\mathit{globalinst}}\) to the \(\href{../exec/runtime.html#syntax-store}{\mathsf{globals}}\) of \(S\).
Return \(a\).
Growing tables¶
Let \(\href{../exec/runtime.html#syntax-tableinst}{\mathit{tableinst}}\) be the table instance to grow and \(n\) the number of elements by which to grow it.
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.
If \(\href{../exec/runtime.html#syntax-tableinst}{\mathit{tableinst}}.\href{../exec/runtime.html#syntax-tableinst}{\mathsf{max}}\) is not empty and its value is smaller than \(\mathit{len}\), then fail.
Append \(n\) empty elements to \(\href{../exec/runtime.html#syntax-tableinst}{\mathit{tableinst}}.\href{../exec/runtime.html#syntax-tableinst}{\mathsf{elem}}\).
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.
If \(\href{../exec/runtime.html#syntax-meminst}{\mathit{meminst}}.\href{../exec/runtime.html#syntax-meminst}{\mathsf{max}}\) is not empty and its value is smaller than \(\mathit{len}\), then fail.
Append \(n\) times \(64\,\mathrm{Ki}\) bytes with value \(\def\mathdef1179#1{\mathtt{0x#1}}\mathdef1179{00}\) to \(\href{../exec/runtime.html#syntax-meminst}{\mathit{meminst}}.\href{../exec/runtime.html#syntax-meminst}{\mathsf{data}}\).
Modules¶
The allocation function for modules requires a suitable list of external values that are assumed to match the import vector of the module, and a list of initialization values for the module’s globals.
1. 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, and \(\href{../exec/runtime.html#syntax-val}{\mathit{val}}^\ast\) the initialization values of the module’s globals.
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{../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}}\).
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]\).
Let \(\href{../exec/runtime.html#syntax-funcaddr}{\mathit{funcaddr}}^\ast\) be the 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 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 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 the concatenation of the global addresses \(\href{../exec/runtime.html#syntax-globaladdr}{\mathit{globaladdr}}_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 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), 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 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-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.
Let \(\href{../exec/runtime.html#syntax-moduleinst}{\mathit{moduleinst}}_{\mathrm{im}}\) 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)\}\) that only consists of the imported globals.
Let \(F_{\mathrm{im}}\) be the auxiliary frame \(\{ \href{../exec/runtime.html#syntax-frame}{\mathsf{module}}~\href{../exec/runtime.html#syntax-moduleinst}{\mathit{moduleinst}}_{\mathrm{im}}, \href{../exec/runtime.html#syntax-frame}{\mathsf{locals}}~\epsilon \}\).
Push the frame \(F_{\mathrm{im}}\) to the stack.
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{im}}\) is now on the top of the stack.
Pop the frame \(F_{\mathrm{im}}\) 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\) and global initializer values \(\href{../exec/runtime.html#syntax-val}{\mathit{val}}^\ast\), and let \(S'\) be the extended store produced by module allocation.
Let \(F\) be the 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{elem}}\), do:
Let \(\mathit{eoval}_i\) be the result of evaluating the expression \(\href{../syntax/modules.html#syntax-elem}{\mathit{elem}}_i.\href{../syntax/modules.html#syntax-elem}{\mathsf{offset}}\).
Assert: due to validation, \(\mathit{eoval}_i\) is of the form \(\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~\mathit{eo}_i\).
Let \(\href{../syntax/modules.html#syntax-tableidx}{\mathit{tableidx}}_i\) be the table index \(\href{../syntax/modules.html#syntax-elem}{\mathit{elem}}_i.\href{../syntax/modules.html#syntax-elem}{\mathsf{table}}\).
Assert: due to validation, \(\href{../exec/runtime.html#syntax-moduleinst}{\mathit{moduleinst}}.\href{../exec/runtime.html#syntax-moduleinst}{\mathsf{tableaddrs}}[\href{../syntax/modules.html#syntax-tableidx}{\mathit{tableidx}}_i]\) exists.
Let \(\href{../exec/runtime.html#syntax-tableaddr}{\mathit{tableaddr}}_i\) be the table address \(\href{../exec/runtime.html#syntax-moduleinst}{\mathit{moduleinst}}.\href{../exec/runtime.html#syntax-moduleinst}{\mathsf{tableaddrs}}[\href{../syntax/modules.html#syntax-tableidx}{\mathit{tableidx}}_i]\).
Assert: due to validation, \(S'.\href{../exec/runtime.html#syntax-store}{\mathsf{tables}}[\href{../exec/runtime.html#syntax-tableaddr}{\mathit{tableaddr}}_i]\) exists.
Let \(\href{../exec/runtime.html#syntax-tableinst}{\mathit{tableinst}}_i\) be the table instance \(S'.\href{../exec/runtime.html#syntax-store}{\mathsf{tables}}[\href{../exec/runtime.html#syntax-tableaddr}{\mathit{tableaddr}}_i]\).
Let \(\mathit{eend}_i\) be \(\mathit{eo}_i\) plus the length of \(\href{../syntax/modules.html#syntax-elem}{\mathit{elem}}_i.\href{../syntax/modules.html#syntax-elem}{\mathsf{init}}\).
If \(\mathit{eend}_i\) is larger than the length of \(\href{../exec/runtime.html#syntax-tableinst}{\mathit{tableinst}}_i.\href{../exec/runtime.html#syntax-tableinst}{\mathsf{elem}}\), then:
Fail.
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{data}}\), do:
Let \(\mathit{doval}_i\) be the result of evaluating the expression \(\href{../syntax/modules.html#syntax-data}{\mathit{data}}_i.\href{../syntax/modules.html#syntax-data}{\mathsf{offset}}\).
Assert: due to validation, \(\mathit{doval}_i\) is of the form \(\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~\mathit{do}_i\).
Let \(\href{../syntax/modules.html#syntax-memidx}{\mathit{memidx}}_i\) be the memory index \(\href{../syntax/modules.html#syntax-data}{\mathit{data}}_i.\href{../syntax/modules.html#syntax-data}{\mathsf{data}}\).
Assert: due to validation, \(\href{../exec/runtime.html#syntax-moduleinst}{\mathit{moduleinst}}.\href{../exec/runtime.html#syntax-moduleinst}{\mathsf{memaddrs}}[\href{../syntax/modules.html#syntax-memidx}{\mathit{memidx}}_i]\) exists.
Let \(\href{../exec/runtime.html#syntax-memaddr}{\mathit{memaddr}}_i\) be the memory address \(\href{../exec/runtime.html#syntax-moduleinst}{\mathit{moduleinst}}.\href{../exec/runtime.html#syntax-moduleinst}{\mathsf{memaddrs}}[\href{../syntax/modules.html#syntax-memidx}{\mathit{memidx}}_i]\).
Assert: due to validation, \(S'.\href{../exec/runtime.html#syntax-store}{\mathsf{mems}}[\href{../exec/runtime.html#syntax-memaddr}{\mathit{memaddr}}_i]\) exists.
Let \(\href{../exec/runtime.html#syntax-meminst}{\mathit{meminst}}_i\) be the memory instance \(S'.\href{../exec/runtime.html#syntax-store}{\mathsf{mems}}[\href{../exec/runtime.html#syntax-memaddr}{\mathit{memaddr}}_i]\).
Let \(\mathit{dend}_i\) be \(\mathit{do}_i\) plus the length of \(\href{../syntax/modules.html#syntax-data}{\mathit{data}}_i.\href{../syntax/modules.html#syntax-data}{\mathsf{init}}\).
If \(\mathit{dend}_i\) is larger than the length of \(\href{../exec/runtime.html#syntax-meminst}{\mathit{meminst}}_i.\href{../exec/runtime.html#syntax-meminst}{\mathsf{data}}\), then:
Fail.
Assert: due to validation, the frame \(F\) is now on the top of the stack.
Pop the frame from 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{elem}}\), do:
For each function index \(\href{../syntax/modules.html#syntax-funcidx}{\mathit{funcidx}}_{ij}\) in \(\href{../syntax/modules.html#syntax-elem}{\mathit{elem}}_i.\href{../syntax/modules.html#syntax-elem}{\mathsf{init}}\) (starting with \(j = 0\)), do:
Assert: due to validation, \(\href{../exec/runtime.html#syntax-moduleinst}{\mathit{moduleinst}}.\href{../exec/runtime.html#syntax-moduleinst}{\mathsf{funcaddrs}}[\href{../syntax/modules.html#syntax-funcidx}{\mathit{funcidx}}_{ij}]\) exists.
Let \(\href{../exec/runtime.html#syntax-funcaddr}{\mathit{funcaddr}}_{ij}\) be the function address \(\href{../exec/runtime.html#syntax-moduleinst}{\mathit{moduleinst}}.\href{../exec/runtime.html#syntax-moduleinst}{\mathsf{funcaddrs}}[\href{../syntax/modules.html#syntax-funcidx}{\mathit{funcidx}}_{ij}]\).
Replace \(\href{../exec/runtime.html#syntax-tableinst}{\mathit{tableinst}}_i.\href{../exec/runtime.html#syntax-tableinst}{\mathsf{elem}}[\mathit{eo}_i + j]\) with \(\href{../exec/runtime.html#syntax-funcaddr}{\mathit{funcaddr}}_{ij}\).
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{data}}\), do:
For each byte \(b_{ij}\) in \(\href{../syntax/modules.html#syntax-data}{\mathit{data}}_i.\href{../syntax/modules.html#syntax-data}{\mathsf{init}}\) (starting with \(j = 0\)), do:
Replace \(\href{../exec/runtime.html#syntax-meminst}{\mathit{meminst}}_i.\href{../exec/runtime.html#syntax-meminst}{\mathsf{data}}[\mathit{do}_i + j]\) with \(b_{ij}\).
If the start function \(\href{../syntax/modules.html#syntax-module}{\mathit{module}}.\href{../syntax/modules.html#syntax-module}{\mathsf{start}}\) is not empty, then:
Assert: due to validation, \(\href{../exec/runtime.html#syntax-moduleinst}{\mathit{moduleinst}}.\href{../exec/runtime.html#syntax-moduleinst}{\mathsf{funcaddrs}}[\href{../syntax/modules.html#syntax-module}{\mathit{module}}.\href{../syntax/modules.html#syntax-module}{\mathsf{start}}.\href{../syntax/modules.html#syntax-start}{\mathsf{func}}]\) exists.
Let \(\href{../exec/runtime.html#syntax-funcaddr}{\mathit{funcaddr}}\) be the function address \(\href{../exec/runtime.html#syntax-moduleinst}{\mathit{moduleinst}}.\href{../exec/runtime.html#syntax-moduleinst}{\mathsf{funcaddrs}}[\href{../syntax/modules.html#syntax-module}{\mathit{module}}.\href{../syntax/modules.html#syntax-module}{\mathsf{start}}.\href{../syntax/modules.html#syntax-start}{\mathsf{func}}]\).
Invoke the function instance at \(\href{../exec/runtime.html#syntax-funcaddr}{\mathit{funcaddr}}\).
Note
Module allocation and the evaluation of global initializers are mutually recursive because the global initialization values \(\href{../exec/runtime.html#syntax-val}{\mathit{val}}^\ast\) are passed to the module allocator but depend on the store \(S'\) and module instance \(\href{../exec/runtime.html#syntax-moduleinst}{\mathit{moduleinst}}\) returned by allocation. However, this recursion is just a specification device. Due to validation, the initialization values can easily be determined from a simple pre-pass that evaluates global initializers in the initial store.
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 \(t_i.\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~c_i\) for some \(c_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.