Modules¶
Modules are valid when all the components they contain are valid. Furthermore, most definitions are themselves classified with a suitable type.
Functions¶
Functions \(\href{../syntax/modules.html#syntax-func}{\mathit{func}}\) are classified by function types of the form \([t_1^\ast] \href{../syntax/types.html#syntax-functype}{\rightarrow} [t_2^\ast]\).
\(\{ \href{../syntax/modules.html#syntax-func}{\mathsf{type}}~x, \href{../syntax/modules.html#syntax-func}{\mathsf{locals}}~t^\ast, \href{../syntax/modules.html#syntax-func}{\mathsf{body}}~\href{../syntax/instructions.html#syntax-expr}{\mathit{expr}} \}\)¶
The type \(C.\href{../valid/conventions.html#context}{\mathsf{types}}[x]\) must be defined in the context.
Let \([t_1^\ast] \href{../syntax/types.html#syntax-functype}{\rightarrow} [t_2^\ast]\) be the function type \(C.\href{../valid/conventions.html#context}{\mathsf{types}}[x]\).
Let \(C'\) be the same context as \(C\), but with:
\(\href{../valid/conventions.html#context}{\mathsf{locals}}\) set to the sequence of value types \(t_1^\ast~t^\ast\), concatenating parameters and locals,
\(\href{../valid/conventions.html#context}{\mathsf{labels}}\) set to the singular sequence containing only result type \([t_2^\ast]\).
\(\href{../valid/conventions.html#context}{\mathsf{return}}\) set to the result type \([t_2^\ast]\).
Under the context \(C'\), the expression \(\href{../syntax/instructions.html#syntax-expr}{\mathit{expr}}\) must be valid with type \([t_2^\ast]\).
Then the function definition is valid with type \([t_1^\ast] \href{../syntax/types.html#syntax-functype}{\rightarrow} [t_2^\ast]\).
Tables¶
Tables \(\href{../syntax/modules.html#syntax-table}{\mathit{table}}\) are classified by table types.
\(\{ \href{../syntax/modules.html#syntax-table}{\mathsf{type}}~\href{../syntax/types.html#syntax-tabletype}{\mathit{tabletype}} \}\)¶
The table type \(\href{../syntax/types.html#syntax-tabletype}{\mathit{tabletype}}\) must be valid.
Then the table definition is valid with type \(\href{../syntax/types.html#syntax-tabletype}{\mathit{tabletype}}\).
Memories¶
Memories \(\href{../syntax/modules.html#syntax-mem}{\mathit{mem}}\) are classified by memory types.
\(\{ \href{../syntax/modules.html#syntax-mem}{\mathsf{type}}~\href{../syntax/types.html#syntax-memtype}{\mathit{memtype}} \}\)¶
The memory type \(\href{../syntax/types.html#syntax-memtype}{\mathit{memtype}}\) must be valid.
Then the memory definition is valid with type \(\href{../syntax/types.html#syntax-memtype}{\mathit{memtype}}\).
Globals¶
Globals \(\href{../syntax/modules.html#syntax-global}{\mathit{global}}\) are classified by global types of the form \(\href{../syntax/types.html#syntax-mut}{\mathit{mut}}~t\).
\(\{ \href{../syntax/modules.html#syntax-global}{\mathsf{type}}~\href{../syntax/types.html#syntax-mut}{\mathit{mut}}~t, \href{../syntax/modules.html#syntax-global}{\mathsf{init}}~\href{../syntax/instructions.html#syntax-expr}{\mathit{expr}} \}\)¶
The global type \(\href{../syntax/types.html#syntax-mut}{\mathit{mut}}~t\) must be valid.
The expression \(\href{../syntax/instructions.html#syntax-expr}{\mathit{expr}}\) must be valid with result type \([t]\).
The expression \(\href{../syntax/instructions.html#syntax-expr}{\mathit{expr}}\) must be constant.
Then the global definition is valid with type \(\href{../syntax/types.html#syntax-mut}{\mathit{mut}}~t\).
Element Segments¶
Element segments \(\href{../syntax/modules.html#syntax-elem}{\mathit{elem}}\) are not classified by any type but merely checked for well-formedness.
\(\{ \href{../syntax/modules.html#syntax-elem}{\mathsf{type}}~et, \href{../syntax/modules.html#syntax-elem}{\mathsf{init}}~e^\ast, \href{../syntax/modules.html#syntax-elem}{\mathsf{mode}}~\href{../syntax/modules.html#syntax-elemmode}{\mathit{elemmode}} \}\)¶
For each \(e_i\) in \(e^\ast\),
The element expression \(e_i\) must be valid.
The element mode \(\href{../syntax/modules.html#syntax-elemmode}{\mathit{elemmode}}\) must be valid.
Then the element segment is valid.
\(\href{../syntax/modules.html#syntax-elemexpr}{\mathit{elemexpr}}\)¶
An element expression must be:
either of the form \(\href{../syntax/modules.html#syntax-elemexpr}{\mathsf{ref.null}}~\href{../syntax/instructions.html#syntax-instr-control}{\mathsf{end}}\),
or of the form \((\href{../syntax/modules.html#syntax-elemexpr}{\mathsf{ref.func}}~x)~\href{../syntax/instructions.html#syntax-instr-control}{\mathsf{end}}\), in which case \(C.\href{../valid/conventions.html#context}{\mathsf{funcs}}[x]\) must be defined in the context.
\(\href{../syntax/modules.html#syntax-elem}{\mathsf{passive}}\)¶
The element mode is valid.
\(\href{../syntax/modules.html#syntax-elem}{\mathsf{active}}~\{ \href{../syntax/modules.html#syntax-elem}{\mathsf{table}}~x, \href{../syntax/modules.html#syntax-elem}{\mathsf{offset}}~\href{../syntax/instructions.html#syntax-expr}{\mathit{expr}} \}\)¶
The table \(C.\href{../valid/conventions.html#context}{\mathsf{tables}}[x]\) must be defined in the context.
Let \(\href{../syntax/types.html#syntax-limits}{\mathit{limits}}~\href{../syntax/types.html#syntax-elemtype}{\mathit{elemtype}}\) be the table type \(C.\href{../valid/conventions.html#context}{\mathsf{tables}}[x]\).
The element type \(\mathit{et}\) of the segment must match \(\href{../syntax/types.html#syntax-elemtype}{\mathit{elemtype}}\).
The expression \(\href{../syntax/instructions.html#syntax-expr}{\mathit{expr}}\) must be valid with result type \([\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}]\).
The expression \(\href{../syntax/instructions.html#syntax-expr}{\mathit{expr}}\) must be constant.
Then the element mode is valid.
Data Segments¶
Data segments \(\href{../syntax/modules.html#syntax-data}{\mathit{data}}\) are not classified by any type but merely checked for well-formedness.
\(\{ \href{../syntax/modules.html#syntax-data}{\mathsf{init}}~b^\ast, \href{../syntax/modules.html#syntax-data}{\mathsf{mode}}~\href{../syntax/modules.html#syntax-datamode}{\mathit{datamode}} \}\)¶
The data mode \(\href{../syntax/modules.html#syntax-datamode}{\mathit{datamode}}\) must be valid.
Then the data segment is valid.
\(\href{../syntax/modules.html#syntax-data}{\mathsf{passive}}\)¶
The data mode is valid.
\(\href{../syntax/modules.html#syntax-data}{\mathsf{active}}~\{ \href{../syntax/modules.html#syntax-data}{\mathsf{memory}}~x, \href{../syntax/modules.html#syntax-data}{\mathsf{offset}}~\href{../syntax/instructions.html#syntax-expr}{\mathit{expr}} \}\)¶
The memory \(C.\href{../valid/conventions.html#context}{\mathsf{mems}}[x]\) must be defined in the context.
The expression \(\href{../syntax/instructions.html#syntax-expr}{\mathit{expr}}\) must be valid with result type \([\href{../syntax/types.html#syntax-valtype}{\mathsf{i32}}]\).
The expression \(\href{../syntax/instructions.html#syntax-expr}{\mathit{expr}}\) must be constant.
Then the data mode is valid.
Start Function¶
Start function declarations \(\href{../syntax/modules.html#syntax-start}{\mathit{start}}\) are not classified by any type.
\(\{ \href{../syntax/modules.html#syntax-start}{\mathsf{func}}~x \}\)¶
The function \(C.\href{../valid/conventions.html#context}{\mathsf{funcs}}[x]\) must be defined in the context.
The type of \(C.\href{../valid/conventions.html#context}{\mathsf{funcs}}[x]\) must be \([] \href{../syntax/types.html#syntax-functype}{\rightarrow} []\).
Then the start function is valid.
Exports¶
Exports \(\href{../syntax/modules.html#syntax-export}{\mathit{export}}\) and export descriptions \(\href{../syntax/modules.html#syntax-exportdesc}{\mathit{exportdesc}}\) are classified by their external type.
\(\{ \href{../syntax/modules.html#syntax-export}{\mathsf{name}}~\href{../syntax/values.html#syntax-name}{\mathit{name}}, \href{../syntax/modules.html#syntax-export}{\mathsf{desc}}~\href{../syntax/modules.html#syntax-exportdesc}{\mathit{exportdesc}} \}\)¶
The export description \(\href{../syntax/modules.html#syntax-exportdesc}{\mathit{exportdesc}}\) must be valid with external type \(\href{../syntax/types.html#syntax-externtype}{\mathit{externtype}}\).
Then the export is valid with external type \(\href{../syntax/types.html#syntax-externtype}{\mathit{externtype}}\).
\(\href{../syntax/modules.html#syntax-exportdesc}{\mathsf{func}}~x\)¶
The function \(C.\href{../valid/conventions.html#context}{\mathsf{funcs}}[x]\) must be defined in the context.
Then the export description is valid with external type \(\href{../syntax/types.html#syntax-externtype}{\mathsf{func}}~C.\href{../valid/conventions.html#context}{\mathsf{funcs}}[x]\).
\(\href{../syntax/modules.html#syntax-exportdesc}{\mathsf{table}}~x\)¶
The table \(C.\href{../valid/conventions.html#context}{\mathsf{tables}}[x]\) must be defined in the context.
Then the export description is valid with external type \(\href{../syntax/types.html#syntax-externtype}{\mathsf{table}}~C.\href{../valid/conventions.html#context}{\mathsf{tables}}[x]\).
\(\href{../syntax/modules.html#syntax-exportdesc}{\mathsf{mem}}~x\)¶
The memory \(C.\href{../valid/conventions.html#context}{\mathsf{mems}}[x]\) must be defined in the context.
Then the export description is valid with external type \(\href{../syntax/types.html#syntax-externtype}{\mathsf{mem}}~C.\href{../valid/conventions.html#context}{\mathsf{mems}}[x]\).
\(\href{../syntax/modules.html#syntax-exportdesc}{\mathsf{global}}~x\)¶
The global \(C.\href{../valid/conventions.html#context}{\mathsf{globals}}[x]\) must be defined in the context.
Then the export description is valid with external type \(\href{../syntax/types.html#syntax-externtype}{\mathsf{global}}~C.\href{../valid/conventions.html#context}{\mathsf{globals}}[x]\).
Imports¶
Imports \(\href{../syntax/modules.html#syntax-import}{\mathit{import}}\) and import descriptions \(\href{../syntax/modules.html#syntax-importdesc}{\mathit{importdesc}}\) are classified by external types.
\(\{ \href{../syntax/modules.html#syntax-import}{\mathsf{module}}~\href{../syntax/values.html#syntax-name}{\mathit{name}}_1, \href{../syntax/modules.html#syntax-import}{\mathsf{name}}~\href{../syntax/values.html#syntax-name}{\mathit{name}}_2, \href{../syntax/modules.html#syntax-import}{\mathsf{desc}}~\href{../syntax/modules.html#syntax-importdesc}{\mathit{importdesc}} \}\)¶
The import description \(\href{../syntax/modules.html#syntax-importdesc}{\mathit{importdesc}}\) must be valid with type \(\href{../syntax/types.html#syntax-externtype}{\mathit{externtype}}\).
Then the import is valid with type \(\href{../syntax/types.html#syntax-externtype}{\mathit{externtype}}\).
\(\href{../syntax/modules.html#syntax-importdesc}{\mathsf{func}}~x\)¶
The function \(C.\href{../valid/conventions.html#context}{\mathsf{types}}[x]\) must be defined in the context.
Let \([t_1^\ast] \href{../syntax/types.html#syntax-functype}{\rightarrow} [t_2^\ast]\) be the function type \(C.\href{../valid/conventions.html#context}{\mathsf{types}}[x]\).
Then the import description is valid with type \(\href{../syntax/types.html#syntax-externtype}{\mathsf{func}}~[t_1^\ast] \href{../syntax/types.html#syntax-functype}{\rightarrow} [t_2^\ast]\).
\(\href{../syntax/modules.html#syntax-importdesc}{\mathsf{table}}~\href{../syntax/types.html#syntax-tabletype}{\mathit{tabletype}}\)¶
The table type \(\href{../syntax/types.html#syntax-tabletype}{\mathit{tabletype}}\) must be valid.
Then the import description is valid with type \(\href{../syntax/types.html#syntax-externtype}{\mathsf{table}}~\href{../syntax/types.html#syntax-tabletype}{\mathit{tabletype}}\).
\(\href{../syntax/modules.html#syntax-importdesc}{\mathsf{mem}}~\href{../syntax/types.html#syntax-memtype}{\mathit{memtype}}\)¶
The memory type \(\href{../syntax/types.html#syntax-memtype}{\mathit{memtype}}\) must be valid.
Then the import description is valid with type \(\href{../syntax/types.html#syntax-externtype}{\mathsf{mem}}~\href{../syntax/types.html#syntax-memtype}{\mathit{memtype}}\).
\(\href{../syntax/modules.html#syntax-importdesc}{\mathsf{global}}~\href{../syntax/types.html#syntax-globaltype}{\mathit{globaltype}}\)¶
The global type \(\href{../syntax/types.html#syntax-globaltype}{\mathit{globaltype}}\) must be valid.
Then the import description is valid with type \(\href{../syntax/types.html#syntax-externtype}{\mathsf{global}}~\href{../syntax/types.html#syntax-globaltype}{\mathit{globaltype}}\).
Modules¶
Modules are classified by their mapping from the external types of their imports to those of their exports.
A module is entirely closed, that is, its components can only refer to definitions that appear in the module itself. Consequently, no initial context is required. Instead, the context \(C\) for validation of the module’s content is constructed from the definitions in the module.
Let \(\href{../syntax/modules.html#syntax-module}{\mathit{module}}\) be the module to validate.
Let \(C\) be a context where:
\(C.\href{../valid/conventions.html#context}{\mathsf{types}}\) is \(\href{../syntax/modules.html#syntax-module}{\mathit{module}}.\href{../syntax/modules.html#syntax-module}{\mathsf{types}}\),
\(C.\href{../valid/conventions.html#context}{\mathsf{funcs}}\) is \(\href{../syntax/types.html#syntax-externtype}{\mathrm{funcs}}(\mathit{it}^\ast)\) concatenated with \(\mathit{ft}^\ast\), with the import’s external types \(\mathit{it}^\ast\) and the internal function types \(\mathit{ft}^\ast\) as determined below,
\(C.\href{../valid/conventions.html#context}{\mathsf{tables}}\) is \(\href{../syntax/types.html#syntax-externtype}{\mathrm{tables}}(\mathit{it}^\ast)\) concatenated with \(\mathit{tt}^\ast\), with the import’s external types \(\mathit{it}^\ast\) and the internal table types \(\mathit{tt}^\ast\) as determined below,
\(C.\href{../valid/conventions.html#context}{\mathsf{mems}}\) is \(\href{../syntax/types.html#syntax-externtype}{\mathrm{mems}}(\mathit{it}^\ast)\) concatenated with \(\mathit{mt}^\ast\), with the import’s external types \(\mathit{it}^\ast\) and the internal memory types \(\mathit{mt}^\ast\) as determined below,
\(C.\href{../valid/conventions.html#context}{\mathsf{globals}}\) is \(\href{../syntax/types.html#syntax-externtype}{\mathrm{globals}}(\mathit{it}^\ast)\) concatenated with \(\mathit{gt}^\ast\), with the import’s external types \(\mathit{it}^\ast\) and the internal global types \(\mathit{gt}^\ast\) as determined below,
\(C.\href{../valid/conventions.html#context}{\mathsf{elems}}\) is \({\mathrel{\mbox{ok}}}^{N_e}\), where \(N_e\) is the length of the vector \(\href{../syntax/modules.html#syntax-module}{\mathit{module}}.\href{../syntax/modules.html#syntax-module}{\mathsf{elems}}\),
\(C.\href{../valid/conventions.html#context}{\mathsf{datas}}\) is \({\mathrel{\mbox{ok}}}^{N_d}\), where \(N_d\) is the length of the vector \(\href{../syntax/modules.html#syntax-module}{\mathit{module}}.\href{../syntax/modules.html#syntax-module}{\mathsf{datas}}\),
\(C.\href{../valid/conventions.html#context}{\mathsf{locals}}\) is empty,
\(C.\href{../valid/conventions.html#context}{\mathsf{labels}}\) is empty,
\(C.\href{../valid/conventions.html#context}{\mathsf{return}}\) is empty.
Let \(C'\) be the context where \(C'.\href{../valid/conventions.html#context}{\mathsf{globals}}\) is the sequence \(\href{../syntax/types.html#syntax-externtype}{\mathrm{globals}}(\mathit{it}^\ast)\) and all other fields are empty.
Under the context \(C\):
For each \(\href{../syntax/types.html#syntax-functype}{\mathit{functype}}_i\) in \(\href{../syntax/modules.html#syntax-module}{\mathit{module}}.\href{../syntax/modules.html#syntax-module}{\mathsf{types}}\), the function type \(\href{../syntax/types.html#syntax-functype}{\mathit{functype}}_i\) must be valid.
For each \(\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}}\), the definition \(\href{../syntax/modules.html#syntax-func}{\mathit{func}}_i\) must be valid with a function type \(\mathit{ft}_i\).
For each \(\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}}\), the definition \(\href{../syntax/modules.html#syntax-table}{\mathit{table}}_i\) must be valid with a table type \(\mathit{tt}_i\).
For each \(\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}}\), the definition \(\href{../syntax/modules.html#syntax-mem}{\mathit{mem}}_i\) must be valid with a memory type \(\mathit{mt}_i\).
For each \(\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}}\):
Under the context \(C'\), the definition \(\href{../syntax/modules.html#syntax-global}{\mathit{global}}_i\) must be valid with a global type \(\mathit{gt}_i\).
For each \(\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}}\), the segment \(\href{../syntax/modules.html#syntax-elem}{\mathit{elem}}_i\) must be valid.
For each \(\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}}\), the segment \(\href{../syntax/modules.html#syntax-data}{\mathit{data}}_i\) must be valid.
If \(\href{../syntax/modules.html#syntax-module}{\mathit{module}}.\href{../syntax/modules.html#syntax-module}{\mathsf{start}}\) is non-empty, then \(\href{../syntax/modules.html#syntax-module}{\mathit{module}}.\href{../syntax/modules.html#syntax-module}{\mathsf{start}}\) must be valid.
For each \(\href{../syntax/modules.html#syntax-import}{\mathit{import}}_i\) in \(\href{../syntax/modules.html#syntax-module}{\mathit{module}}.\href{../syntax/modules.html#syntax-module}{\mathsf{imports}}\), the segment \(\href{../syntax/modules.html#syntax-import}{\mathit{import}}_i\) must be valid with an external type \(\mathit{it}_i\).
For each \(\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}}\), the segment \(\href{../syntax/modules.html#syntax-export}{\mathit{export}}_i\) must be valid with external type \(\mathit{et}_i\).
The length of \(C.\href{../valid/conventions.html#context}{\mathsf{tables}}\) must not be larger than \(1\).
The length of \(C.\href{../valid/conventions.html#context}{\mathsf{mems}}\) must not be larger than \(1\).
All export names \(\href{../syntax/modules.html#syntax-export}{\mathit{export}}_i.\href{../syntax/modules.html#syntax-export}{\mathsf{name}}\) must be different.
Let \(\mathit{ft}^\ast\) be the concatenation of the internal function types \(\mathit{ft}_i\), in index order.
Let \(\mathit{tt}^\ast\) be the concatenation of the internal table types \(\mathit{tt}_i\), in index order.
Let \(\mathit{mt}^\ast\) be the concatenation of the internal memory types \(\mathit{mt}_i\), in index order.
Let \(\mathit{gt}^\ast\) be the concatenation of the internal global types \(\mathit{gt}_i\), in index order.
Let \(\mathit{it}^\ast\) be the concatenation of external types \(\mathit{it}_i\) of the imports, in index order.
Let \(\mathit{et}^\ast\) be the concatenation of external types \(\mathit{et}_i\) of the exports, in index order.
Then the module is valid with external types \(\mathit{it}^\ast \href{../syntax/types.html#syntax-functype}{\rightarrow} \mathit{et}^\ast\).
Note
Most definitions in a module – particularly functions – are mutually recursive. Consequently, the definition of the context \(C\) in this rule is recursive: it depends on the outcome of validation of the function, table, memory, and global definitions contained in the module, which itself depends on \(C\). However, this recursion is just a specification device. All types needed to construct \(C\) can easily be determined from a simple pre-pass over the module that does not perform any actual validation.
Globals, however, are not recursive. The effect of defining the limited context \(C'\) for validating the module’s globals is that their initialization expressions can only access imported globals and nothing else.
Note
The restriction on the number of tables and memories may be lifted in future versions of WebAssembly.