模块
模块的二进制编码组织成节。大多数节对应于模块记录的一个组件,但函数定义被分成两个节,在函数节中分离它们的类型声明,在代码节中分离它们的函数体。
注意
这种分离使得能够并行和流式编译模块中的函数。
索引
所有索引都使用它们各自的值进行编码。
\[\begin{split}\begin{array}{llclll} \def\mathdef1857#1{{}}\mathdef1857{类型索引} & \href{../binary/modules.html#binary-typeidx}{\mathtt{typeidx}} &::=& x{:}\href{../binary/values.html#binary-int}{\def\mathdef1862#1{{\mathtt{u}#1}}\mathdef1862{\mathtt{32}}} &\Rightarrow& x \\ \def\mathdef1857#1{{}}\mathdef1857{函数索引} & \href{../binary/modules.html#binary-funcidx}{\mathtt{funcidx}} &::=& x{:}\href{../binary/values.html#binary-int}{\def\mathdef1862#1{{\mathtt{u}#1}}\mathdef1862{\mathtt{32}}} &\Rightarrow& x \\ \def\mathdef1857#1{{}}\mathdef1857{表索引} & \href{../binary/modules.html#binary-tableidx}{\mathtt{tableidx}} &::=& x{:}\href{../binary/values.html#binary-int}{\def\mathdef1862#1{{\mathtt{u}#1}}\mathdef1862{\mathtt{32}}} &\Rightarrow& x \\ \def\mathdef1857#1{{}}\mathdef1857{内存索引} & \href{../binary/modules.html#binary-memidx}{\mathtt{memidx}} &::=& x{:}\href{../binary/values.html#binary-int}{\def\mathdef1862#1{{\mathtt{u}#1}}\mathdef1862{\mathtt{32}}} &\Rightarrow& x \\ \def\mathdef1857#1{{}}\mathdef1857{全局索引} & \href{../binary/modules.html#binary-globalidx}{\mathtt{globalidx}} &::=& x{:}\href{../binary/values.html#binary-int}{\def\mathdef1862#1{{\mathtt{u}#1}}\mathdef1862{\mathtt{32}}} &\Rightarrow& x \\ \def\mathdef1857#1{{}}\mathdef1857{元素索引} & \href{../binary/modules.html#binary-elemidx}{\mathtt{elemidx}} &::=& x{:}\href{../binary/values.html#binary-int}{\def\mathdef1862#1{{\mathtt{u}#1}}\mathdef1862{\mathtt{32}}} &\Rightarrow& x \\ \def\mathdef1857#1{{}}\mathdef1857{数据索引} & \href{../binary/modules.html#binary-dataidx}{\mathtt{dataidx}} &::=& x{:}\href{../binary/values.html#binary-int}{\def\mathdef1862#1{{\mathtt{u}#1}}\mathdef1862{\mathtt{32}}} &\Rightarrow& x \\ \def\mathdef1857#1{{}}\mathdef1857{局部索引} & \href{../binary/modules.html#binary-localidx}{\mathtt{localidx}} &::=& x{:}\href{../binary/values.html#binary-int}{\def\mathdef1862#1{{\mathtt{u}#1}}\mathdef1862{\mathtt{32}}} &\Rightarrow& x \\ \def\mathdef1857#1{{}}\mathdef1857{标签索引} & \href{../binary/modules.html#binary-labelidx}{\mathtt{labelidx}} &::=& l{:}\href{../binary/values.html#binary-int}{\def\mathdef1862#1{{\mathtt{u}#1}}\mathdef1862{\mathtt{32}}} &\Rightarrow& l \\ \end{array}\end{split}\]
节
每个节由以下部分组成:
每个节都是可选的;省略的节等同于该节存在且内容为空。
以下参数化语法规则定义了具有id \(N\)且内容由语法 \(\mathtt{B}\) 描述的节的通用结构。
\[\begin{split}\begin{array}{llclll@{\qquad}l} \def\mathdef1857#1{{}}\mathdef1857{节} & \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\mathdef1862#1{{\mathtt{u}#1}}\mathdef1862{\mathtt{32}}}~~\mathit{cont}{:}\mathtt{B} &\Rightarrow& \mathit{cont} & (\mathrel{\mbox{if}} \mathit{size} = ||\mathtt{B}||) \\ &&|& \epsilon &\Rightarrow& \epsilon \end{array}\end{split}\]
对于大多数节,内容 \(\mathtt{B}\) 编码一个向量。在这些情况下,空结果 \(\epsilon\) 被解释为空向量。
注意
除了未知的自定义节之外,\(\mathit{size}\) 对于解码不是必需的,但可以在遍历二进制文件时用于跳过节。如果大小与二进制内容 \(\mathtt{B}\) 的长度不匹配,则模块格式错误。
使用以下节id
自定义节
自定义节的id为0。它们旨在用于调试信息或第三方扩展,并且被WebAssembly语义忽略。它们的内容由一个名称进一步标识自定义节,后跟一个用于自定义用途的未解释字节序列。
\[\begin{split}\begin{array}{llclll} \def\mathdef1857#1{{}}\mathdef1857{自定义节} & \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\mathdef1857#1{{}}\mathdef1857{自定义数据} & \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}\]
注意
如果实现解释自定义节的数据,则该数据中的错误或节的放置不得使模块无效。
类型节
类型节的id为1。它解码成函数类型的向量,这些函数类型表示模块的\(\href{../syntax/modules.html#syntax-module}{\mathsf{types}}\)组件。
\[\begin{split}\begin{array}{llclll} \def\mathdef1857#1{{}}\mathdef1857{类型节} & \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}\]
导入节
导入节的id为2。它解码成导入的向量,这些导入表示模块的\(\href{../syntax/modules.html#syntax-module}{\mathsf{imports}}\)组件。
\[\begin{split}\begin{array}{llclll} \def\mathdef1857#1{{}}\mathdef1857{导入节} & \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\mathdef1857#1{{}}\mathdef1857{导入} & \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\mathdef1857#1{{}}\mathdef1857{导入描述} & \href{../binary/modules.html#binary-importdesc}{\mathtt{importdesc}} &::=& \def\mathdef1896#1{\mathtt{0x#1}}\mathdef1896{00}~~x{:}\href{../binary/modules.html#binary-typeidx}{\mathtt{typeidx}} &\Rightarrow& \href{../syntax/modules.html#syntax-importdesc}{\mathsf{func}}~x \\ &&|& \def\mathdef1897#1{\mathtt{0x#1}}\mathdef1897{01}~~\mathit{tt}{:}\href{../binary/types.html#binary-tabletype}{\mathtt{tabletype}} &\Rightarrow& \href{../syntax/modules.html#syntax-importdesc}{\mathsf{table}}~\mathit{tt} \\ &&|& \def\mathdef1898#1{\mathtt{0x#1}}\mathdef1898{02}~~\mathit{mt}{:}\href{../binary/types.html#binary-memtype}{\mathtt{memtype}} &\Rightarrow& \href{../syntax/modules.html#syntax-importdesc}{\mathsf{mem}}~\mathit{mt} \\ &&|& \def\mathdef1899#1{\mathtt{0x#1}}\mathdef1899{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}\]
函数节
函数节的id为3。它解码成类型索引的向量,这些类型索引表示模块的\(\href{../syntax/modules.html#syntax-module}{\mathsf{funcs}}\)组件中函数的\(\href{../syntax/modules.html#syntax-func}{\mathsf{type}}\)字段。代码节中分别编码了相应函数的\(\href{../syntax/modules.html#syntax-func}{\mathsf{locals}}\)和\(\href{../syntax/modules.html#syntax-func}{\mathsf{body}}\)字段。
\[\begin{split}\begin{array}{llclll} \def\mathdef1857#1{{}}\mathdef1857{函数节} & \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}\]
表节
表节的id为4。它解码成表的向量,这些表表示模块的\(\href{../syntax/modules.html#syntax-module}{\mathsf{tables}}\)组件。
\[\begin{split}\begin{array}{llclll} \def\mathdef1857#1{{}}\mathdef1857{表节} & \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\mathdef1857#1{{}}\mathdef1857{表} & \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}\]
内存节
内存节的id为5。它解码成内存的向量,这些内存表示模块的\(\href{../syntax/modules.html#syntax-module}{\mathsf{mems}}\)组件。
\[\begin{split}\begin{array}{llclll} \def\mathdef1857#1{{}}\mathdef1857{内存节} & \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\mathdef1857#1{{}}\mathdef1857{内存} & \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}\]
全局节
全局节的id为6。它解码成全局变量的向量,这些全局变量表示模块的\(\href{../syntax/modules.html#syntax-module}{\mathsf{globals}}\)组件。
\[\begin{split}\begin{array}{llclll} \def\mathdef1857#1{{}}\mathdef1857{全局节} & \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\mathdef1857#1{{}}\mathdef1857{全局变量} & \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}\]
导出节
导出段的id为7。它解码为一个导出向量,表示模块的\(\href{../syntax/modules.html#syntax-module}{\mathsf{exports}}\) 组件。
\[\begin{split}\begin{array}{llclll} \def\mathdef1857#1{{}}\mathdef1857{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\mathdef1857#1{{}}\mathdef1857{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\mathdef1857#1{{}}\mathdef1857{export description} & \href{../binary/modules.html#binary-exportdesc}{\mathtt{exportdesc}} &::=& \def\mathdef1900#1{\mathtt{0x#1}}\mathdef1900{00}~~x{:}\href{../binary/modules.html#binary-funcidx}{\mathtt{funcidx}} &\Rightarrow& \href{../syntax/modules.html#syntax-exportdesc}{\mathsf{func}}~x \\ &&|& \def\mathdef1901#1{\mathtt{0x#1}}\mathdef1901{01}~~x{:}\href{../binary/modules.html#binary-tableidx}{\mathtt{tableidx}} &\Rightarrow& \href{../syntax/modules.html#syntax-exportdesc}{\mathsf{table}}~x \\ &&|& \def\mathdef1902#1{\mathtt{0x#1}}\mathdef1902{02}~~x{:}\href{../binary/modules.html#binary-memidx}{\mathtt{memidx}} &\Rightarrow& \href{../syntax/modules.html#syntax-exportdesc}{\mathsf{mem}}~x \\ &&|& \def\mathdef1903#1{\mathtt{0x#1}}\mathdef1903{03}~~x{:}\href{../binary/modules.html#binary-globalidx}{\mathtt{globalidx}} &\Rightarrow& \href{../syntax/modules.html#syntax-exportdesc}{\mathsf{global}}~x \\ \end{array}\end{split}\]
起始段
起始段的id为8。它解码为一个可选的起始函数,表示模块的\(\href{../syntax/modules.html#syntax-module}{\mathsf{start}}\) 组件。
\[\begin{split}\begin{array}{llclll} \def\mathdef1857#1{{}}\mathdef1857{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\mathdef1857#1{{}}\mathdef1857{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}\]
元素段
元素段的id为9。它解码为一个元素段向量,表示模块的\(\href{../syntax/modules.html#syntax-module}{\mathsf{elems}}\) 组件。
\[\begin{split}\begin{array}{llclll} \def\mathdef1857#1{{}}\mathdef1857{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\mathdef1857#1{{}}\mathdef1857{element segment} & \href{../binary/modules.html#binary-elem}{\mathtt{elem}} &::=& 0{:}\href{../binary/values.html#binary-int}{\def\mathdef1862#1{{\mathtt{u}#1}}\mathdef1862{\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\mathdef1862#1{{\mathtt{u}#1}}\mathdef1862{\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\mathdef1862#1{{\mathtt{u}#1}}\mathdef1862{\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\mathdef1862#1{{\mathtt{u}#1}}\mathdef1862{\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\mathdef1862#1{{\mathtt{u}#1}}\mathdef1862{\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\mathdef1862#1{{\mathtt{u}#1}}\mathdef1862{\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\mathdef1862#1{{\mathtt{u}#1}}\mathdef1862{\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\mathdef1862#1{{\mathtt{u}#1}}\mathdef1862{\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\mathdef1857#1{{}}\mathdef1857{element kind} & \href{../binary/modules.html#binary-elemkind}{\mathtt{elemkind}} &::=& \def\mathdef1904#1{\mathtt{0x#1}}\mathdef1904{00} &\Rightarrow& \href{../syntax/types.html#syntax-reftype}{\mathsf{funcref}} \\ \end{array}\end{split}\]
注意
初始整数可以解释为一个位域。第0位区分被动或声明性段和活动段,第1位指示活动段中是否存在显式表索引,否则区分被动段和声明性段,第2位指示使用元素类型和元素表达式而不是元素种类和元素索引。
WebAssembly 的未来版本可能会添加其他元素种类。
代码段
代码段的id为10。它解码为一个代码条目的向量,这些条目是值类型向量和表达式的配对。它们表示模块的\(\href{../syntax/modules.html#syntax-module}{\mathsf{funcs}}\) 组件中函数的\(\href{../syntax/modules.html#syntax-func}{\mathsf{locals}}\) 和\(\href{../syntax/modules.html#syntax-func}{\mathsf{body}}\) 字段。函数段中分别编码了各个函数的\(\href{../syntax/modules.html#syntax-func}{\mathsf{type}}\) 字段。
每个代码条目的编码包括
局部变量声明被压缩成一个向量,其条目包括
表示相同值类型的计数个局部变量。
\[\begin{split}\begin{array}{llclll@{\qquad}l} \def\mathdef1857#1{{}}\mathdef1857{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\mathdef1857#1{{}}\mathdef1857{code} & \href{../binary/modules.html#binary-code}{\mathtt{code}} &::=& \mathit{size}{:}\href{../binary/values.html#binary-int}{\def\mathdef1862#1{{\mathtt{u}#1}}\mathdef1862{\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\mathdef1857#1{{}}\mathdef1857{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\mathdef1857#1{{}}\mathdef1857{locals} & \href{../binary/modules.html#binary-local}{\mathtt{locals}} &::=& n{:}\href{../binary/values.html#binary-int}{\def\mathdef1862#1{{\mathtt{u}#1}}\mathdef1862{\mathtt{32}}}~~t{:}\href{../binary/types.html#binary-valtype}{\mathtt{valtype}} &\Rightarrow& t^n \\ \end{array}\end{split}\]
这里,\(\mathit{code}\) 涵盖\((\href{../syntax/types.html#syntax-valtype}{\mathit{valtype}}^\ast, \href{../syntax/instructions.html#syntax-expr}{\mathit{expr}})\) 对。元函数\(\href{../syntax/conventions.html#notation-concat}{\mathrm{concat}}((t^\ast)^\ast)\) 连接\((t^\ast)^\ast\) 中的所有序列\(t_i^\ast\)。如果结果序列的长度超出向量最大大小的范围,则该代码格式错误。
注意
与段类似,代码\(\mathit{size}\) 不需要用于解码,但可用于在遍历二进制文件时跳过函数。如果大小与相应函数代码的长度不匹配,则模块格式错误。
数据段
数据段的id为11。它解码为一个数据段向量,表示模块的\(\href{../syntax/modules.html#syntax-module}{\mathsf{datas}}\) 组件。
\[\begin{split}\begin{array}{llclll} \def\mathdef1857#1{{}}\mathdef1857{数据段} & \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\mathdef1857#1{{}}\mathdef1857{数据段} & \href{../binary/modules.html#binary-data}{\mathtt{data}} &::=& 0{:}\href{../binary/values.html#binary-int}{\def\mathdef1862#1{{\mathtt{u}#1}}\mathdef1862{\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\mathdef1862#1{{\mathtt{u}#1}}\mathdef1862{\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\mathdef1862#1{{\mathtt{u}#1}}\mathdef1862{\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}\]
注意
初始整数可以解释为一个位域。第 0 位表示被动段,第 1 位表示活动段存在显式内存索引。
在当前版本的 WebAssembly 中,最多可以在单个模块中定义或导入一个内存,因此所有有效的 active 数据段的 \(\href{../syntax/modules.html#syntax-data}{\mathsf{memory}}\) 值为 \(0\)。
数据计数段
数据计数段 的 ID 为 12。它解码成一个可选的 u32,表示 数据段 在 数据段 中的数量。如果此计数与数据段向量的长度不匹配,则模块格式错误。
\[\begin{split}\begin{array}{llclll} \def\mathdef1857#1{{}}\mathdef1857{数据计数段} & \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\mathdef1862#1{{\mathtt{u}#1}}\mathdef1862{\mathtt{32}}}) &\Rightarrow& \mathit{n}^? \\ \end{array}\end{split}\]
注意
数据计数段用于简化单遍验证。由于数据段出现在代码段之后,\(\href{../syntax/instructions.html#syntax-instr-memory}{\mathsf{memory.init}}\) 和 \(\href{../syntax/instructions.html#syntax-instr-memory}{\mathsf{data.drop}}\) 指令无法在读取数据段之前检查数据段索引是否有效。数据计数段出现在代码段之前,因此单遍验证器可以使用此计数,而不是延迟验证。
模块
一个 模块 的编码以包含 4 字节魔数(字符串 \(\def\mathdef1905#1{\mbox{‘}\mathtt{#1}\mbox{’}}\mathdef1905{\backslash0asm}\))和版本字段的前导部分开始。WebAssembly 二进制格式的当前版本为 1。
前导部分之后是一系列 段。可以在此序列中的任何位置插入 自定义段,而其他段最多只能出现一次,并且必须按规定的顺序出现。所有段都可以为空。
由(可能为空的)函数 和 代码 段生成的向量的长度必须匹配。
类似地,可选的数据计数必须与 数据段 向量的长度匹配。此外,如果代码段中出现任何 数据索引,则必须存在。
\[\begin{split}\begin{array}{llcllll} \def\mathdef1857#1{{}}\mathdef1857{魔数} & \href{../binary/modules.html#binary-magic}{\mathtt{magic}} &::=& \def\mathdef1906#1{\mathtt{0x#1}}\mathdef1906{00}~\def\mathdef1907#1{\mathtt{0x#1}}\mathdef1907{61}~\def\mathdef1908#1{\mathtt{0x#1}}\mathdef1908{73}~\def\mathdef1909#1{\mathtt{0x#1}}\mathdef1909{6D} \\ \def\mathdef1857#1{{}}\mathdef1857{版本} & \href{../binary/modules.html#binary-version}{\mathtt{version}} &::=& \def\mathdef1910#1{\mathtt{0x#1}}\mathdef1910{01}~\def\mathdef1911#1{\mathtt{0x#1}}\mathdef1911{00}~\def\mathdef1912#1{\mathtt{0x#1}}\mathdef1912{00}~\def\mathdef1913#1{\mathtt{0x#1}}\mathdef1913{00} \\ \def\mathdef1857#1{{}}\mathdef1857{模块} & \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}\]
其中,对于 \(t_i^\ast, e_i\) 在 \(\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}\]
注意
如果必须对格式进行向后不兼容的更改,WebAssembly 二进制格式的版本将来可能会增加。但是,此类更改预计很少发生,即使发生也是极少数。二进制格式旨在向前兼容,以便将来可以进行扩展而无需增加其版本。