Modules

The binary encoding of modules is organized into sections. Most sections correspond to one component of a module record, except that function definitions are split into two sections, separating their type declarations in the function section from their bodies in the code section.

Note

This separation enables parallel and streaming compilation of the functions in a module.

Indices

All indices are encoded with their respective value.

\[\begin{split}\begin{array}{llclll} \def\mathdef1859#1{{}}\mathdef1859{type index} & \href{../binary/modules.html#binary-typeidx}{\mathtt{typeidx}} &::=& x{:}\href{../binary/values.html#binary-int}{\def\mathdef1864#1{{\mathtt{u}#1}}\mathdef1864{\mathtt{32}}} &\Rightarrow& x \\ \def\mathdef1859#1{{}}\mathdef1859{function index} & \href{../binary/modules.html#binary-funcidx}{\mathtt{funcidx}} &::=& x{:}\href{../binary/values.html#binary-int}{\def\mathdef1864#1{{\mathtt{u}#1}}\mathdef1864{\mathtt{32}}} &\Rightarrow& x \\ \def\mathdef1859#1{{}}\mathdef1859{table index} & \href{../binary/modules.html#binary-tableidx}{\mathtt{tableidx}} &::=& x{:}\href{../binary/values.html#binary-int}{\def\mathdef1864#1{{\mathtt{u}#1}}\mathdef1864{\mathtt{32}}} &\Rightarrow& x \\ \def\mathdef1859#1{{}}\mathdef1859{memory index} & \href{../binary/modules.html#binary-memidx}{\mathtt{memidx}} &::=& x{:}\href{../binary/values.html#binary-int}{\def\mathdef1864#1{{\mathtt{u}#1}}\mathdef1864{\mathtt{32}}} &\Rightarrow& x \\ \def\mathdef1859#1{{}}\mathdef1859{global index} & \href{../binary/modules.html#binary-globalidx}{\mathtt{globalidx}} &::=& x{:}\href{../binary/values.html#binary-int}{\def\mathdef1864#1{{\mathtt{u}#1}}\mathdef1864{\mathtt{32}}} &\Rightarrow& x \\ \def\mathdef1859#1{{}}\mathdef1859{element index} & \href{../binary/modules.html#binary-elemidx}{\mathtt{elemidx}} &::=& x{:}\href{../binary/values.html#binary-int}{\def\mathdef1864#1{{\mathtt{u}#1}}\mathdef1864{\mathtt{32}}} &\Rightarrow& x \\ \def\mathdef1859#1{{}}\mathdef1859{data index} & \href{../binary/modules.html#binary-dataidx}{\mathtt{dataidx}} &::=& x{:}\href{../binary/values.html#binary-int}{\def\mathdef1864#1{{\mathtt{u}#1}}\mathdef1864{\mathtt{32}}} &\Rightarrow& x \\ \def\mathdef1859#1{{}}\mathdef1859{local index} & \href{../binary/modules.html#binary-localidx}{\mathtt{localidx}} &::=& x{:}\href{../binary/values.html#binary-int}{\def\mathdef1864#1{{\mathtt{u}#1}}\mathdef1864{\mathtt{32}}} &\Rightarrow& x \\ \def\mathdef1859#1{{}}\mathdef1859{label index} & \href{../binary/modules.html#binary-labelidx}{\mathtt{labelidx}} &::=& l{:}\href{../binary/values.html#binary-int}{\def\mathdef1864#1{{\mathtt{u}#1}}\mathdef1864{\mathtt{32}}} &\Rightarrow& l \\ \end{array}\end{split}\]

Sections

Each section consists of

  • a one-byte section id,

  • the \(\href{../syntax/values.html#syntax-int}{\mathit{u32}}\) size of the contents, in bytes,

  • the actual contents, whose structure is depended on the section id.

Every section is optional; an omitted section is equivalent to the section being present with empty contents.

The following parameterized grammar rule defines the generic structure of a section with id \(N\) and contents described by the grammar \(\mathtt{B}\).

\[\begin{split}\begin{array}{llclll@{\qquad}l} \def\mathdef1859#1{{}}\mathdef1859{section} & \href{../binary/modules.html#binary-section}{\mathtt{section}}_N(\mathtt{B}) &::=& N{:}\href{../binary/values.html#binary-byte}{\mathtt{byte}}~~\mathit{size}{:}\href{../binary/values.html#binary-int}{\def\mathdef1864#1{{\mathtt{u}#1}}\mathdef1864{\mathtt{32}}}~~\mathit{cont}{:}\mathtt{B} &\Rightarrow& \mathit{cont} & (\mathrel{\mbox{if}} \mathit{size} = ||\mathtt{B}||) \\ &&|& \epsilon &\Rightarrow& \epsilon \end{array}\end{split}\]

For most sections, the contents \(\mathtt{B}\) encodes a vector. In these cases, the empty result \(\epsilon\) is interpreted as the empty vector.

Note

Other than for unknown custom sections, the \(\mathit{size}\) is not required for decoding, but can be used to skip sections when navigating through a binary. The module is malformed if the size does not match the length of the binary contents \(\mathtt{B}\).

The following section ids are used:

Id

Section

0

custom section

1

type section

2

import section

3

function section

4

table section

5

memory section

6

global section

7

export section

8

start section

9

element section

10

code section

11

data section

12

data count section

Custom Section

Custom sections have the id 0. They are intended to be used for debugging information or third-party extensions, and are ignored by the WebAssembly semantics. Their contents consist of a name further identifying the custom section, followed by an uninterpreted sequence of bytes for custom use.

\[\begin{split}\begin{array}{llclll} \def\mathdef1859#1{{}}\mathdef1859{custom section} & \href{../binary/modules.html#binary-customsec}{\mathtt{customsec}} &::=& \href{../binary/modules.html#binary-section}{\mathtt{section}}_0(\href{../binary/modules.html#binary-customsec}{\mathtt{custom}}) \\ \def\mathdef1859#1{{}}\mathdef1859{custom data} & \href{../binary/modules.html#binary-customsec}{\mathtt{custom}} &::=& \href{../binary/values.html#binary-name}{\mathtt{name}}~~\href{../binary/values.html#binary-byte}{\mathtt{byte}}^\ast \\ \end{array}\end{split}\]

Note

If an implementation interprets the data of a custom section, then errors in that data, or the placement of the section, must not invalidate the module.

Type Section

The type section has the id 1. It decodes into a vector of function types that represent the \(\href{../syntax/modules.html#syntax-module}{\mathsf{types}}\) component of a module.

\[\begin{split}\begin{array}{llclll} \def\mathdef1859#1{{}}\mathdef1859{type section} & \href{../binary/modules.html#binary-typesec}{\mathtt{typesec}} &::=& \mathit{ft}^\ast{:\,}\href{../binary/modules.html#binary-section}{\mathtt{section}}_1(\href{../binary/conventions.html#binary-vec}{\mathtt{vec}}(\href{../binary/types.html#binary-functype}{\mathtt{functype}})) &\Rightarrow& \mathit{ft}^\ast \\ \end{array}\end{split}\]

Import Section

The import section has the id 2. It decodes into a vector of imports that represent the \(\href{../syntax/modules.html#syntax-module}{\mathsf{imports}}\) component of a module.

\[\begin{split}\begin{array}{llclll} \def\mathdef1859#1{{}}\mathdef1859{import section} & \href{../binary/modules.html#binary-importsec}{\mathtt{importsec}} &::=& \mathit{im}^\ast{:}\href{../binary/modules.html#binary-section}{\mathtt{section}}_2(\href{../binary/conventions.html#binary-vec}{\mathtt{vec}}(\href{../binary/modules.html#binary-import}{\mathtt{import}})) &\Rightarrow& \mathit{im}^\ast \\ \def\mathdef1859#1{{}}\mathdef1859{import} & \href{../binary/modules.html#binary-import}{\mathtt{import}} &::=& \mathit{mod}{:}\href{../binary/values.html#binary-name}{\mathtt{name}}~~\mathit{nm}{:}\href{../binary/values.html#binary-name}{\mathtt{name}}~~d{:}\href{../binary/modules.html#binary-importdesc}{\mathtt{importdesc}} &\Rightarrow& \{ \href{../syntax/modules.html#syntax-import}{\mathsf{module}}~\mathit{mod}, \href{../syntax/modules.html#syntax-import}{\mathsf{name}}~\mathit{nm}, \href{../syntax/modules.html#syntax-import}{\mathsf{desc}}~d \} \\ \def\mathdef1859#1{{}}\mathdef1859{import description} & \href{../binary/modules.html#binary-importdesc}{\mathtt{importdesc}} &::=& \def\mathdef1898#1{\mathtt{0x#1}}\mathdef1898{00}~~x{:}\href{../binary/modules.html#binary-typeidx}{\mathtt{typeidx}} &\Rightarrow& \href{../syntax/modules.html#syntax-importdesc}{\mathsf{func}}~x \\ &&|& \def\mathdef1899#1{\mathtt{0x#1}}\mathdef1899{01}~~\mathit{tt}{:}\href{../binary/types.html#binary-tabletype}{\mathtt{tabletype}} &\Rightarrow& \href{../syntax/modules.html#syntax-importdesc}{\mathsf{table}}~\mathit{tt} \\ &&|& \def\mathdef1900#1{\mathtt{0x#1}}\mathdef1900{02}~~\mathit{mt}{:}\href{../binary/types.html#binary-memtype}{\mathtt{memtype}} &\Rightarrow& \href{../syntax/modules.html#syntax-importdesc}{\mathsf{mem}}~\mathit{mt} \\ &&|& \def\mathdef1901#1{\mathtt{0x#1}}\mathdef1901{03}~~\mathit{gt}{:}\href{../binary/types.html#binary-globaltype}{\mathtt{globaltype}} &\Rightarrow& \href{../syntax/modules.html#syntax-importdesc}{\mathsf{global}}~\mathit{gt} \\ \end{array}\end{split}\]

Function Section

The function section has the id 3. It decodes into a vector of type indices that represent the \(\href{../syntax/modules.html#syntax-func}{\mathsf{type}}\) fields of the functions in the \(\href{../syntax/modules.html#syntax-module}{\mathsf{funcs}}\) component of a module. The \(\href{../syntax/modules.html#syntax-func}{\mathsf{locals}}\) and \(\href{../syntax/modules.html#syntax-func}{\mathsf{body}}\) fields of the respective functions are encoded separately in the code section.

\[\begin{split}\begin{array}{llclll} \def\mathdef1859#1{{}}\mathdef1859{function section} & \href{../binary/modules.html#binary-funcsec}{\mathtt{funcsec}} &::=& x^\ast{:}\href{../binary/modules.html#binary-section}{\mathtt{section}}_3(\href{../binary/conventions.html#binary-vec}{\mathtt{vec}}(\href{../binary/modules.html#binary-typeidx}{\mathtt{typeidx}})) &\Rightarrow& x^\ast \\ \end{array}\end{split}\]

Table Section

The table section has the id 4. It decodes into a vector of tables that represent the \(\href{../syntax/modules.html#syntax-module}{\mathsf{tables}}\) component of a module.

\[\begin{split}\begin{array}{llclll} \def\mathdef1859#1{{}}\mathdef1859{table section} & \href{../binary/modules.html#binary-tablesec}{\mathtt{tablesec}} &::=& \mathit{tab}^\ast{:}\href{../binary/modules.html#binary-section}{\mathtt{section}}_4(\href{../binary/conventions.html#binary-vec}{\mathtt{vec}}(\href{../binary/modules.html#binary-table}{\mathtt{table}})) &\Rightarrow& \mathit{tab}^\ast \\ \def\mathdef1859#1{{}}\mathdef1859{table} & \href{../binary/modules.html#binary-table}{\mathtt{table}} &::=& \mathit{tt}{:}\href{../binary/types.html#binary-tabletype}{\mathtt{tabletype}} &\Rightarrow& \{ \href{../syntax/modules.html#syntax-table}{\mathsf{type}}~\mathit{tt} \} \\ \end{array}\end{split}\]

Memory Section

The memory section has the id 5. It decodes into a vector of memories that represent the \(\href{../syntax/modules.html#syntax-module}{\mathsf{mems}}\) component of a module.

\[\begin{split}\begin{array}{llclll} \def\mathdef1859#1{{}}\mathdef1859{memory section} & \href{../binary/modules.html#binary-memsec}{\mathtt{memsec}} &::=& \mathit{mem}^\ast{:}\href{../binary/modules.html#binary-section}{\mathtt{section}}_5(\href{../binary/conventions.html#binary-vec}{\mathtt{vec}}(\href{../binary/modules.html#binary-mem}{\mathtt{mem}})) &\Rightarrow& \mathit{mem}^\ast \\ \def\mathdef1859#1{{}}\mathdef1859{memory} & \href{../binary/modules.html#binary-mem}{\mathtt{mem}} &::=& \mathit{mt}{:}\href{../binary/types.html#binary-memtype}{\mathtt{memtype}} &\Rightarrow& \{ \href{../syntax/modules.html#syntax-mem}{\mathsf{type}}~\mathit{mt} \} \\ \end{array}\end{split}\]

Global Section

The global section has the id 6. It decodes into a vector of globals that represent the \(\href{../syntax/modules.html#syntax-module}{\mathsf{globals}}\) component of a module.

\[\begin{split}\begin{array}{llclll} \def\mathdef1859#1{{}}\mathdef1859{global section} & \href{../binary/modules.html#binary-globalsec}{\mathtt{globalsec}} &::=& \mathit{glob}^\ast{:}\href{../binary/modules.html#binary-section}{\mathtt{section}}_6(\href{../binary/conventions.html#binary-vec}{\mathtt{vec}}(\href{../binary/modules.html#binary-global}{\mathtt{global}})) &\Rightarrow& \mathit{glob}^\ast \\ \def\mathdef1859#1{{}}\mathdef1859{global} & \href{../binary/modules.html#binary-global}{\mathtt{global}} &::=& \mathit{gt}{:}\href{../binary/types.html#binary-globaltype}{\mathtt{globaltype}}~~e{:}\href{../binary/instructions.html#binary-expr}{\mathtt{expr}} &\Rightarrow& \{ \href{../syntax/modules.html#syntax-global}{\mathsf{type}}~\mathit{gt}, \href{../syntax/modules.html#syntax-global}{\mathsf{init}}~e \} \\ \end{array}\end{split}\]

Export Section

The export section has the id 7. It decodes into a vector of exports that represent the \(\href{../syntax/modules.html#syntax-module}{\mathsf{exports}}\) component of a module.

\[\begin{split}\begin{array}{llclll} \def\mathdef1859#1{{}}\mathdef1859{export section} & \href{../binary/modules.html#binary-exportsec}{\mathtt{exportsec}} &::=& \mathit{ex}^\ast{:}\href{../binary/modules.html#binary-section}{\mathtt{section}}_7(\href{../binary/conventions.html#binary-vec}{\mathtt{vec}}(\href{../binary/modules.html#binary-export}{\mathtt{export}})) &\Rightarrow& \mathit{ex}^\ast \\ \def\mathdef1859#1{{}}\mathdef1859{export} & \href{../binary/modules.html#binary-export}{\mathtt{export}} &::=& \mathit{nm}{:}\href{../binary/values.html#binary-name}{\mathtt{name}}~~d{:}\href{../binary/modules.html#binary-exportdesc}{\mathtt{exportdesc}} &\Rightarrow& \{ \href{../syntax/modules.html#syntax-export}{\mathsf{name}}~\mathit{nm}, \href{../syntax/modules.html#syntax-export}{\mathsf{desc}}~d \} \\ \def\mathdef1859#1{{}}\mathdef1859{export description} & \href{../binary/modules.html#binary-exportdesc}{\mathtt{exportdesc}} &::=& \def\mathdef1902#1{\mathtt{0x#1}}\mathdef1902{00}~~x{:}\href{../binary/modules.html#binary-funcidx}{\mathtt{funcidx}} &\Rightarrow& \href{../syntax/modules.html#syntax-exportdesc}{\mathsf{func}}~x \\ &&|& \def\mathdef1903#1{\mathtt{0x#1}}\mathdef1903{01}~~x{:}\href{../binary/modules.html#binary-tableidx}{\mathtt{tableidx}} &\Rightarrow& \href{../syntax/modules.html#syntax-exportdesc}{\mathsf{table}}~x \\ &&|& \def\mathdef1904#1{\mathtt{0x#1}}\mathdef1904{02}~~x{:}\href{../binary/modules.html#binary-memidx}{\mathtt{memidx}} &\Rightarrow& \href{../syntax/modules.html#syntax-exportdesc}{\mathsf{mem}}~x \\ &&|& \def\mathdef1905#1{\mathtt{0x#1}}\mathdef1905{03}~~x{:}\href{../binary/modules.html#binary-globalidx}{\mathtt{globalidx}} &\Rightarrow& \href{../syntax/modules.html#syntax-exportdesc}{\mathsf{global}}~x \\ \end{array}\end{split}\]

Start Section

The start section has the id 8. It decodes into an optional start function that represents the \(\href{../syntax/modules.html#syntax-module}{\mathsf{start}}\) component of a module.

\[\begin{split}\begin{array}{llclll} \def\mathdef1859#1{{}}\mathdef1859{start section} & \href{../binary/modules.html#binary-startsec}{\mathtt{startsec}} &::=& \mathit{st}^?{:}\href{../binary/modules.html#binary-section}{\mathtt{section}}_8(\href{../binary/modules.html#binary-start}{\mathtt{start}}) &\Rightarrow& \mathit{st}^? \\ \def\mathdef1859#1{{}}\mathdef1859{start function} & \href{../binary/modules.html#binary-start}{\mathtt{start}} &::=& x{:}\href{../binary/modules.html#binary-funcidx}{\mathtt{funcidx}} &\Rightarrow& \{ \href{../syntax/modules.html#syntax-start}{\mathsf{func}}~x \} \\ \end{array}\end{split}\]

Element Section

The element section has the id 9. It decodes into a vector of element segments that represent the \(\href{../syntax/modules.html#syntax-module}{\mathsf{elems}}\) component of a module.

\[\begin{split}\begin{array}{llclll} \def\mathdef1859#1{{}}\mathdef1859{element section} & \href{../binary/modules.html#binary-elemsec}{\mathtt{elemsec}} &::=& \mathit{seg}^\ast{:}\href{../binary/modules.html#binary-section}{\mathtt{section}}_9(\href{../binary/conventions.html#binary-vec}{\mathtt{vec}}(\href{../binary/modules.html#binary-elem}{\mathtt{elem}})) &\Rightarrow& \mathit{seg}^\ast \\ \def\mathdef1859#1{{}}\mathdef1859{element segment} & \href{../binary/modules.html#binary-elem}{\mathtt{elem}} &::=& 0{:}\href{../binary/values.html#binary-int}{\def\mathdef1864#1{{\mathtt{u}#1}}\mathdef1864{\mathtt{32}}}~~e{:}\href{../binary/instructions.html#binary-expr}{\mathtt{expr}}~~y^\ast{:}\href{../binary/conventions.html#binary-vec}{\mathtt{vec}}(\href{../binary/modules.html#binary-funcidx}{\mathtt{funcidx}}) &\Rightarrow& \\&&&\quad \{ \href{../syntax/modules.html#syntax-elem}{\mathsf{type}}~\href{../syntax/types.html#syntax-reftype}{\mathsf{funcref}}, \href{../syntax/modules.html#syntax-elem}{\mathsf{init}}~((\href{../syntax/instructions.html#syntax-instr-ref}{\mathsf{ref{.}func}}~y)~\href{../syntax/instructions.html#syntax-instr-control}{\mathsf{end}})^\ast, \href{../syntax/modules.html#syntax-elem}{\mathsf{mode}}~\href{../syntax/modules.html#syntax-elemmode}{\mathsf{active}}~\{ \href{../syntax/modules.html#syntax-elem}{\mathsf{table}}~0, \href{../syntax/modules.html#syntax-elem}{\mathsf{offset}}~e \} \} \\ &&|& 1{:}\href{../binary/values.html#binary-int}{\def\mathdef1864#1{{\mathtt{u}#1}}\mathdef1864{\mathtt{32}}}~~\mathit{et}:\href{../binary/modules.html#binary-elemkind}{\mathtt{elemkind}}~~y^\ast{:}\href{../binary/conventions.html#binary-vec}{\mathtt{vec}}(\href{../binary/modules.html#binary-funcidx}{\mathtt{funcidx}}) &\Rightarrow& \\&&&\quad \{ \href{../syntax/modules.html#syntax-elem}{\mathsf{type}}~\mathit{et}, \href{../syntax/modules.html#syntax-elem}{\mathsf{init}}~((\href{../syntax/instructions.html#syntax-instr-ref}{\mathsf{ref{.}func}}~y)~\href{../syntax/instructions.html#syntax-instr-control}{\mathsf{end}})^\ast, \href{../syntax/modules.html#syntax-elem}{\mathsf{mode}}~\href{../syntax/modules.html#syntax-elemmode}{\mathsf{passive}} \} \\ &&|& 2{:}\href{../binary/values.html#binary-int}{\def\mathdef1864#1{{\mathtt{u}#1}}\mathdef1864{\mathtt{32}}}~~x{:}\href{../binary/modules.html#binary-tableidx}{\mathtt{tableidx}}~~e{:}\href{../binary/instructions.html#binary-expr}{\mathtt{expr}}~~\mathit{et}:\href{../binary/modules.html#binary-elemkind}{\mathtt{elemkind}}~~y^\ast{:}\href{../binary/conventions.html#binary-vec}{\mathtt{vec}}(\href{../binary/modules.html#binary-funcidx}{\mathtt{funcidx}}) &\Rightarrow& \\&&&\quad \{ \href{../syntax/modules.html#syntax-elem}{\mathsf{type}}~\mathit{et}, \href{../syntax/modules.html#syntax-elem}{\mathsf{init}}~((\href{../syntax/instructions.html#syntax-instr-ref}{\mathsf{ref{.}func}}~y)~\href{../syntax/instructions.html#syntax-instr-control}{\mathsf{end}})^\ast, \href{../syntax/modules.html#syntax-elem}{\mathsf{mode}}~\href{../syntax/modules.html#syntax-elemmode}{\mathsf{active}}~\{ \href{../syntax/modules.html#syntax-elem}{\mathsf{table}}~x, \href{../syntax/modules.html#syntax-elem}{\mathsf{offset}}~e \} \} \\ &&|& 3{:}\href{../binary/values.html#binary-int}{\def\mathdef1864#1{{\mathtt{u}#1}}\mathdef1864{\mathtt{32}}}~~\mathit{et}:\href{../binary/modules.html#binary-elemkind}{\mathtt{elemkind}}~~y^\ast{:}\href{../binary/conventions.html#binary-vec}{\mathtt{vec}}(\href{../binary/modules.html#binary-funcidx}{\mathtt{funcidx}}) &\Rightarrow& \\&&&\quad \{ \href{../syntax/modules.html#syntax-elem}{\mathsf{type}}~\mathit{et}, \href{../syntax/modules.html#syntax-elem}{\mathsf{init}}~((\href{../syntax/instructions.html#syntax-instr-ref}{\mathsf{ref{.}func}}~y)~\href{../syntax/instructions.html#syntax-instr-control}{\mathsf{end}})^\ast, \href{../syntax/modules.html#syntax-elem}{\mathsf{mode}}~\href{../syntax/modules.html#syntax-elemmode}{\mathsf{declarative}} \} \\ &&|& 4{:}\href{../binary/values.html#binary-int}{\def\mathdef1864#1{{\mathtt{u}#1}}\mathdef1864{\mathtt{32}}}~~e{:}\href{../binary/instructions.html#binary-expr}{\mathtt{expr}}~~\mathit{el}^\ast{:}\href{../binary/conventions.html#binary-vec}{\mathtt{vec}}(\href{../binary/instructions.html#binary-expr}{\mathtt{expr}}) &\Rightarrow& \\&&&\quad \{ \href{../syntax/modules.html#syntax-elem}{\mathsf{type}}~\href{../syntax/types.html#syntax-reftype}{\mathsf{funcref}}, \href{../syntax/modules.html#syntax-elem}{\mathsf{init}}~\mathit{el}^\ast, \href{../syntax/modules.html#syntax-elem}{\mathsf{mode}}~\href{../syntax/modules.html#syntax-elemmode}{\mathsf{active}}~\{ \href{../syntax/modules.html#syntax-elem}{\mathsf{table}}~0, \href{../syntax/modules.html#syntax-elem}{\mathsf{offset}}~e \} \} \\ &&|& 5{:}\href{../binary/values.html#binary-int}{\def\mathdef1864#1{{\mathtt{u}#1}}\mathdef1864{\mathtt{32}}}~~\mathit{et}:\href{../binary/types.html#binary-reftype}{\mathtt{reftype}}~~\mathit{el}^\ast{:}\href{../binary/conventions.html#binary-vec}{\mathtt{vec}}(\href{../binary/instructions.html#binary-expr}{\mathtt{expr}}) &\Rightarrow& \\&&&\quad \{ \href{../syntax/modules.html#syntax-elem}{\mathsf{type}}~et, \href{../syntax/modules.html#syntax-elem}{\mathsf{init}}~\mathit{el}^\ast, \href{../syntax/modules.html#syntax-elem}{\mathsf{mode}}~\href{../syntax/modules.html#syntax-elemmode}{\mathsf{passive}} \} \\ &&|& 6{:}\href{../binary/values.html#binary-int}{\def\mathdef1864#1{{\mathtt{u}#1}}\mathdef1864{\mathtt{32}}}~~x{:}\href{../binary/modules.html#binary-tableidx}{\mathtt{tableidx}}~~e{:}\href{../binary/instructions.html#binary-expr}{\mathtt{expr}}~~\mathit{et}:\href{../binary/types.html#binary-reftype}{\mathtt{reftype}}~~\mathit{el}^\ast{:}\href{../binary/conventions.html#binary-vec}{\mathtt{vec}}(\href{../binary/instructions.html#binary-expr}{\mathtt{expr}}) &\Rightarrow& \\&&&\quad \{ \href{../syntax/modules.html#syntax-elem}{\mathsf{type}}~et, \href{../syntax/modules.html#syntax-elem}{\mathsf{init}}~\mathit{el}^\ast, \href{../syntax/modules.html#syntax-elem}{\mathsf{mode}}~\href{../syntax/modules.html#syntax-elemmode}{\mathsf{active}}~\{ \href{../syntax/modules.html#syntax-elem}{\mathsf{table}}~x, \href{../syntax/modules.html#syntax-elem}{\mathsf{offset}}~e \} \} \\ &&|& 7{:}\href{../binary/values.html#binary-int}{\def\mathdef1864#1{{\mathtt{u}#1}}\mathdef1864{\mathtt{32}}}~~\mathit{et}:\href{../binary/types.html#binary-reftype}{\mathtt{reftype}}~~\mathit{el}^\ast{:}\href{../binary/conventions.html#binary-vec}{\mathtt{vec}}(\href{../binary/instructions.html#binary-expr}{\mathtt{expr}}) &\Rightarrow& \\&&&\quad \{ \href{../syntax/modules.html#syntax-elem}{\mathsf{type}}~et, \href{../syntax/modules.html#syntax-elem}{\mathsf{init}}~\mathit{el}^\ast, \href{../syntax/modules.html#syntax-elem}{\mathsf{mode}}~\href{../syntax/modules.html#syntax-elemmode}{\mathsf{declarative}} \} \\ \def\mathdef1859#1{{}}\mathdef1859{element kind} & \href{../binary/modules.html#binary-elemkind}{\mathtt{elemkind}} &::=& \def\mathdef1906#1{\mathtt{0x#1}}\mathdef1906{00} &\Rightarrow& \href{../syntax/types.html#syntax-reftype}{\mathsf{funcref}} \\ \end{array}\end{split}\]

Note

The initial integer can be interpreted as a bitfield. Bit 0 indicates a passive or declarative segment, bit 1 indicates the presence of an explicit table index for an active segment and otherwise distinguishes passive from declarative segments, bit 2 indicates the use of element type and element expressions instead of element kind and element indices.

Additional element kinds may be added in future versions of WebAssembly.

Code Section

The code section has the id 10. It decodes into a vector of code entries that are pairs of value type vectors and expressions. They represent the \(\href{../syntax/modules.html#syntax-func}{\mathsf{locals}}\) and \(\href{../syntax/modules.html#syntax-func}{\mathsf{body}}\) field of the functions in the \(\href{../syntax/modules.html#syntax-module}{\mathsf{funcs}}\) component of a module. The \(\href{../syntax/modules.html#syntax-func}{\mathsf{type}}\) fields of the respective functions are encoded separately in the function section.

The encoding of each code entry consists of

  • the \(\href{../syntax/values.html#syntax-int}{\mathit{u32}}\) size of the function code in bytes,

  • the actual function code, which in turn consists of

    • the declaration of locals,

    • the function body as an expression.

Local declarations are compressed into a vector whose entries consist of

  • a \(\href{../syntax/values.html#syntax-int}{\mathit{u32}}\) count,

  • a value type,

denoting count locals of the same value type.

\[\begin{split}\begin{array}{llclll@{\qquad}l} \def\mathdef1859#1{{}}\mathdef1859{code section} & \href{../binary/modules.html#binary-codesec}{\mathtt{codesec}} &::=& \mathit{code}^\ast{:}\href{../binary/modules.html#binary-section}{\mathtt{section}}_{10}(\href{../binary/conventions.html#binary-vec}{\mathtt{vec}}(\href{../binary/modules.html#binary-code}{\mathtt{code}})) &\Rightarrow& \mathit{code}^\ast \\ \def\mathdef1859#1{{}}\mathdef1859{code} & \href{../binary/modules.html#binary-code}{\mathtt{code}} &::=& \mathit{size}{:}\href{../binary/values.html#binary-int}{\def\mathdef1864#1{{\mathtt{u}#1}}\mathdef1864{\mathtt{32}}}~~\mathit{code}{:}\href{../binary/modules.html#binary-func}{\mathtt{func}} &\Rightarrow& \mathit{code} & (\mathrel{\mbox{if}} \mathit{size} = ||\href{../binary/modules.html#binary-func}{\mathtt{func}}||) \\ \def\mathdef1859#1{{}}\mathdef1859{function} & \href{../binary/modules.html#binary-func}{\mathtt{func}} &::=& (t^\ast)^\ast{:}\href{../binary/conventions.html#binary-vec}{\mathtt{vec}}(\href{../binary/modules.html#binary-local}{\mathtt{locals}})~~e{:}\href{../binary/instructions.html#binary-expr}{\mathtt{expr}} &\Rightarrow& \href{../syntax/conventions.html#notation-concat}{\mathrm{concat}}((t^\ast)^\ast), e & (\mathrel{\mbox{if}} |\href{../syntax/conventions.html#notation-concat}{\mathrm{concat}}((t^\ast)^\ast)| < 2^{32}) \\ \def\mathdef1859#1{{}}\mathdef1859{locals} & \href{../binary/modules.html#binary-local}{\mathtt{locals}} &::=& n{:}\href{../binary/values.html#binary-int}{\def\mathdef1864#1{{\mathtt{u}#1}}\mathdef1864{\mathtt{32}}}~~t{:}\href{../binary/types.html#binary-valtype}{\mathtt{valtype}} &\Rightarrow& t^n \\ \end{array}\end{split}\]

Here, \(\mathit{code}\) ranges over pairs \((\href{../syntax/types.html#syntax-valtype}{\mathit{valtype}}^\ast, \href{../syntax/instructions.html#syntax-expr}{\mathit{expr}})\). The meta function \(\href{../syntax/conventions.html#notation-concat}{\mathrm{concat}}((t^\ast)^\ast)\) concatenates all sequences \(t_i^\ast\) in \((t^\ast)^\ast\). Any code for which the length of the resulting sequence is out of bounds of the maximum size of a vector is malformed.

Note

Like with sections, the code \(\mathit{size}\) is not needed for decoding, but can be used to skip functions when navigating through a binary. The module is malformed if a size does not match the length of the respective function code.

Data Section

The data section has the id 11. It decodes into a vector of data segments that represent the \(\href{../syntax/modules.html#syntax-module}{\mathsf{datas}}\) component of a module.

\[\begin{split}\begin{array}{llclll} \def\mathdef1859#1{{}}\mathdef1859{data section} & \href{../binary/modules.html#binary-datasec}{\mathtt{datasec}} &::=& \mathit{seg}^\ast{:}\href{../binary/modules.html#binary-section}{\mathtt{section}}_{11}(\href{../binary/conventions.html#binary-vec}{\mathtt{vec}}(\href{../binary/modules.html#binary-data}{\mathtt{data}})) &\Rightarrow& \mathit{seg}^\ast \\ \def\mathdef1859#1{{}}\mathdef1859{data segment} & \href{../binary/modules.html#binary-data}{\mathtt{data}} &::=& 0{:}\href{../binary/values.html#binary-int}{\def\mathdef1864#1{{\mathtt{u}#1}}\mathdef1864{\mathtt{32}}}~~e{:}\href{../binary/instructions.html#binary-expr}{\mathtt{expr}}~~b^\ast{:}\href{../binary/conventions.html#binary-vec}{\mathtt{vec}}(\href{../binary/values.html#binary-byte}{\mathtt{byte}}) &\Rightarrow& \{ \href{../syntax/modules.html#syntax-data}{\mathsf{init}}~b^\ast, \href{../syntax/modules.html#syntax-data}{\mathsf{mode}}~\href{../syntax/modules.html#syntax-datamode}{\mathsf{active}}~\{ \href{../syntax/modules.html#syntax-data}{\mathsf{memory}}~0, \href{../syntax/modules.html#syntax-data}{\mathsf{offset}}~e \} \} \\ &&|& 1{:}\href{../binary/values.html#binary-int}{\def\mathdef1864#1{{\mathtt{u}#1}}\mathdef1864{\mathtt{32}}}~~b^\ast{:}\href{../binary/conventions.html#binary-vec}{\mathtt{vec}}(\href{../binary/values.html#binary-byte}{\mathtt{byte}}) &\Rightarrow& \{ \href{../syntax/modules.html#syntax-data}{\mathsf{init}}~b^\ast, \href{../syntax/modules.html#syntax-data}{\mathsf{mode}}~\href{../syntax/modules.html#syntax-datamode}{\mathsf{passive}} \} \\ &&|& 2{:}\href{../binary/values.html#binary-int}{\def\mathdef1864#1{{\mathtt{u}#1}}\mathdef1864{\mathtt{32}}}~~x{:}\href{../binary/modules.html#binary-memidx}{\mathtt{memidx}}~~e{:}\href{../binary/instructions.html#binary-expr}{\mathtt{expr}}~~b^\ast{:}\href{../binary/conventions.html#binary-vec}{\mathtt{vec}}(\href{../binary/values.html#binary-byte}{\mathtt{byte}}) &\Rightarrow& \{ \href{../syntax/modules.html#syntax-data}{\mathsf{init}}~b^\ast, \href{../syntax/modules.html#syntax-data}{\mathsf{mode}}~\href{../syntax/modules.html#syntax-datamode}{\mathsf{active}}~\{ \href{../syntax/modules.html#syntax-data}{\mathsf{memory}}~x, \href{../syntax/modules.html#syntax-data}{\mathsf{offset}}~e \} \} \\ \end{array}\end{split}\]

Note

The initial integer can be interpreted as a bitfield. Bit 0 indicates a passive segment, bit 1 indicates the presence of an explicit memory index for an active segment.

In the current version of WebAssembly, at most one memory may be defined or imported in a single module, so all valid active data segments have a \(\href{../syntax/modules.html#syntax-data}{\mathsf{memory}}\) value of \(0\).

Data Count Section

The data count section has the id 12. It decodes into an optional u32 that represents the number of data segments in the data section. If this count does not match the length of the data segment vector, the module is malformed.

\[\begin{split}\begin{array}{llclll} \def\mathdef1859#1{{}}\mathdef1859{data count section} & \href{../binary/modules.html#binary-datacountsec}{\mathtt{datacountsec}} &::=& \mathit{n}^?{:}\href{../binary/modules.html#binary-section}{\mathtt{section}}_{12}(\href{../binary/values.html#binary-int}{\def\mathdef1864#1{{\mathtt{u}#1}}\mathdef1864{\mathtt{32}}}) &\Rightarrow& \mathit{n}^? \\ \end{array}\end{split}\]

Note

The data count section is used to simplify single-pass validation. Since the data section occurs after the code section, the \(\href{../syntax/instructions.html#syntax-instr-memory}{\mathsf{memory.init}}\) and \(\href{../syntax/instructions.html#syntax-instr-memory}{\mathsf{data.drop}}\) instructions would not be able to check whether the data segment index is valid until the data section is read. The data count section occurs before the code section, so a single-pass validator can use this count instead of deferring validation.

Modules

The encoding of a module starts with a preamble containing a 4-byte magic number (the string \(\def\mathdef1907#1{\mbox{‘}\mathtt{#1}\mbox{’}}\mathdef1907{\backslash0asm}\)) and a version field. The current version of the WebAssembly binary format is 1.

The preamble is followed by a sequence of sections. Custom sections may be inserted at any place in this sequence, while other sections must occur at most once and in the prescribed order. All sections can be empty.

The lengths of vectors produced by the (possibly empty) function and code section must match up.

Similarly, the optional data count must match the length of the data segment vector. Furthermore, it must be present if any data index occurs in the code section.

\[\begin{split}\begin{array}{llcllll} \def\mathdef1859#1{{}}\mathdef1859{magic} & \href{../binary/modules.html#binary-magic}{\mathtt{magic}} &::=& \def\mathdef1908#1{\mathtt{0x#1}}\mathdef1908{00}~\def\mathdef1909#1{\mathtt{0x#1}}\mathdef1909{61}~\def\mathdef1910#1{\mathtt{0x#1}}\mathdef1910{73}~\def\mathdef1911#1{\mathtt{0x#1}}\mathdef1911{6D} \\ \def\mathdef1859#1{{}}\mathdef1859{version} & \href{../binary/modules.html#binary-version}{\mathtt{version}} &::=& \def\mathdef1912#1{\mathtt{0x#1}}\mathdef1912{01}~\def\mathdef1913#1{\mathtt{0x#1}}\mathdef1913{00}~\def\mathdef1914#1{\mathtt{0x#1}}\mathdef1914{00}~\def\mathdef1915#1{\mathtt{0x#1}}\mathdef1915{00} \\ \def\mathdef1859#1{{}}\mathdef1859{module} & \href{../binary/modules.html#binary-module}{\mathtt{module}} &::=& \href{../binary/modules.html#binary-magic}{\mathtt{magic}} \\ &&& \href{../binary/modules.html#binary-version}{\mathtt{version}} \\ &&& \href{../binary/modules.html#binary-customsec}{\mathtt{customsec}}^\ast \\ &&& \href{../syntax/types.html#syntax-functype}{\mathit{functype}}^\ast{:\,}\href{../binary/modules.html#binary-typesec}{\mathtt{typesec}} \\ &&& \href{../binary/modules.html#binary-customsec}{\mathtt{customsec}}^\ast \\ &&& \href{../syntax/modules.html#syntax-import}{\mathit{import}}^\ast{:\,}\href{../binary/modules.html#binary-importsec}{\mathtt{importsec}} \\ &&& \href{../binary/modules.html#binary-customsec}{\mathtt{customsec}}^\ast \\ &&& \href{../syntax/modules.html#syntax-typeidx}{\mathit{typeidx}}^n{:\,}\href{../binary/modules.html#binary-funcsec}{\mathtt{funcsec}} \\ &&& \href{../binary/modules.html#binary-customsec}{\mathtt{customsec}}^\ast \\ &&& \href{../syntax/modules.html#syntax-table}{\mathit{table}}^\ast{:\,}\href{../binary/modules.html#binary-tablesec}{\mathtt{tablesec}} \\ &&& \href{../binary/modules.html#binary-customsec}{\mathtt{customsec}}^\ast \\ &&& \href{../syntax/modules.html#syntax-mem}{\mathit{mem}}^\ast{:\,}\href{../binary/modules.html#binary-memsec}{\mathtt{memsec}} \\ &&& \href{../binary/modules.html#binary-customsec}{\mathtt{customsec}}^\ast \\ &&& \href{../syntax/modules.html#syntax-global}{\mathit{global}}^\ast{:\,}\href{../binary/modules.html#binary-globalsec}{\mathtt{globalsec}} \\ &&& \href{../binary/modules.html#binary-customsec}{\mathtt{customsec}}^\ast \\ &&& \href{../syntax/modules.html#syntax-export}{\mathit{export}}^\ast{:\,}\href{../binary/modules.html#binary-exportsec}{\mathtt{exportsec}} \\ &&& \href{../binary/modules.html#binary-customsec}{\mathtt{customsec}}^\ast \\ &&& \href{../syntax/modules.html#syntax-start}{\mathit{start}}^?{:\,}\href{../binary/modules.html#binary-startsec}{\mathtt{startsec}} \\ &&& \href{../binary/modules.html#binary-customsec}{\mathtt{customsec}}^\ast \\ &&& \href{../syntax/modules.html#syntax-elem}{\mathit{elem}}^\ast{:\,}\href{../binary/modules.html#binary-elemsec}{\mathtt{elemsec}} \\ &&& \href{../binary/modules.html#binary-customsec}{\mathtt{customsec}}^\ast \\ &&& m^?{:\,}\href{../binary/modules.html#binary-datacountsec}{\mathtt{datacountsec}} \\ &&& \href{../binary/modules.html#binary-customsec}{\mathtt{customsec}}^\ast \\ &&& \mathit{code}^n{:\,}\href{../binary/modules.html#binary-codesec}{\mathtt{codesec}} \\ &&& \href{../binary/modules.html#binary-customsec}{\mathtt{customsec}}^\ast \\ &&& \href{../syntax/modules.html#syntax-data}{\mathit{data}}^m{:\,}\href{../binary/modules.html#binary-datasec}{\mathtt{datasec}} \\ &&& \href{../binary/modules.html#binary-customsec}{\mathtt{customsec}}^\ast \quad\Rightarrow\quad \{~ \begin{array}[t]{@{}l@{}} \href{../syntax/modules.html#syntax-module}{\mathsf{types}}~\href{../syntax/types.html#syntax-functype}{\mathit{functype}}^\ast, \\ \href{../syntax/modules.html#syntax-module}{\mathsf{funcs}}~\href{../syntax/modules.html#syntax-func}{\mathit{func}}^n, \\ \href{../syntax/modules.html#syntax-module}{\mathsf{tables}}~\href{../syntax/modules.html#syntax-table}{\mathit{table}}^\ast, \\ \href{../syntax/modules.html#syntax-module}{\mathsf{mems}}~\href{../syntax/modules.html#syntax-mem}{\mathit{mem}}^\ast, \\ \href{../syntax/modules.html#syntax-module}{\mathsf{globals}}~\href{../syntax/modules.html#syntax-global}{\mathit{global}}^\ast, \\ \href{../syntax/modules.html#syntax-module}{\mathsf{elems}}~\href{../syntax/modules.html#syntax-elem}{\mathit{elem}}^\ast, \\ \href{../syntax/modules.html#syntax-module}{\mathsf{datas}}~\href{../syntax/modules.html#syntax-data}{\mathit{data}}^m, \\ \href{../syntax/modules.html#syntax-module}{\mathsf{start}}~\href{../syntax/modules.html#syntax-start}{\mathit{start}}^?, \\ \href{../syntax/modules.html#syntax-module}{\mathsf{imports}}~\href{../syntax/modules.html#syntax-import}{\mathit{import}}^\ast, \\ \href{../syntax/modules.html#syntax-module}{\mathsf{exports}}~\href{../syntax/modules.html#syntax-export}{\mathit{export}}^\ast ~\} \\ \end{array} \\ &&& (\mathrel{\mbox{if}} m^? \neq \epsilon \vee \href{../syntax/modules.html#syntax-dataidx}{\mathrm{dataidx}}(\mathit{code}^n) = \emptyset) \\ \end{array}\end{split}\]

where for each \(t_i^\ast, e_i\) in \(\mathit{code}^n\),

\[\begin{split}\href{../syntax/modules.html#syntax-func}{\mathit{func}}^n[i] = \{ \href{../syntax/modules.html#syntax-func}{\mathsf{type}}~\href{../syntax/modules.html#syntax-typeidx}{\mathit{typeidx}}^n[i], \href{../syntax/modules.html#syntax-func}{\mathsf{locals}}~t_i^\ast, \href{../syntax/modules.html#syntax-func}{\mathsf{body}}~e_i \} \\\end{split}\]

Note

The version of the WebAssembly binary format may increase in the future if backward-incompatible changes have to be made to the format. However, such changes are expected to occur very infrequently, if ever. The binary format is intended to be forward-compatible, such that future extensions can be made without incrementing its version.