From fa6ee73701027a02a0585c8b075de80230858786 Mon Sep 17 00:00:00 2001 From: rossberg-chromium Date: Thu, 27 Apr 2017 17:58:26 +0200 Subject: [PATCH 01/30] Start on text format --- document/appendix-textual/index.rst | 8 - document/binary/conventions.rst | 4 +- document/binary/instructions.rst | 28 +- document/binary/types.rst | 4 +- document/binary/values.rst | 6 +- document/index.rst | 2 +- document/math.def | 93 ++++++ document/text/conventions.rst | 82 +++++ document/text/index.rst | 13 + document/text/instructions.rst | 371 ++++++++++++++++++++++ document/text/modules.rst | 477 ++++++++++++++++++++++++++++ document/text/types.rst | 133 ++++++++ document/text/values.rst | 168 ++++++++++ 13 files changed, 1359 insertions(+), 30 deletions(-) delete mode 100644 document/appendix-textual/index.rst create mode 100644 document/text/conventions.rst create mode 100644 document/text/index.rst create mode 100644 document/text/instructions.rst create mode 100644 document/text/modules.rst create mode 100644 document/text/types.rst create mode 100644 document/text/values.rst diff --git a/document/appendix-textual/index.rst b/document/appendix-textual/index.rst deleted file mode 100644 index e7ea647eb8..0000000000 --- a/document/appendix-textual/index.rst +++ /dev/null @@ -1,8 +0,0 @@ -.. text-format: - -Appendix: Text Format ---------------------- - -.. todo:: - - Describe diff --git a/document/binary/conventions.rst b/document/binary/conventions.rst index c48bc84843..32f9512063 100644 --- a/document/binary/conventions.rst +++ b/document/binary/conventions.rst @@ -44,10 +44,10 @@ In order to distinguish symbols of the binary syntax from symbols of the abstrac * :math:`B^n` is a sequence of :math:`n\geq 0` iterations of :math:`B`. * :math:`B^\ast` is a possibly empty sequence of iterations of :math:`B`. - (This is a shorthand for :math:`A^n` used where :math:`n` is not relevant.) + (This is a shorthand for :math:`B^n` used where :math:`n` is not relevant.) * :math:`B^?` is an optional occurrence of :math:`B`. - (This is a shorthand for :math:`A^n` where :math:`n \leq 1`.) + (This is a shorthand for :math:`B^n` where :math:`n \leq 1`.) * :math:`x{:}B` denotes the same language as the nonterminal :math:`B`, but also binds the variable :math:`x` to the attribute synthesized for :math:`B`. diff --git a/document/binary/instructions.rst b/document/binary/instructions.rst index 945b391e8b..4047c740b7 100644 --- a/document/binary/instructions.rst +++ b/document/binary/instructions.rst @@ -23,17 +23,17 @@ Control Instructions :ref:`Control instructions ` have varying encodings. For structured instructions, the nested instruction sequences are terminated with explicit opcodes for |END| and |ELSE|. -.. _valid-nop: -.. _valid-unreachable: -.. _valid-block: -.. _valid-loop: -.. _valid-if: -.. _valid-br: -.. _valid-br_if: -.. _valid-br_table: -.. _valid-return: -.. _valid-call: -.. _valid-call_indirect: +.. _binary-nop: +.. _binary-unreachable: +.. _binary-block: +.. _binary-loop: +.. _binary-if: +.. _binary-br: +.. _binary-br_if: +.. _binary-br_table: +.. _binary-return: +.. _binary-call: +.. _binary-call_indirect: .. math:: \begin{array}{llclll} @@ -51,8 +51,8 @@ Control Instructions &\Rightarrow& \IF~\X{rt}~\X{in}_1^\ast~\ELSE~\X{in}_2^\ast~\END \\ &&|& \hex{0C}~~l{:}\Blabelidx &\Rightarrow& \BR~l \\ &&|& \hex{0D}~~l{:}\Blabelidx &\Rightarrow& \BRIF~l \\ &&|& - \hex{0E}~~l^\ast{:}\Bvec(\Blabelidx)~~l_N{:}\Blabelidx &\Rightarrow& - \BRTABLE~l^\ast~l_N \\ &&|& + \hex{0E}~~l^\ast{:}\Bvec(\Blabelidx)~~l_N{:}\Blabelidx + &\Rightarrow& \BRTABLE~l^\ast~l_N \\ &&|& \hex{0F} &\Rightarrow& \RETURN \\ &&|& \hex{10}~~x{:}\Bfuncidx &\Rightarrow& \CALL~x \\ &&|& \hex{11}~~x{:}\Btypeidx &\Rightarrow& \CALLINDIRECT~x \\ @@ -113,7 +113,7 @@ Variable Instructions .. _binary-instr-memory: .. _binary-memarg: .. index:: memory instruction, memory index - pair: validation; instruction + pair: binary format; instruction single: abstract syntax; instruction Memory Instructions diff --git a/document/binary/types.rst b/document/binary/types.rst index 33e5188b56..b1ab57a015 100644 --- a/document/binary/types.rst +++ b/document/binary/types.rst @@ -105,8 +105,8 @@ Memory Types \end{array} -.. _syntax-tabletype: -.. _syntax-elemtype: +.. _binary-tabletype: +.. _binary-elemtype: .. index:: table type, element type, limits pair: binary format; table type pair: binary format; element type diff --git a/document/binary/values.rst b/document/binary/values.rst index b2abed9ffa..6c228b3bc3 100644 --- a/document/binary/values.rst +++ b/document/binary/values.rst @@ -1,6 +1,6 @@ .. _binary-value: .. index:: value - binary: binary format; value + pair: binary format; value single: abstract syntax; value Values @@ -9,13 +9,13 @@ Values .. _binary-byte: .. index:: byte - pair: binary encoding; byte + pair: binary format; byte single: abstract syntax; byte Bytes ~~~~~ -:ref:`Bytes ` encode themselves. +:ref:`Bytes ` encode themselves. .. math:: \begin{array}{llcll@{\qquad}l} diff --git a/document/index.rst b/document/index.rst index 6060619a7d..7ec7d4fd1d 100644 --- a/document/index.rst +++ b/document/index.rst @@ -15,9 +15,9 @@ WebAssembly Specification execution/index instructions/index binary/index + text/index appendix-properties/index appendix-algorithm/index - appendix-textual/index appendix-names/index .. only:: latex diff --git a/document/math.def b/document/math.def index d79f1fea3c..91244aa3b0 100644 --- a/document/math.def +++ b/document/math.def @@ -10,11 +10,13 @@ .. F - functions .. K - keywords / terminals .. B - binary grammar non-terminals +.. T - textual grammar non-terminals .. |X| mathdef:: \mathit .. |F| mathdef:: \mathrm .. |K| mathdef:: \mathsf .. |B| mathdef:: \mathtt +.. |T| mathdef:: \mathtt .. Auxiliary definitions for grammars @@ -26,6 +28,7 @@ .. |hex#1| mathdef:: \mathtt{0x#1} .. |unicode#1| mathdef:: \mathrm{U{+}#1} +.. |text#1| mathdef:: \mbox{‘}\mathtt{#1}\mbox{’} .. Values, non-terminals @@ -98,6 +101,41 @@ .. |Bcodecont| mathdef:: \xref{binary/values}{binary-name}{\B{cont}} +.. Values, textual non-terminals + +.. |Tbyte| mathdef:: \xref{text/values}{text-byte}{\T{byte}} + +.. |TuX#1| mathdef:: {\T{u}#1} +.. |TsX#1| mathdef:: {\T{s}#1} +.. |TiX#1| mathdef:: {\T{i}#1} +.. |TfX#1| mathdef:: {\T{f}#1} + +.. |TuN| mathdef:: \xref{text/values}{text-int}{\TuX{N}} +.. |Tu1| mathdef:: \xref{text/values}{text-int}{\TuX{\T{1}}} +.. |Tu8| mathdef:: \xref{text/values}{text-int}{\TuX{\T{8}}} +.. |Tu16| mathdef:: \xref{text/values}{text-int}{\TuX{\T{16}}} +.. |Tu32| mathdef:: \xref{text/values}{text-int}{\TuX{\T{32}}} +.. |Tu64| mathdef:: \xref{text/values}{text-int}{\TuX{\T{64}}} + +.. |TsN| mathdef:: \xref{text/values}{text-int}{\TsX{N}} +.. |Ts32| mathdef:: \xref{text/values}{text-int}{\TsX{\T{32}}} +.. |Ts64| mathdef:: \xref{text/values}{text-int}{\TsX{\T{64}}} + +.. |TiN| mathdef:: \xref{text/values}{text-int}{\TiX{N}} +.. |Ti32| mathdef:: \xref{text/values}{text-int}{\TiX{\T{32}}} +.. |Ti64| mathdef:: \xref{text/values}{text-int}{\TiX{\T{64}}} + +.. |TfN| mathdef:: \xref{text/values}{text-float}{\TfX{N}} +.. |Tf32| mathdef:: \xref{text/values}{text-float}{\TfX{\T{32}}} +.. |Tf64| mathdef:: \xref{text/values}{text-float}{\TfX{\T{64}}} + +.. |Tvec| mathdef:: \xref{text/values}{text-vec}{\T{vec}} +.. |Tname| mathdef:: \xref{text/values}{text-name}{\T{name}} +.. |Tcodepoint| mathdef:: \xref{text/values}{text-name}{\T{codepoint}} +.. |Tcodeval| mathdef:: \xref{text/values}{text-name}{\T{codeval}} +.. |Tcodecont| mathdef:: \xref{text/values}{text-name}{\T{cont}} + + .. Types, terminals .. |I32| mathdef:: \xref{syntax/types}{syntax-valtype}{\K{i32}} @@ -107,6 +145,7 @@ .. |ANYFUNC| mathdef:: \xref{syntax/types}{syntax-elemtype}{\K{anyfunc}} .. |MUT| mathdef:: \xref{syntax/types}{syntax-mut}{\K{mut}} +.. |VAR| mathdef:: \xref{syntax/types}{syntax-mut}{\K{var}} .. |MIN| mathdef:: \K{min} .. |MAX| mathdef:: \K{max} @@ -141,6 +180,22 @@ .. |Bmut| mathdef:: \xref{binary/types}{binary-mut}{\B{mut}} +.. Types, textual non-terminals + +.. |Tvaltype| mathdef:: \xref{text/types}{text-valtype}{\T{valtype}} +.. |Tresulttype| mathdef:: \xref{text/types}{text-resulttype}{\T{resulttype}} +.. |Tblocktype| mathdef:: \xref{text/types}{text-blocktype}{\T{blocktype}} +.. |Tfunctype| mathdef:: \xref{text/types}{text-functype}{\T{functype}} +.. |Tglobaltype| mathdef:: \xref{text/types}{text-globaltype}{\T{globaltype}} +.. |Ttabletype| mathdef:: \xref{text/types}{text-tabletype}{\T{tabletype}} +.. |Telemtype| mathdef:: \xref{text/types}{text-elemtype}{\T{elemtype}} +.. |Tmemtype| mathdef:: \xref{text/types}{text-memtype}{\T{memtype}} +.. |Texterntype| mathdef:: \xref{text/types}{text-externtype}{\T{externtype}} +.. |Tlimits| mathdef:: \xref{text/types}{text-limits}{\T{limits}} +.. |Tparam| mathdef:: \xref{text/types}{text-functype}{\T{param}} +.. |Tresult| mathdef:: \xref{text/types}{text-functype}{\T{result}} + + .. Indices .. |typeidx| mathdef:: \xref{syntax/modules}{syntax-typeidx}{\X{typeidx}} @@ -159,6 +214,14 @@ .. |Blocalidx| mathdef:: \xref{binary/modules}{binary-localidx}{\B{localidx}} .. |Blabelidx| mathdef:: \xref{binary/modules}{binary-labelidx}{\B{labelidx}} +.. |Ttypeidx| mathdef:: \xref{text/modules}{text-typeidx}{\T{typeidx}} +.. |Tfuncidx| mathdef:: \xref{text/modules}{text-funcidx}{\T{funcidx}} +.. |Ttableidx| mathdef:: \xref{text/modules}{text-tableidx}{\T{tableidx}} +.. |Tmemidx| mathdef:: \xref{text/modules}{text-memidx}{\T{memidx}} +.. |Tglobalidx| mathdef:: \xref{text/modules}{text-globalidx}{\T{globalidx}} +.. |Tlocalidx| mathdef:: \xref{text/modules}{text-localidx}{\T{localidx}} +.. |Tlabelidx| mathdef:: \xref{text/modules}{text-labelidx}{\T{labelidx}} + .. Modules, terminals @@ -249,6 +312,26 @@ .. |Bstart| mathdef:: \xref{binary/modules}{binary-start}{\B{start}} +.. Modules, textual non-terminals + +.. |Tmodule| mathdef:: \xref{text/modules}{text-module}{\T{module}} +.. |Ttype| mathdef:: \xref{text/modules}{text-type}{\T{type}} +.. |Tfunc| mathdef:: \xref{text/modules}{text-func}{\T{func}} +.. |Ttable| mathdef:: \xref{text/modules}{text-table}{\T{table}} +.. |Tmem| mathdef:: \xref{text/modules}{text-mem}{\T{mem}} +.. |Tglobal| mathdef:: \xref{text/modules}{text-global}{\T{global}} +.. |Timport| mathdef:: \xref{text/modules}{text-import}{\T{import}} +.. |Texport| mathdef:: \xref{text/modules}{text-export}{\T{export}} +.. |Timportdesc| mathdef:: \xref{text/modules}{text-importdesc}{\T{importdesc}} +.. |Texportdesc| mathdef:: \xref{text/modules}{text-exportdesc}{\T{exportdesc}} +.. |Telem| mathdef:: \xref{text/modules}{text-elem}{\T{elem}} +.. |Tcode| mathdef:: \xref{text/modules}{text-code}{\T{code}} +.. |Tlocal| mathdef:: \xref{text/modules}{text-local}{\T{local}} +.. |Tlocals| mathdef:: \xref{text/modules}{text-local}{\T{locals}} +.. |Tdata| mathdef:: \xref{text/modules}{text-data}{\T{data}} +.. |Tstart| mathdef:: \xref{text/modules}{text-start}{\T{start}} + + .. Modules, meta functions .. |funcs| mathdef:: \xref{syntax/types}{syntax-externtype}{\F{funcs}} @@ -353,3 +436,13 @@ .. |Binstr| mathdef:: \xref{binary/instructions}{binary-instr}{\B{instr}} .. |Bexpr| mathdef:: \xref{binary/instructions}{binary-expr}{\B{expr}} + + +.. Instructions, textual non-terminals + +.. |Tmemarg| mathdef:: \xref{text/instructions}{text-memarg}{\T{memarg}} +.. |Talign| mathdef:: \xref{text/instructions}{text-memarg}{\T{align}} +.. |Toffset| mathdef:: \xref{text/instructions}{text-memarg}{\T{offset}} + +.. |Tinstr| mathdef:: \xref{text/instructions}{text-instr}{\T{instr}} +.. |Texpr| mathdef:: \xref{text/instructions}{text-expr}{\T{expr}} diff --git a/document/text/conventions.rst b/document/text/conventions.rst new file mode 100644 index 0000000000..cb401930b4 --- /dev/null +++ b/document/text/conventions.rst @@ -0,0 +1,82 @@ +.. index:: ! text format + +Conventions +----------- + +The textual format for WebAssembly :ref:`modules ` is a rendering of their :ref:`abstract syntax ` into *S-expressions*. + +Like the :ref:`binary format `, the text format is defined by an *attribute grammar*. +A text string is a well-formed description of a module if and only if it is generated by the grammar. + +Each production of this grammar has exactly one synthesized attribute: the abstract syntax that the respective byte sequence encodes. +Thus, the attribute grammar implicitly defines a *parsing* function. + +Except for a few exceptions, the core of the text grammar closely mirrors the grammar of the abstract syntax. +However, it also defines a number of forms that are *syntactic sugar* over the core syntax. + + +.. _text-grammar: +.. index:: grammar notation, notation + single: text format; grammar + pair: text format; notation + +Grammar +~~~~~~~ + +The following conventions are adopted in defining grammar rules for the text format. +They mirror the conventions used for :ref:`abstract syntax ` and for the :ref:`binary format `. +In order to distinguish symbols of the textual syntax from symbols of the abstract syntax, typewriter font is adopted for the former. + +* Terminal symbols are strings given in quotes: :math:`\text{module}`. + +* Nonterminal symbols are written in typewriter font: :math:`\T{valtype}, \T{instr}`. + +* Arbitrary :ref:`white space ` is allowed in any place where the grammar contains spaces. + +* :math:`T^n` is a sequence of :math:`n\geq 0` iterations of :math:`T`. + +* :math:`T^\ast` is a possibly empty sequence of iterations of :math:`T`. + (This is a shorthand for :math:`T^n` used where :math:`n` is not relevant.) + +* :math:`T^?` is an optional occurrence of :math:`T`. + (This is a shorthand for :math:`T^n` where :math:`n \leq 1`.) + +* :math:`x{:}T` denotes the same language as the nonterminal :math:`T`, but also binds the variable :math:`x` to the attribute synthesized for :math:`T`. + +* Productions are written :math:`\T{name} ::= T \Rightarrow A`, where :math:`A` is the attribute that is synthesized for :math:`\T{name}`, usually from attribute variables bound in :math:`T`. + +* Some productions are augmented by side conditions in parentheses, which restrict the applicability of the production. They provide a shorthand for a combinatorial expansion of the production into many separate cases. + +.. note:: + For example, the :ref:`textual grammar ` for :ref:`value types ` is given as follows: + + .. math:: + \begin{array}{llcll@{\qquad\qquad}l} + \production{value types} & \Tvaltype &::=& + \text{i32} &\Rightarrow& \I32 \\ &&|& + \text{i64} &\Rightarrow& \I64 \\ &&|& + \text{f32} &\Rightarrow& \F32 \\ &&|& + \text{f64} &\Rightarrow& \F64 \\ + \end{array} + + The :ref:`textual grammar ` for :ref:`limits ` is defined as follows: + + .. math:: + \begin{array}{llclll} + \production{limits} & \Tlimits &::=& + n{:}\Tu32 &\Rightarrow& \{ \MIN~n, \MAX~\epsilon \} \\ &&|& + n{:}\Tu32~~m{:}\Tu32 &\Rightarrow& \{ \MIN~n, \MAX~m \} \\ + \end{array} + + The variables :math:`n` and :math:`m` name the attributes of the respective |Tu32| nonterminals, which in this case are the actual :ref:`unsigned integers ` they decode into. + The attribute of the complete production then is the abstract syntax for the limit, expressed in terms of the former values. + + +.. _binary-notation: + +Auxiliary Notation +~~~~~~~~~~~~~~~~~~ + +When dealing with binary encodings the following notation is also used: + +* :math:`\epsilon` denotes the empty byte sequence. diff --git a/document/text/index.rst b/document/text/index.rst new file mode 100644 index 0000000000..c0acfb8d43 --- /dev/null +++ b/document/text/index.rst @@ -0,0 +1,13 @@ +.. _text-format: + +Text Format +=========== + +.. toctree:: + :maxdepth: 2 + + conventions + values + types + instructions + modules diff --git a/document/text/instructions.rst b/document/text/instructions.rst new file mode 100644 index 0000000000..133678b3bd --- /dev/null +++ b/document/text/instructions.rst @@ -0,0 +1,371 @@ +.. _text-instr: +.. index:: instruction + +Instructions +------------ + +:ref:`Instructions ` are encoded by *opcodes*. +Each opcode is represented by a single byte, +and is followed by the instruction's immediate arguments, where present. +The only exception are :ref:`structured control instructions `, which consist of several opcodes bracketing their nested instruction sequences. + + +.. _text-instr-control: +.. index:: control instructions, structured control, label, block, branch, result type, label index, function index, type index, vector, polymorphism + pair: text format; instruction + single: abstract syntax; instruction + +Control Instructions +~~~~~~~~~~~~~~~~~~~~ + +:ref:`Control instructions ` have varying encodings. For structured instructions, the nested instruction sequences are terminated with explicit opcodes for |END| and |ELSE|. + +.. _text-nop: +.. _text-unreachable: +.. _text-block: +.. _text-loop: +.. _text-if: +.. _text-br: +.. _text-br_if: +.. _text-br_table: +.. _text-return: +.. _text-call: +.. _text-call_indirect: + +.. math:: + \begin{array}{llclll} + \production{instruction} & \Tinstr &::=& + \text{unreachable} &\Rightarrow& \UNREACHABLE \\ &&|& + \text{nop} &\Rightarrow& \NOP \\ &&|& + \text{block}~~\X{rt}{:}\Tblocktype~~(\X{in}{:}\Tinstr)^\ast~~\text{end} + &\Rightarrow& \BLOCK~\X{rt}~\X{in}^\ast~\END \\ &&|& + \text{loop}~~\X{rt}{:}\Tblocktype~~(\X{in}{:}\Tinstr)^\ast~~\text{end} + &\Rightarrow& \LOOP~\X{rt}~\X{in}^\ast~\END \\ &&|& + \text{if}~~\X{rt}{:}\Tblocktype~~(\X{in}{:}\Tinstr)^\ast~~\text{end} + &\Rightarrow& \IF~\X{rt}~\X{in}^\ast~\ELSE~\epsilon~\END \\ &&|& + \text{if}~~\X{rt}{:}\Tblocktype~~(\X{in}_1{:}\Tinstr)^\ast~~ + \text{else}~~(\X{in}_2{:}\Tinstr)^\ast~~\text{end} + &\Rightarrow& \IF~\X{rt}~\X{in}_1^\ast~\ELSE~\X{in}_2^\ast~\END \\ &&|& + \text{br}~~l{:}\Tlabelidx &\Rightarrow& \BR~l \\ &&|& + \text{br\_if}~~l{:}\Tlabelidx &\Rightarrow& \BRIF~l \\ &&|& + \text{br\_table}~~l^\ast{:}\Tvec(\Tlabelidx)~~l_N{:}\Tlabelidx + &\Rightarrow& \BRTABLE~l^\ast~l_N \\ &&|& + \text{return} &\Rightarrow& \RETURN \\ &&|& + \text{call}~~x{:}\Tfuncidx &\Rightarrow& \CALL~x \\ &&|& + \text{call\_indirect}~~x{:}\Ttypeidx &\Rightarrow& \CALLINDIRECT~x \\ + \end{array} + +.. note:: + The :math:`\text{else}` keyword an :math:`\text{if}` instruction can be omitted if the following instruction sequence is empty. + + +.. _text-instr-parametric: +.. index:: value type, polymorphism + pair: text format; instruction + single: abstract syntax; instruction + +Parametric Instructions +~~~~~~~~~~~~~~~~~~~~~~~ + +.. _text-drop: +.. _text-select: + +.. math:: + \begin{array}{llclll} + \production{instruction} & \Tinstr &::=& \dots \\ &&|& + \text{drop} &\Rightarrow& \DROP \\ &&|& + \text{select} &\Rightarrow& \SELECT \\ + \end{array} + + +.. _text-instr-variable: +.. index:: variable instructions, local index, global index + pair: text format; instruction + single: abstract syntax; instruction + +Variable Instructions +~~~~~~~~~~~~~~~~~~~~~ + +.. _text-get_local: +.. _text-set_local: +.. _text-tee_local: +.. _text-get_global: +.. _text-set_global: + +.. math:: + \begin{array}{llclll} + \production{instruction} & \Tinstr &::=& \dots \\ &&|& + \text{get\_local}~~x{:}\Tlocalidx &\Rightarrow& \GETLOCAL~x \\ &&|& + \text{set\_local}~~x{:}\Tlocalidx &\Rightarrow& \SETLOCAL~x \\ &&|& + \text{tee\_local}~~x{:}\Tlocalidx &\Rightarrow& \TEELOCAL~x \\ &&|& + \text{get\_global}~~x{:}\Tglobalidx &\Rightarrow& \GETGLOBAL~x \\ &&|& + \text{set\_global}~~x{:}\Tglobalidx &\Rightarrow& \SETGLOBAL~x \\ + \end{array} + + +.. _text-instr-memory: +.. _text-memarg: +.. index:: memory instruction, memory index + pair: text format; instruction + single: abstract syntax; instruction + +Memory Instructions +~~~~~~~~~~~~~~~~~~~ + +.. _text-memarg: +.. _text-load: +.. _text-loadn: +.. _text-store: +.. _text-storen: +.. _text-current_memory: +.. _text-grow_memory: + +.. math:: + \begin{array}{llclll} + \production{memory argument} & \Tmemarg_N &::=& + o{:}\Toffset~~a{:}\Talign_N &\Rightarrow& \{ \ALIGN~a,~\OFFSET~o \} \\ + \production{memory offset} & \Toffset &::=& + \text{offset{=}}o{:}\Tu32 &\Rightarrow& o \\ &&|& + \epsilon &\Rightarrow& 0 \\ + \production{memory alignment} & \Talign_N &::=& + \text{align{=}}a{:}\Tu32 &\Rightarrow& a \\ &&|& + \epsilon &\Rightarrow& N \\ + \production{instruction} & \Tinstr &::=& \dots \\ &&|& + \text{i32.load}~~m{:}\Tmemarg_4 &\Rightarrow& \I32.\LOAD~m \\ &&|& + \text{i64.load}~~m{:}\Tmemarg_8 &\Rightarrow& \I64.\LOAD~m \\ &&|& + \text{f32.load}~~m{:}\Tmemarg_4 &\Rightarrow& \F32.\LOAD~m \\ &&|& + \text{f64.load}~~m{:}\Tmemarg_8 &\Rightarrow& \F64.\LOAD~m \\ &&|& + \text{i32.load8\_s}~~m{:}\Tmemarg_1 &\Rightarrow& \I32.\LOAD\K{8\_s}~m \\ &&|& + \text{i32.load8\_u}~~m{:}\Tmemarg_1 &\Rightarrow& \I32.\LOAD\K{8\_u}~m \\ &&|& + \text{i32.load16\_s}~~m{:}\Tmemarg_2 &\Rightarrow& \I32.\LOAD\K{16\_s}~m \\ &&|& + \text{i32.load16\_u}~~m{:}\Tmemarg_2 &\Rightarrow& \I32.\LOAD\K{16\_u}~m \\ &&|& + \text{i64.load8\_s}~~m{:}\Tmemarg_1 &\Rightarrow& \I64.\LOAD\K{8\_s}~m \\ &&|& + \text{i64.load8\_u}~~m{:}\Tmemarg_1 &\Rightarrow& \I64.\LOAD\K{8\_u}~m \\ &&|& + \text{i64.load16\_s}~~m{:}\Tmemarg_2 &\Rightarrow& \I64.\LOAD\K{16\_s}~m \\ &&|& + \text{i64.load16\_u}~~m{:}\Tmemarg_2 &\Rightarrow& \I64.\LOAD\K{16\_u}~m \\ &&|& + \text{i64.load32\_s}~~m{:}\Tmemarg_4 &\Rightarrow& \I64.\LOAD\K{32\_s}~m \\ &&|& + \text{i64.load32\_u}~~m{:}\Tmemarg_4 &\Rightarrow& \I64.\LOAD\K{32\_u}~m \\ &&|& + \text{i32.store}~~m{:}\Tmemarg_4 &\Rightarrow& \I32.\STORE~m \\ &&|& + \text{i64.store}~~m{:}\Tmemarg_8 &\Rightarrow& \I64.\STORE~m \\ &&|& + \text{f32.store}~~m{:}\Tmemarg_4 &\Rightarrow& \F32.\STORE~m \\ &&|& + \text{f64.store}~~m{:}\Tmemarg_8 &\Rightarrow& \F64.\STORE~m \\ &&|& + \text{i32.store8}~~m{:}\Tmemarg_1 &\Rightarrow& \I32.\STORE\K{8}~m \\ &&|& + \text{i32.store16}~~m{:}\Tmemarg_2 &\Rightarrow& \I32.\STORE\K{16}~m \\ &&|& + \text{i64.store8}~~m{:}\Tmemarg_1 &\Rightarrow& \I64.\STORE\K{8}~m \\ &&|& + \text{i64.store16}~~m{:}\Tmemarg_2 &\Rightarrow& \I64.\STORE\K{16}~m \\ &&|& + \text{i64.store32}~~m{:}\Tmemarg_4 &\Rightarrow& \I64.\STORE\K{32}~m \\ &&|& + \text{current\_memory} &\Rightarrow& \CURRENTMEMORY \\ &&|& + \text{grow\_memory} &\Rightarrow& \GROWMEMORY \\ + \end{array} + + +.. _text-instr-numeric: +.. index:: numeric instruction + pair: text format; instruction + single: abstract syntax; instruction + +Numeric Instructions +~~~~~~~~~~~~~~~~~~~~ + +.. _text-const: + +.. math:: + \begin{array}{llclll} + \production{instruction} & \Tinstr &::=& \dots \\&&|& + \text{i32.const}~~n{:}\Ti32 &\Rightarrow& \I32.\CONST~n \\ &&|& + \text{i64.const}~~n{:}\Ti64 &\Rightarrow& \I64.\CONST~n \\ &&|& + \text{f32.const}~~z{:}\Tf32 &\Rightarrow& \F32.\CONST~z \\ &&|& + \text{f64.const}~~z{:}\Tf64 &\Rightarrow& \F64.\CONST~z \\ + \end{array} + +.. _text-unop: +.. _text-binop: + +.. math:: + \begin{array}{llclll} + \phantom{\production{instruction}} & \phantom{\Tinstr} &\phantom{::=}& \phantom{thisisenough} && \phantom{thisshouldbeenough} \\[-2ex] &&|& + \text{i32.clz} &\Rightarrow& \I32.\CLZ \\ &&|& + \text{i32.ctz} &\Rightarrow& \I32.\CTZ \\ &&|& + \text{i32.popcnt} &\Rightarrow& \I32.\POPCNT \\ &&|& + \text{i32.add} &\Rightarrow& \I32.\ADD \\ &&|& + \text{i32.sub} &\Rightarrow& \I32.\SUB \\ &&|& + \text{i32.mul} &\Rightarrow& \I32.\MUL \\ &&|& + \text{i32.div\_s} &\Rightarrow& \I32.\DIV\K{\_s} \\ &&|& + \text{i32.div\_u} &\Rightarrow& \I32.\DIV\K{\_u} \\ &&|& + \text{i32.rem\_s} &\Rightarrow& \I32.\REM\K{\_s} \\ &&|& + \text{i32.rem\_u} &\Rightarrow& \I32.\REM\K{\_u} \\ &&|& + \text{i32.and} &\Rightarrow& \I32.\AND \\ &&|& + \text{i32.or} &\Rightarrow& \I32.\OR \\ &&|& + \text{i32.xor} &\Rightarrow& \I32.\XOR \\ &&|& + \text{i32.shl} &\Rightarrow& \I32.\SHL \\ &&|& + \text{i32.shr\_s} &\Rightarrow& \I32.\SHR\K{\_s} \\ &&|& + \text{i32.shr\_u} &\Rightarrow& \I32.\SHR\K{\_u} \\ &&|& + \text{i32.rotl} &\Rightarrow& \I32.\ROTL \\ &&|& + \text{i32.rotr} &\Rightarrow& \I32.\ROTR \\ + \end{array} + +.. math:: + \begin{array}{llclll} + \phantom{\production{instruction}} & \phantom{\Tinstr} &\phantom{::=}& \phantom{thisisenough} && \phantom{thisshouldbeenough} \\[-2ex] &&|& + \text{i64.clz} &\Rightarrow& \I64.\CLZ \\ &&|& + \text{i64.ctz} &\Rightarrow& \I64.\CTZ \\ &&|& + \text{i64.popcnt} &\Rightarrow& \I64.\POPCNT \\ &&|& + \text{i64.add} &\Rightarrow& \I64.\ADD \\ &&|& + \text{i64.sub} &\Rightarrow& \I64.\SUB \\ &&|& + \text{i64.mul} &\Rightarrow& \I64.\MUL \\ &&|& + \text{i64.div\_s} &\Rightarrow& \I64.\DIV\K{\_s} \\ &&|& + \text{i64.div\_u} &\Rightarrow& \I64.\DIV\K{\_u} \\ &&|& + \text{i64.rem\_s} &\Rightarrow& \I64.\REM\K{\_s} \\ &&|& + \text{i64.rem\_u} &\Rightarrow& \I64.\REM\K{\_u} \\ &&|& + \text{i64.and} &\Rightarrow& \I64.\AND \\ &&|& + \text{i64.or} &\Rightarrow& \I64.\OR \\ &&|& + \text{i64.xor} &\Rightarrow& \I64.\XOR \\ &&|& + \text{i64.shl} &\Rightarrow& \I64.\SHL \\ &&|& + \text{i64.shr\_s} &\Rightarrow& \I64.\SHR\K{\_s} \\ &&|& + \text{i64.shr\_u} &\Rightarrow& \I64.\SHR\K{\_u} \\ &&|& + \text{i64.rotl} &\Rightarrow& \I64.\ROTL \\ &&|& + \text{i64.rotr} &\Rightarrow& \I64.\ROTR \\ + \end{array} + +.. math:: + \begin{array}{llclll} + \phantom{\production{instruction}} & \phantom{\Tinstr} &\phantom{::=}& \phantom{thisisenough} && \phantom{thisshouldbeenough} \\[-2ex] &&|& + \text{f32.abs} &\Rightarrow& \F32.\ABS \\ &&|& + \text{f32.neg} &\Rightarrow& \F32.\NEG \\ &&|& + \text{f32.ceil} &\Rightarrow& \F32.\CEIL \\ &&|& + \text{f32.floor} &\Rightarrow& \F32.\FLOOR \\ &&|& + \text{f32.trunc} &\Rightarrow& \F32.\TRUNC \\ &&|& + \text{f32.nearest} &\Rightarrow& \F32.\NEAREST \\ &&|& + \text{f32.sqrt} &\Rightarrow& \F32.\SQRT \\ &&|& + \text{f32.add} &\Rightarrow& \F32.\ADD \\ &&|& + \text{f32.sub} &\Rightarrow& \F32.\SUB \\ &&|& + \text{f32.mul} &\Rightarrow& \F32.\MUL \\ &&|& + \text{f32.div} &\Rightarrow& \F32.\DIV \\ &&|& + \text{f32.min} &\Rightarrow& \F32.\FMIN \\ &&|& + \text{f32.max} &\Rightarrow& \F32.\FMAX \\ &&|& + \text{f32.copysign} &\Rightarrow& \F32.\COPYSIGN \\ + \end{array} + +.. math:: + \begin{array}{llclll} + \phantom{\production{instruction}} & \phantom{\Tinstr} &\phantom{::=}& \phantom{thisisenough} && \phantom{thisshouldbeenough} \\[-2ex] &&|& + \text{f64.abs} &\Rightarrow& \F64.\ABS \\ &&|& + \text{f64.neg} &\Rightarrow& \F64.\NEG \\ &&|& + \text{f64.ceil} &\Rightarrow& \F64.\CEIL \\ &&|& + \text{f64.floor} &\Rightarrow& \F64.\FLOOR \\ &&|& + \text{f64.trunc} &\Rightarrow& \F64.\TRUNC \\ &&|& + \text{f64.nearest} &\Rightarrow& \F64.\NEAREST \\ &&|& + \text{f64.sqrt} &\Rightarrow& \F64.\SQRT \\ &&|& + \text{f64.add} &\Rightarrow& \F64.\ADD \\ &&|& + \text{f64.sub} &\Rightarrow& \F64.\SUB \\ &&|& + \text{f64.mul} &\Rightarrow& \F64.\MUL \\ &&|& + \text{f64.div} &\Rightarrow& \F64.\DIV \\ &&|& + \text{f64.min} &\Rightarrow& \F64.\FMIN \\ &&|& + \text{f64.max} &\Rightarrow& \F64.\FMAX \\ &&|& + \text{f64.copysign} &\Rightarrow& \F64.\COPYSIGN \\ + \end{array} + +.. _text-testop: +.. _text-relop: + +.. math:: + \begin{array}{llclll} + \phantom{\production{instruction}} & \phantom{\Tinstr} &\phantom{::=}& \phantom{thisisenough} && \phantom{thisshouldbeenough} \\[-2ex] &&|& + \text{i32.eqz} &\Rightarrow& \I32.\EQZ \\ &&|& + \text{i32.eq} &\Rightarrow& \I32.\EQ \\ &&|& + \text{i32.ne} &\Rightarrow& \I32.\NE \\ &&|& + \text{i32.lt\_s} &\Rightarrow& \I32.\LT\K{\_s} \\ &&|& + \text{i32.lt\_u} &\Rightarrow& \I32.\LT\K{\_u} \\ &&|& + \text{i32.gt\_s} &\Rightarrow& \I32.\GT\K{\_s} \\ &&|& + \text{i32.gt\_u} &\Rightarrow& \I32.\GT\K{\_u} \\ &&|& + \text{i32.le\_s} &\Rightarrow& \I32.\LE\K{\_s} \\ &&|& + \text{i32.le\_u} &\Rightarrow& \I32.\LE\K{\_u} \\ &&|& + \text{i32.ge\_s} &\Rightarrow& \I32.\GE\K{\_s} \\ &&|& + \text{i32.ge\_u} &\Rightarrow& \I32.\GE\K{\_u} \\ + \end{array} + +.. math:: + \begin{array}{llclll} + \phantom{\production{instruction}} & \phantom{\Tinstr} &\phantom{::=}& \phantom{thisisenough} && \phantom{thisshouldbeenough} \\[-2ex] &&|& + \text{i64.eqz} &\Rightarrow& \I64.\EQZ \\ &&|& + \text{i64.eq} &\Rightarrow& \I64.\EQ \\ &&|& + \text{i64.ne} &\Rightarrow& \I64.\NE \\ &&|& + \text{i64.lt\_s} &\Rightarrow& \I64.\LT\K{\_s} \\ &&|& + \text{i64.lt\_u} &\Rightarrow& \I64.\LT\K{\_u} \\ &&|& + \text{i64.gt\_s} &\Rightarrow& \I64.\GT\K{\_s} \\ &&|& + \text{i64.gt\_u} &\Rightarrow& \I64.\GT\K{\_u} \\ &&|& + \text{i64.le\_s} &\Rightarrow& \I64.\LE\K{\_s} \\ &&|& + \text{i64.le\_u} &\Rightarrow& \I64.\LE\K{\_u} \\ &&|& + \text{i64.ge\_s} &\Rightarrow& \I64.\GE\K{\_s} \\ &&|& + \text{i64.ge\_u} &\Rightarrow& \I64.\GE\K{\_u} \\ + \end{array} + +.. math:: + \begin{array}{llclll} + \phantom{\production{instruction}} & \phantom{\Tinstr} &\phantom{::=}& \phantom{thisisenough} && \phantom{thisshouldbeenough} \\[-2ex] &&|& + \text{f32.eq} &\Rightarrow& \F32.\EQ \\ &&|& + \text{f32.ne} &\Rightarrow& \F32.\NE \\ &&|& + \text{f32.lt} &\Rightarrow& \F32.\LT \\ &&|& + \text{f32.gt} &\Rightarrow& \F32.\GT \\ &&|& + \text{f32.le} &\Rightarrow& \F32.\LE \\ &&|& + \text{f32.ge} &\Rightarrow& \F32.\GE \\ + \end{array} + +.. math:: + \begin{array}{llclll} + \phantom{\production{instruction}} & \phantom{\Tinstr} &\phantom{::=}& \phantom{thisisenough} && \phantom{thisshouldbeenough} \\[-2ex] &&|& + \text{f64.eq} &\Rightarrow& \F64.\EQ \\ &&|& + \text{f64.ne} &\Rightarrow& \F64.\NE \\ &&|& + \text{f64.lt} &\Rightarrow& \F64.\LT \\ &&|& + \text{f64.gt} &\Rightarrow& \F64.\GT \\ &&|& + \text{f64.le} &\Rightarrow& \F64.\LE \\ &&|& + \text{f64.ge} &\Rightarrow& \F64.\GE \\ + \end{array} + +.. _text-cvtop: + +.. math:: + \begin{array}{llclll} + \phantom{\production{instruction}} & \phantom{\Tinstr} &\phantom{::=}& \phantom{thisisenough} && \phantom{thisshouldbeenough} \\[-2ex] &&|& + \text{i32.wrap/i64} &\Rightarrow& \I32.\WRAP\K{/}\I64 \\ &&|& + \text{i32.trunc\_s/f32} &\Rightarrow& \I32.\TRUNC\K{\_s/}\F32 \\ &&|& + \text{i32.trunc\_u/f32} &\Rightarrow& \I32.\TRUNC\K{\_u/}\F32 \\ &&|& + \text{i32.trunc\_s/f64} &\Rightarrow& \I32.\TRUNC\K{\_s/}\F64 \\ &&|& + \text{i32.trunc\_u/f64} &\Rightarrow& \I32.\TRUNC\K{\_u/}\F64 \\ &&|& + \text{i64.extend\_s/i32} &\Rightarrow& \I64.\EXTEND\K{\_s/}\I32 \\ &&|& + \text{i64.extend\_u/i32} &\Rightarrow& \I64.\EXTEND\K{\_u/}\I32 \\ &&|& + \text{i64.trunc\_s/f32} &\Rightarrow& \I64.\TRUNC\K{\_s/}\F32 \\ &&|& + \text{i64.trunc\_u/f32} &\Rightarrow& \I64.\TRUNC\K{\_u/}\F32 \\ &&|& + \text{i64.trunc\_s/f64} &\Rightarrow& \I64.\TRUNC\K{\_s/}\F64 \\ &&|& + \text{i64.trunc\_u/f64} &\Rightarrow& \I64.\TRUNC\K{\_u/}\F64 \\ &&|& + \text{f32.convert\_s/i32} &\Rightarrow& \F32.\CONVERT\K{\_s/}\I32 \\ &&|& + \text{f32.convert\_u/i32} &\Rightarrow& \F32.\CONVERT\K{\_u/}\I32 \\ &&|& + \text{f32.convert\_s/i64} &\Rightarrow& \F32.\CONVERT\K{\_s/}\I64 \\ &&|& + \text{f32.convert\_u/i64} &\Rightarrow& \F32.\CONVERT\K{\_u/}\I64 \\ &&|& + \text{f32.demote/f64} &\Rightarrow& \F32.\DEMOTE\K{/}\F64 \\ &&|& + \text{f64.convert\_s/i32} &\Rightarrow& \F64.\CONVERT\K{\_s/}\I32 \\ &&|& + \text{f64.convert\_u/i32} &\Rightarrow& \F64.\CONVERT\K{\_u/}\I32 \\ &&|& + \text{f64.convert\_s/i64} &\Rightarrow& \F64.\CONVERT\K{\_s/}\I64 \\ &&|& + \text{f64.convert\_u/i64} &\Rightarrow& \F64.\CONVERT\K{\_u/}\I64 \\ &&|& + \text{f64.demote/f32} &\Rightarrow& \F64.\PROMOTE\K{/}\F32 \\ &&|& + \text{i32.reinterpret/f32} &\Rightarrow& \I32.\REINTERPRET\K{/}\F32 \\ &&|& + \text{i64.reinterpret/f64} &\Rightarrow& \I64.\REINTERPRET\K{/}\F64 \\ &&|& + \text{f32.reinterpret/i32} &\Rightarrow& \F32.\REINTERPRET\K{/}\I32 \\ &&|& + \text{f64.reinterpret/i64} &\Rightarrow& \F64.\REINTERPRET\K{/}\I64 \\ + \end{array} + + +.. _text-expr: +.. index:: expression + pair: text format; expression + single: abstract syntax; expression + single: expression; constant + +Expressions +~~~~~~~~~~~ + +.. math:: + \begin{array}{llclll} + \production{expression} & \Texpr &::=& + (\X{in}{:}\Tinstr)^\ast &\Rightarrow& \X{in}^\ast~\END \\ + \end{array} diff --git a/document/text/modules.rst b/document/text/modules.rst new file mode 100644 index 0000000000..4431f17841 --- /dev/null +++ b/document/text/modules.rst @@ -0,0 +1,477 @@ +Modules +------- + +The binary encoding of modules is organized into *sections*. +Most sections correspond to one component of a :ref:`module ` record, +except that :ref:`function definitions ` are split into two sections, separating their type declarations in the :ref:`function section ` from their bodies in the :ref:`code section `. + +.. note:: + This separation enables *parallel* and *streaming* compilation of the functions in a module. + + +.. _binary-index: +.. _binary-typeidx: +.. _binary-funcidx: +.. _binary-tableidx: +.. _binary-memidx: +.. _binary-globalidx: +.. _binary-localidx: +.. _binary-labelidx: +.. index:: index, index space, type index, function index, table index, memory index, global index, local index, label index + pair: binary format; type index + pair: binary format; function index + pair: binary format; table index + pair: binary format; memory index + pair: binary format; global index + pair: binary format; local index + pair: binary format; label index + single: abstract syntax; type index + single: abstract syntax; function index + single: abstract syntax; table index + single: abstract syntax; memory index + single: abstract syntax; global index + single: abstract syntax; local index + single: abstract syntax; label index + +Indices +~~~~~~~ + +All :ref:`indices ` are encoded with their respective |U32| value. + +.. math:: + \begin{array}{llclll} + \production{type indices} & \Btypeidx &::=& x{:}\Bu32 &\Rightarrow& x \\ + \production{function indices} & \Bfuncidx &::=& x{:}\Bu32 &\Rightarrow& x \\ + \production{table indices} & \Btableidx &::=& x{:}\Bu32 &\Rightarrow& x \\ + \production{memory indices} & \Bmemidx &::=& x{:}\Bu32 &\Rightarrow& x \\ + \production{global indices} & \Bglobalidx &::=& x{:}\Bu32 &\Rightarrow& x \\ + \production{local indices} & \Blocalidx &::=& x{:}\Bu32 &\Rightarrow& x \\ + \production{label indices} & \Blabelidx &::=& l{:}\Bu32 &\Rightarrow& l \\ + \end{array} + + +.. _binary-section: +.. index:: ! section + pair: binary format; section + +Sections +~~~~~~~~ + +Each section consists of + +* a one-byte section *id*, +* the |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 :math:`N` and contents described by the grammar :math:`\B{B}`. + +.. math:: + \begin{array}{llclll@{\qquad}l} + \production{sections} & \Bsection_N(\B{B}) &::=& + N{:}\Bbyte~~\X{size}{:}\Bu32~~\X{cont}{:}\B{B} + &\Rightarrow& \X{cont} & (\X{size} = ||\B{B}||) \\ &&|& + \epsilon &\Rightarrow& \epsilon + \end{array} + +For most sections, the contents :math:`\B{B}` encodes a :ref:`vector `. +In these cases, the empty result :math:`\epsilon` is interpreted as the empty vector. + +.. note:: + Other than for unknown :ref:`custom sections `, + the :math:`\X{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 :math:`\B{B}`. + + +.. _binary-customsec: +.. index:: ! custom section + pair: binary format; custom section + single: section; custom + +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 :ref:`name ` further identifying the custom section, followed by an uninterpreted sequence of bytes for custom use. + +.. math:: + \begin{array}{llclll} + \production{custom sections} & \Bcustomsec &::=& + \Bsection_0(\Bcustom) \\ + \production{custom data} & \Bcustom &::=& + \Bname~~\Bbyte^\ast \\ + \end{array} + +.. note:: + If an implementation interprets the contents of a custom section, then errors in that contents, or the placement of the section, must not invalidate the module. + + +.. _binary-typesec: +.. _binary-type: +.. index:: ! type section, type definition + pair: binary format; type section + single: abstract syntax; type definition + pair: section; type + +Type Section +~~~~~~~~~~~~ + +The *type section* has the id 1. +It decodes into a vector of :ref:`function types ` that represent the |TYPES| component of a :ref:`module `. + +.. math:: + \begin{array}{llclll} + \production{type sections} & \Btypesec &::=& + \X{ft}^\ast{:\,}\Bsection_1(\Bvec(\Bfunctype)) &\Rightarrow& \X{ft}^\ast \\ + \end{array} + + +.. _binary-importsec: +.. _binary-import: +.. index:: ! import section, import, name, function type, table type, memory type, global type + pair: binary format; import + single: abstract syntax; import + pair: section; import + +Import Section +~~~~~~~~~~~~~~ + +The *import section* has the id 2. +It decodes into a vector of :ref:`imports ` that represent the |IMPORTS| component of a :ref:`module `. + +.. math:: + \begin{array}{llclll} + \production{import sections} & \Bimportsec &::=& + \X{im}^\ast{:}\Bsection_2(\Bvec(\Bimport)) &\Rightarrow& \X{im}^\ast \\ + \production{imports} & \Bimport &::=& + \X{mod}{:}\Bname~~\X{nm}{:}\Bname~~d{:}\Bimportdesc + &\Rightarrow& \{ \MODULE~\X{mod}, \NAME~\X{nm}, \DESC~d \} \\ + \production{import descriptions} & \Bimportdesc &::=& + \hex{00}~~x{:}\Btypeidx &\Rightarrow& \FUNC~x \\ &&|& + \hex{01}~~\X{tt}{:}\Btabletype &\Rightarrow& \TABLE~\X{tt} \\ &&|& + \hex{02}~~\X{mt}{:}\Bmemtype &\Rightarrow& \MEM~\X{mt} \\ &&|& + \hex{03}~~\X{gt}{:}\Bglobaltype &\Rightarrow& \GLOBAL~\X{gt} \\ + \end{array} + + +.. _binary-funcsec: +.. _binary-func: +.. index:: ! function section, function, type index, function type + pair: binary format; function + single: abstract syntax; function + pair: section; function + +Function Section +~~~~~~~~~~~~~~~~ + +The *function section* has the id 3. +It decodes into a vector of :ref:`type indices ` that represent the |TYPE| fields of the :ref:`functions ` in the |FUNCS| component of a :ref:`module `. +The |LOCALS| and |BODY| fields of the respective functions are encoded separately in the :ref:`code section `. + +.. math:: + \begin{array}{llclll} + \production{function sections} & \Bfuncsec &::=& + x^\ast{:}\Bsection_3(\Bvec(\Btypeidx)) &\Rightarrow& x^\ast \\ + \end{array} + + +.. _binary-tablesec: +.. _binary-table: +.. index:: ! table section, table, table type + pair: binary format; table + single: abstract syntax; table + pair: section; table + +Table Section +~~~~~~~~~~~~~ + +The *table section* has the id 4. +It decodes into a vector of :ref:`tables ` that represent the |TABLES| component of a :ref:`module `. + +.. math:: + \begin{array}{llclll} + \production{table sections} & \Btablesec &::=& + \X{tab}^\ast{:}\Bsection_4(\Bvec(\Btable)) &\Rightarrow& \X{tab}^\ast \\ + \production{tables} & \Btable &::=& + \X{tt}{:}\Btabletype &\Rightarrow& \{ \TYPE~\X{tt} \} \\ + \end{array} + + +.. _binary-memsec: +.. _binary-mem: +.. index:: ! memory section, memory, memory type + pair: binary format; memory + single: abstract syntax; memory + pair: section; memory + +Memory Section +~~~~~~~~~~~~~~ + +The *memory section* has the id 5. +It decodes into a vector of :ref:`memories ` that represent the |MEMS| component of a :ref:`module `. + +.. math:: + \begin{array}{llclll} + \production{memory sections} & \Bmemsec &::=& + \X{mem}^\ast{:}\Bsection_5(\Bvec(\Bmem)) &\Rightarrow& \X{mem}^\ast \\ + \production{memories} & \Bmem &::=& + \X{mt}{:}\Bmemtype &\Rightarrow& \{ \TYPE~\X{mt} \} \\ + \end{array} + + +.. _binary-globalsec: +.. _binary-global: +.. index:: ! global section, global, global type, expression + pair: binary format; global + single: abstract syntax; global + pair: section; global + +Global Section +~~~~~~~~~~~~~~ + +The *global section* has the id 6. +It decodes into a vector of :ref:`globals ` that represent the |GLOBALS| component of a :ref:`module `. + +.. math:: + \begin{array}{llclll} + \production{global sections} & \Bglobalsec &::=& + \X{glob}^\ast{:}\Bsection_6(\Bvec(\Bglobal)) &\Rightarrow& \X{glob}^\ast \\ + \production{globals} & \Bglobal &::=& + \X{gt}{:}\Bglobaltype~~e{:}\Bexpr + &\Rightarrow& \{ \TYPE~\X{gt}, \INIT~e \} \\ + \end{array} + + +.. _binary-exportsec: +.. _binary-export: +.. index:: ! export section, export, name, index, function index, table index, memory index, global index + pair: binary format; export + single: abstract syntax; export + pair: section; export + +Export Section +~~~~~~~~~~~~~~ + +The *export section* has the id 7. +It decodes into a vector of :ref:`exports ` that represent the |EXPORTS| component of a :ref:`module `. + +.. math:: + \begin{array}{llclll} + \production{export sections} & \Bexportsec &::=& + \X{ex}^\ast{:}\Bsection_7(\Bvec(\Bexport)) &\Rightarrow& \X{ex}^\ast \\ + \production{exports} & \Bexport &::=& + \X{nm}{:}\Bname~~d{:}\Bexportdesc + &\Rightarrow& \{ \NAME~\X{nm}, \DESC~d \} \\ + \production{export descriptions} & \Bexportdesc &::=& + \hex{00}~~x{:}\Bfuncidx &\Rightarrow& \FUNC~x \\ &&|& + \hex{01}~~x{:}\Btableidx &\Rightarrow& \TABLE~x \\ &&|& + \hex{02}~~x{:}\Bmemidx &\Rightarrow& \MEM~x \\ &&|& + \hex{03}~~x{:}\Bglobalidx &\Rightarrow& \GLOBAL~x \\ + \end{array} + + +.. _binary-startsec: +.. _binary-start: +.. index:: ! start section, start function, function index + pair: binary format; start function + single: abstract syntax; start function + single: section; start + single: start function; section + +Start Section +~~~~~~~~~~~~~ + +The *start section* has the id 8. +It decodes into an optional :ref:`start function ` that represents the |START| component of a :ref:`module `. + +.. math:: + \begin{array}{llclll} + \production{start sections} & \Bstartsec &::=& + \X{st}^?{:}\Bsection_8(\Bstart) &\Rightarrow& \X{st}^? \\ + \production{start functions} & \Bstart &::=& + x{:}\Bfuncidx &\Rightarrow& \{ \FUNC~x \} \\ + \end{array} + + +.. _binary-elemsec: +.. _binary-elem: +.. index:: ! element section, element, table index, expression, function index + pair: binary format; element + single: abstract syntax; element + pair: section; element + single: table; element + single: element; segment + +Element Section +~~~~~~~~~~~~~~~ + +The *element section* has the id 9. +It decodes into a vector of :ref:`element segments ` that represent the |ELEM| component of a :ref:`module `. + +.. math:: + \begin{array}{llclll} + \production{element sections} & \Belemsec &::=& + \X{seg}^\ast{:}\Bsection_9(\Bvec(\Belem)) &\Rightarrow& \X{seg} \\ + \production{element segments} & \Belem &::=& + x{:}\Btableidx~~e{:}\Bexpr~~y^\ast{:}\Bvec(\Bfuncidx) + &\Rightarrow& \{ \TABLE~x, \OFFSET~e, \INIT~y^\ast \} \\ + \end{array} + + +.. _binary-codesec: +.. _binary-local: +.. index:: ! code section, function, local, type index, function type + pair: binary format; function + single: abstract syntax; function + pair: section; code + +Code Section +~~~~~~~~~~~~ + +The *code section* has the id 10. +It decodes into a vector of *code* entries that are pairs of :ref:`value type ` vectors and :ref:`expressions `. +They represent the |LOCALS| and |BODY| field of the :ref:`functions ` in the |FUNCS| component of a :ref:`module `. +The |TYPE| fields of the respective functions are encoded separately in the :ref:`function section `. + +The encoding of each code entry consists of + +* the |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 :ref:`expression `. + +Local declarations are compressed into a vector whose entries consist of + +* a |U32| *count*, +* a :ref:`value type `, + +denoting *count* locals of the same value type. + +.. math:: + \begin{array}{llclll@{\qquad}l} + \production{code sections} & \Bcodesec &::=& + \X{code}^\ast{:}\Bsection_{10}(\Bvec(\Bcode)) + &\Rightarrow& \X{code}^\ast \\ + \production{code} & \Bcode &::=& + \X{size}{:}\Bu32~~\X{code}{:}\Bfunc + &\Rightarrow& \X{code} & (\X{size} = ||\Bfunc||) \\ + \production{functions} & \Bfunc &::=& + (t^\ast)^\ast{:}\Bvec(\Blocals)~~e{:}\Bexpr + &\Rightarrow& \F{concat}((t^\ast)^\ast), e^\ast + & (|\F{concat}((t^\ast)^\ast)| < 2^{32}) \\ + \production{locals} & \Blocals &::=& + n{:}\Bu32~~t{:}\Bvaltype &\Rightarrow& t^n \\ + \end{array} + +Here, :math:`\X{code}` ranges over pairs :math:`(\valtype^\ast, \expr)`. +The meta function :math:`\F{concat}((t^\ast)^\ast)` denotes the sequence of types formed by concatenating all sequences :math:`t_i^\ast` in :math:`(t^\ast)^\ast`. +Any code for which the length of the resulting sequence is out of bounds of the maximum size of a :ref:`vector ` is malformed. + +.. note:: + The :math:`\X{size}` is not needed for decoding, but like with :ref:`sections `, 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. + + +.. _binary-datasec: +.. _binary-data: +.. index:: ! data section, data, memory, memory index, expression, byte + pair: binary format; data + single: abstract syntax; data + pair: section; data + single: memory; data + single: data; segment + +Data Section +~~~~~~~~~~~~ + +The *data section* has the id 11. +It decodes into a vector of :ref:`data segments ` that represent the |DATA| component of a :ref:`module `. + +.. math:: + \begin{array}{llclll} + \production{data sections} & \Bdatasec &::=& + \X{seg}^\ast{:}\Bsection_{11}(\Bvec(\Bdata)) &\Rightarrow& \X{seg} \\ + \production{data segments} & \Bdata &::=& + x{:}\Bmemidx~~e{:}\Bexpr~~b^\ast{:}\Bvec(\Bbyte) + &\Rightarrow& \{ \MEM~x, \OFFSET~e, \INIT~b^\ast \} \\ + \end{array} + + +.. _binary-module: +.. _binary-magic: +.. _binary-version: +.. index:: module, section, type definition, function type, function, table, memory, global, element, data, start function, import, export, context, version + pair: binary format; module + single: abstract syntax; module + +Modules +~~~~~~~ + +The encoding of a :ref:`module ` starts with a preamble containing a 4-byte magic number and a version field. +The current version of the WebAssembly binary format is 1. + +The preamble is followed by a sequence of :ref:`sections `. +:ref:`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) :ref:`function ` and :ref:`code ` section must match up. + +.. math:: + \begin{array}{llcllll} + \production{magic} & \Bmagic &::=& + \hex{00}~\hex{61}~\hex{73}~\hex{6D} \\ + \production{version} & \Bversion &::=& + \hex{01}~\hex{00}~\hex{00}~\hex{00} \\ + \production{modules} & \Bmodule &::=& + \Bmagic \\ &&& + \Bversion \\ &&& + \Bcustomsec^\ast \\ &&& + \functype^\ast{:\,}\Btypesec \\ &&& + \Bcustomsec^\ast \\ &&& + \import^\ast{:\,}\Bimportsec \\ &&& + \Bcustomsec^\ast \\ &&& + \typeidx^n{:\,}\Bfuncsec \\ &&& + \Bcustomsec^\ast \\ &&& + \table^\ast{:\,}\Btablesec \\ &&& + \Bcustomsec^\ast \\ &&& + \mem^\ast{:\,}\Bmemsec \\ &&& + \Bcustomsec^\ast \\ &&& + \global^\ast{:\,}\Bglobalsec \\ &&& + \Bcustomsec^\ast \\ &&& + \export^\ast{:\,}\Bexportsec \\ &&& + \Bcustomsec^\ast \\ &&& + \start^?{:\,}\Bstartsec \\ &&& + \Bcustomsec^\ast \\ &&& + \elem^\ast{:\,}\Belemsec \\ &&& + \Bcustomsec^\ast \\ &&& + \X{code}^n{:\,}\Bcodesec \\ &&& + \Bcustomsec^\ast \\ &&& + \data^\ast{:\,}\Bdatasec \\ &&& + \Bcustomsec^\ast + &\Rightarrow& \{~ + \begin{array}[t]{@{}l@{}} + \TYPES~\functype^\ast, \\ + \FUNCS~\func^n, \\ + \TABLES~\table^\ast, \\ + \MEMS~\mem^\ast, \\ + \GLOBALS~\global^\ast, \\ + \ELEM~\elem^\ast, \\ + \DATA~\data^\ast, \\ + \START~\start^?, \\ + \IMPORTS~\import^\ast, \\ + \EXPORTS~\export^\ast ~\} \\ + \end{array} \\ + \end{array} + +where for each :math:`(t_i^\ast, e_i)` in :math:`\X{code}^n`, +:math:`\func^n[i] = \{ \TYPE~\typeidx^n[i], \LOCALS~t_i^\ast, \BODY~e_i \}`. + +.. note:: + The version of the WebAssembly binary format may increase in the future + if backward-incompatible changes are 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. diff --git a/document/text/types.rst b/document/text/types.rst new file mode 100644 index 0000000000..04a6651731 --- /dev/null +++ b/document/text/types.rst @@ -0,0 +1,133 @@ +.. _text-type: +.. index:: type + pair: text format; type + single: abstract syntax; type + +Types +----- + +.. _text-valtype: +.. index:: value type + pair: text format; value type + single: abstract syntax; value type + +Value Types +~~~~~~~~~~~ + +.. math:: + \begin{array}{llcll@{\qquad\qquad}l} + \production{value type} & \Tvaltype &::=& + \text{i32} &\Rightarrow& \I32 \\ &&|& + \text{i64} &\Rightarrow& \I64 \\ &&|& + \text{f32} &\Rightarrow& \F32 \\ &&|& + \text{f64} &\Rightarrow& \F64 \\ + \end{array} + + +.. _text-resulttype: +.. index:: result type, value type + pair: text format; result type + single: abstract syntax; result type + +Block Types +~~~~~~~~~~~ + +.. math:: + \begin{array}{llclll@{\qquad\qquad}l} + \production{result type} & \Tblocktype &::=& + (t{:}\Tresult)^? &\Rightarrow& [t^?] \\ + \end{array} + +.. note:: + In future versions of WebAssembly, this scheme may be extended to support multiple results or more general block types. + + +.. _text-functype: +.. index:: function type, value type, result type + pair: text format; function type + single: abstract syntax; function type + +Function Types +~~~~~~~~~~~~~~ + +.. math:: + \begin{array}{llclll@{\qquad\qquad}l} + \production{function type} & \Tfunctype &::=& + \text{(}~\text{func}~~t_1^\ast{:\,}\Tvec(\Tparam)~~t_2^\ast{:\,}\Tvec(\Tresult)~\text{)} + &\Rightarrow& [t_1^\ast] \to [t_2^\ast] \\ + \production{parameter} & \Tparam &::=& + \text{(}~\text{param}~~t{:}\Tvaltype~\text{)} + &\Rightarrow& t \\ + \production{result} & \Tresult &::=& + \text{(}~\text{result}~~t{:}\Tvaltype~\text{)} + &\Rightarrow& t \\ + \end{array} + + +.. _text-limits: +.. index:: limits + pair: text format; limits + single: abstract syntax; limits + +Limits +~~~~~~ + +.. math:: + \begin{array}{llclll} + \production{limits} & \Tlimits &::=& + n{:}\Tu32 &\Rightarrow& \{ \MIN~n, \MAX~\epsilon \} \\ &&|& + n{:}\Tu32~~m{:}\Tu32 &\Rightarrow& \{ \MIN~n, \MAX~m \} \\ + \end{array} + + +.. _text-memtype: +.. index:: memory type, limits, page size + single: text format; memory type + pair: abstract syntax; memory type + +Memory Types +~~~~~~~~~~~~ + +.. math:: + \begin{array}{llclll@{\qquad\qquad}l} + \production{memory type} & \Tmemtype &::=& + \X{lim}{:}\Tlimits &\Rightarrow& \X{lim} \\ + \end{array} + + +.. _text-tabletype: +.. _text-elemtype: +.. index:: table type, element type, limits + pair: text format; table type + pair: text format; element type + single: abstract syntax; table type + single: abstract syntax; element type + +Table Types +~~~~~~~~~~~ + +.. math:: + \begin{array}{llclll} + \production{table type} & \Ttabletype &::=& + \X{lim}{:}\Tlimits~~\X{et}{:}\Telemtype &\Rightarrow& \X{lim}~\X{et} \\ + \production{element type} & \Telemtype &::=& + \text{anyfunc} &\Rightarrow& \ANYFUNC \\ + \end{array} + + +.. _text-globaltype: +.. index:: global type, mutability, value type + pair: text format; global type + pair: text format; mutability + single: abstract syntax; global type + single: abstract syntax; mutability + +Global Types +~~~~~~~~~~~~ + +.. math:: + \begin{array}{llclll} + \production{global type} & \Tglobaltype &::=& + t{:}\Tvaltype &\Rightarrow& \CONST~t \\ &&|& + \text{(}~\text{mut}~~t{:}\Tvaltype~\text{)} &\Rightarrow& \VAR~t \\ + \end{array} diff --git a/document/text/values.rst b/document/text/values.rst new file mode 100644 index 0000000000..eb81d81c87 --- /dev/null +++ b/document/text/values.rst @@ -0,0 +1,168 @@ +.. _text-value: +.. index:: value + pair: text format; value + single: abstract syntax; value + +Values +------ + + +.. text-byte: +.. index:: byte + pair: text format; byte + single: abstract syntax; byte + +Bytes +~~~~~ + +.. todo:: needed? + +:ref:`Bytes ` encode themselves. + +.. math:: + \begin{array}{llcll@{\qquad}l} + \production{bytes} & \Bbyte &::=& + \hex{00} &\Rightarrow& \hex{00} \\ &&|&& + \dots \\ &&|& + \hex{FF} &\Rightarrow& \hex{FF} \\ + \end{array} + + +.. _text-int: +.. _text-sint: +.. _text-uint: +.. index:: integer, unsigned integer, signed integer, uninterpreted integer + pair: text format; integer + pair: text format; unsigned integer + pair: text format; signed integer + pair: text format; uninterpreted integer + single: abstract syntax; integer + single: abstract syntax; unsigned integer + single: abstract syntax; signed integer + single: abstract syntax; uninterpreted integer + +Integers +~~~~~~~~ + +All :ref:`integers ` are encoded using the `LEB128 `_ variable-length integer encoding, in either unsigned or signed variant. + +:ref:`Unsigned integers ` are encoded in `unsigned LEB128 `_ format. +As an additional constraint, the total number of bytes encoding a value of type :math:`\uX{N}` must not exceed :math:`\F{ceil}(N/7)` bytes. + +.. math:: + \begin{array}{llclll@{\qquad}l} + \production{unsigned integers} & \BuX{N} &::=& + n{:}\Bbyte &\Rightarrow& n & (n < 2^7 \wedge n < 2^N) \\ &&|& + n{:}\Bbyte~~m{:}\BuX{N-7} &\Rightarrow& + 2^7\cdot m + (n-2^7) & (n \geq 2^7 \wedge N > 7) \\ + \end{array} + +:ref:`Signed integers ` are encoded in `signed LEB128 `_ format, which uses a 2's complement representation. +As an additional constraint, the total number of bytes encoding a value of type :math:`\sX{N}` must not exceed :math:`\F{ceil}(N/7)` bytes. + +.. math:: + \begin{array}{llclll@{\qquad}l} + \production{signed integers} & \BsX{N} &::=& + n{:}\Bbyte &\Rightarrow& n & (n < 2^6 \wedge n < 2^{N-1}) \\ &&|& + n{:}\Bbyte &\Rightarrow& n-2^7 & (2^6 \leq n < 2^7 \wedge n \geq 2^7-2^{N-1}) \\ &&|& + n{:}\Bbyte~~m{:}\BsX{N-7} &\Rightarrow& + 2^7\cdot m + (n-2^7) & (n \geq 2^7 \wedge N > 7) \\ + \end{array} + +:ref:`Uninterpreted integers ` are always encoded as signed integers. + +.. math:: + \begin{array}{llclll@{\qquad\qquad}l} + \production{uninterpreted integers} & \BiX{N} &::=& + n{:}\BsX{N} &\Rightarrow& n + \end{array} + +.. note:: + While the side conditions :math:`N > 7` in the productions for *non-terminating* bytes restrict the length of the :math:`\uX{}` and :math:`\sX{}` encodings, + "trailing zeros" are still allowed within these bounds. + For example, :math:`\hex{03}` and :math:`\hex{83}~\hex{00}` are both well-formed encodings for the value :math:`3` as a |u8|. + Similarly, either of :math:`\hex{7e}` and :math:`\hex{FE}~\hex{7F}` and :math:`\hex{FE}~\hex{FF}~\hex{7F}` are well-formed encodings of the value :math:`-2` as a |s16|. + + The side conditions on the value :math:`n` of *terminating* bytes further enforce that + any unused bits in these bytes must be :math:`0` for positive values and :math:`1` for negative ones. + For example, :math:`\hex{83}~\hex{10}` is malformed as a |u8| encoding. + Similarly, both :math:`\hex{83}~\hex{3E}` and :math:`\hex{FF}~\hex{7B}` are malformed as |s8| encodings. + + +.. _binary-float: +.. index:: floating-point number + pair: binary format; floating-point number + single: abstract syntax; floating-point number + +Floating-Point +~~~~~~~~~~~~~~ + +:ref:`Floating point ` values are encoded directly by their IEEE bit pattern in `little endian `_ byte order: + +.. math:: + \begin{array}{llclll@{\qquad\qquad}l} + \production{floating-point numbers} & \BfX{N} &::=& + b^\ast{:\,}\Bbyte^{N/8} &\Rightarrow& \F{reverse}(b^\ast) \\ + \end{array} + +Here, :math:`\F{reverse}(b^\ast)` denotes the byte sequence :math:`b^\ast` in reversed order. + + +.. _binary-vec: +.. index:: vector + pair: binary format; vector + single: abstract syntax; vector + +Vectors +~~~~~~~ + +:ref:`Vectors ` are encoded with their length followed by the encoding of their element sequence. + +.. math:: + \begin{array}{llclll@{\qquad\qquad}l} + \production{vectors} & \Bvec(\B{B}) &::=& + n{:}\Bu32~~(x{:}\B{B})^n &\Rightarrow& x^n \\ + \end{array} + + +.. _binary-name: +.. index:: name, byte + pair: binary format; name + single: abstract syntax; name + +Names +~~~~~ + +:ref:`Names ` are encoded like a :ref:`vector ` of bytes containing the `UTF-8 `_ encoding of the name's code point sequence. + +.. math:: + \begin{array}{llclll@{\qquad}l} + \production{names} & \Bname &::=& + n{:}\Bu32~~(\X{uc}{:}\Bcodepoint)^\ast &\Rightarrow& \X{uc}^\ast + & (|\Bcodepoint^\ast| = n) \\ + \production{code points} & \Bcodepoint &::=& + \X{uv}{:}\Bcodeval_N &\Rightarrow& \X{uv} + & (\X{uv} \geq N \wedge (\X{uv} < \unicode{D800} \vee \unicode{E000} \leq \X{uv} < \unicode{110000})) \\ + \production{code values} & \Bcodeval_N &::=& + b_1{:}\Bbyte &\Rightarrow& + b_1 + & (b_1 < \hex{80} \wedge N = \unicode{00}) \\ &&|& + b_1{:}\Bbyte~~b_2{:}\Bcodecont &\Rightarrow& + 2^6\cdot(b_1-\hex{c0}) + b_2 + & (\hex{c0} \leq b_1 < \hex{e0} \wedge N = \unicode{80}) \\ &&|& + b_1{:}\Bbyte~~b_2{:}\Bcodecont~~b_3{:}\Bcodecont &\Rightarrow& + 2^{12}\cdot(b_1-\hex{e0}) + 2^6\cdot b_2 + b_3 + & (\hex{e0} \leq b_1 < \hex{f0} \wedge N = \unicode{800}) \\ &&|& + b_1{:}\Bbyte~~b_2{:}\Bcodecont~~b_3{:}\Bcodecont~~b_4{:}\Bcodecont + &\Rightarrow& + 2^{18}\cdot(b_1-\hex{f0}) + 2^{12}\cdot b_2 + 2^6\cdot b_3 + b_4 + & (\hex{f0} \leq b_1 < \hex{f8} \wedge N = \unicode{10000}) \\ + \production{code continuation} & \Bcodecont &::=& + b{:}\Bbyte &\Rightarrow& b - \hex{80} & (b \geq \hex{80}) \\ + \end{array} + +.. note:: + The :ref:`size `, :math:`||\Bcodepoint^\ast||` denotes the number of bytes in the encoding of the sequence, not the number of code points. + + The index :math:`N` to |Bcodeval| is the minimum value that a given byte sequence may decode into. + The respective side conditions on it exclude encodings using more than the minimal number of bytes to represent a code point. From cefc9345f9aa5bdf8c0f4dc7a6ef521f62c86934 Mon Sep 17 00:00:00 2001 From: rossberg-chromium Date: Tue, 2 May 2017 17:10:20 +0200 Subject: [PATCH 02/30] Core syntax done --- document/binary/modules.rst | 21 +- document/math.def | 13 + document/text/instructions.rst | 88 ++++-- document/text/modules.rst | 562 ++++++++++++--------------------- 4 files changed, 276 insertions(+), 408 deletions(-) diff --git a/document/binary/modules.rst b/document/binary/modules.rst index 4431f17841..aa904566f2 100644 --- a/document/binary/modules.rst +++ b/document/binary/modules.rst @@ -17,7 +17,7 @@ except that :ref:`function definitions ` are split into two section .. _binary-globalidx: .. _binary-localidx: .. _binary-labelidx: -.. index:: index, index space, type index, function index, table index, memory index, global index, local index, label index +.. index:: index, type index, function index, table index, memory index, global index, local index, label index pair: binary format; type index pair: binary format; function index pair: binary format; table index @@ -25,13 +25,6 @@ except that :ref:`function definitions ` are split into two section pair: binary format; global index pair: binary format; local index pair: binary format; label index - single: abstract syntax; type index - single: abstract syntax; function index - single: abstract syntax; table index - single: abstract syntax; memory index - single: abstract syntax; global index - single: abstract syntax; local index - single: abstract syntax; label index Indices ~~~~~~~ @@ -112,7 +105,6 @@ Their contents consist of a :ref:`name ` further identifying the cu .. _binary-type: .. index:: ! type section, type definition pair: binary format; type section - single: abstract syntax; type definition pair: section; type Type Section @@ -132,7 +124,6 @@ It decodes into a vector of :ref:`function types ` that represe .. _binary-import: .. index:: ! import section, import, name, function type, table type, memory type, global type pair: binary format; import - single: abstract syntax; import pair: section; import Import Section @@ -160,7 +151,6 @@ It decodes into a vector of :ref:`imports ` that represent the |I .. _binary-func: .. index:: ! function section, function, type index, function type pair: binary format; function - single: abstract syntax; function pair: section; function Function Section @@ -181,7 +171,6 @@ The |LOCALS| and |BODY| fields of the respective functions are encoded separatel .. _binary-table: .. index:: ! table section, table, table type pair: binary format; table - single: abstract syntax; table pair: section; table Table Section @@ -203,7 +192,6 @@ It decodes into a vector of :ref:`tables ` that represent the |TAB .. _binary-mem: .. index:: ! memory section, memory, memory type pair: binary format; memory - single: abstract syntax; memory pair: section; memory Memory Section @@ -225,7 +213,6 @@ It decodes into a vector of :ref:`memories ` that represent the |MEM .. _binary-global: .. index:: ! global section, global, global type, expression pair: binary format; global - single: abstract syntax; global pair: section; global Global Section @@ -248,7 +235,6 @@ It decodes into a vector of :ref:`globals ` that represent the |G .. _binary-export: .. index:: ! export section, export, name, index, function index, table index, memory index, global index pair: binary format; export - single: abstract syntax; export pair: section; export Export Section @@ -276,7 +262,6 @@ It decodes into a vector of :ref:`exports ` that represent the |E .. _binary-start: .. index:: ! start section, start function, function index pair: binary format; start function - single: abstract syntax; start function single: section; start single: start function; section @@ -299,7 +284,6 @@ It decodes into an optional :ref:`start function ` that represents .. _binary-elem: .. index:: ! element section, element, table index, expression, function index pair: binary format; element - single: abstract syntax; element pair: section; element single: table; element single: element; segment @@ -324,7 +308,6 @@ It decodes into a vector of :ref:`element segments ` that represent .. _binary-local: .. index:: ! code section, function, local, type index, function type pair: binary format; function - single: abstract syntax; function pair: section; code Code Section @@ -379,7 +362,6 @@ Any code for which the length of the resulting sequence is out of bounds of the .. _binary-data: .. index:: ! data section, data, memory, memory index, expression, byte pair: binary format; data - single: abstract syntax; data pair: section; data single: memory; data single: data; segment @@ -405,7 +387,6 @@ It decodes into a vector of :ref:`data segments ` that represent th .. _binary-version: .. index:: module, section, type definition, function type, function, table, memory, global, element, data, start function, import, export, context, version pair: binary format; module - single: abstract syntax; module Modules ~~~~~~~ diff --git a/document/math.def b/document/math.def index 91244aa3b0..ce89257679 100644 --- a/document/math.def +++ b/document/math.def @@ -222,6 +222,14 @@ .. |Tlocalidx| mathdef:: \xref{text/modules}{text-localidx}{\T{localidx}} .. |Tlabelidx| mathdef:: \xref{text/modules}{text-labelidx}{\T{labelidx}} +.. |Ttypebind| mathdef:: \xref{text/modules}{text-typebind}{\T{typebind}} +.. |Tfuncbind| mathdef:: \xref{text/modules}{text-funcbind}{\T{funcbind}} +.. |Ttablebind| mathdef:: \xref{text/modules}{text-tablebind}{\T{tablebind}} +.. |Tmembind| mathdef:: \xref{text/modules}{text-membind}{\T{membind}} +.. |Tglobalbind| mathdef:: \xref{text/modules}{text-globalbind}{\T{globalbind}} +.. |Tlocalbind| mathdef:: \xref{text/modules}{text-localbind}{\T{localbind}} +.. |Tlabelbind| mathdef:: \xref{text/modules}{text-labelbind}{\T{labelbind}} + .. Modules, terminals @@ -315,7 +323,9 @@ .. Modules, textual non-terminals .. |Tmodule| mathdef:: \xref{text/modules}{text-module}{\T{module}} +.. |Tmodulebody| mathdef:: \xref{text/modules}{text-module}{\T{modulebody}} .. |Ttype| mathdef:: \xref{text/modules}{text-type}{\T{type}} +.. |Ttypeuse| mathdef:: \xref{text/modules}{text-typeuse}{\T{typeuse}} .. |Tfunc| mathdef:: \xref{text/modules}{text-func}{\T{func}} .. |Ttable| mathdef:: \xref{text/modules}{text-table}{\T{table}} .. |Tmem| mathdef:: \xref{text/modules}{text-mem}{\T{mem}} @@ -445,4 +455,7 @@ .. |Toffset| mathdef:: \xref{text/instructions}{text-memarg}{\T{offset}} .. |Tinstr| mathdef:: \xref{text/instructions}{text-instr}{\T{instr}} +.. |Tplaininstr| mathdef:: \xref{text/instructions}{text-plaininstr}{\T{plaininstr}} +.. |Tblockinstr| mathdef:: \xref{text/instructions}{text-blockinstr}{\T{blockinstr}} +.. |Tfoldedinstr| mathdef:: \xref{text/instructions}{text-foldedinstr}{\T{foldedinstr}} .. |Texpr| mathdef:: \xref{text/instructions}{text-expr}{\T{expr}} diff --git a/document/text/instructions.rst b/document/text/instructions.rst index 133678b3bd..bd0904d045 100644 --- a/document/text/instructions.rst +++ b/document/text/instructions.rst @@ -4,10 +4,19 @@ Instructions ------------ -:ref:`Instructions ` are encoded by *opcodes*. -Each opcode is represented by a single byte, -and is followed by the instruction's immediate arguments, where present. -The only exception are :ref:`structured control instructions `, which consist of several opcodes bracketing their nested instruction sequences. +.. todo:: symbolic labels + + +.. math:: + \begin{array}{llclll} + \production{instruction} & \Tinstr_C &::=& + \X{in}{:}\Tplaininstr + &\Rightarrow& \X{in} \\ &&|& + \X{in}{:}\Tblockinstr_C + &\Rightarrow& \X{in} \\ &&|& + \X{in}^\ast{:}\Tfoldedinstr_C + &\Rightarrow& \X{in}^\ast \\ + \end{array} .. _text-instr-control: @@ -18,8 +27,6 @@ The only exception are :ref:`structured control instructions ` have varying encodings. For structured instructions, the nested instruction sequences are terminated with explicit opcodes for |END| and |ELSE|. - .. _text-nop: .. _text-unreachable: .. _text-block: @@ -34,18 +41,19 @@ Control Instructions .. math:: \begin{array}{llclll} - \production{instruction} & \Tinstr &::=& - \text{unreachable} &\Rightarrow& \UNREACHABLE \\ &&|& - \text{nop} &\Rightarrow& \NOP \\ &&|& - \text{block}~~\X{rt}{:}\Tblocktype~~(\X{in}{:}\Tinstr)^\ast~~\text{end} + \production{block instruction} & \Tblockinstr_C &::=& + \text{block}~~\X{rt}{:}\Tblocktype~~(\X{in}{:}\Tinstr_{C'})^\ast~~\text{end} &\Rightarrow& \BLOCK~\X{rt}~\X{in}^\ast~\END \\ &&|& - \text{loop}~~\X{rt}{:}\Tblocktype~~(\X{in}{:}\Tinstr)^\ast~~\text{end} + \text{loop}~~\X{rt}{:}\Tblocktype~~(\X{in}{:}\Tinstr_{C'})^\ast~~\text{end} &\Rightarrow& \LOOP~\X{rt}~\X{in}^\ast~\END \\ &&|& - \text{if}~~\X{rt}{:}\Tblocktype~~(\X{in}{:}\Tinstr)^\ast~~\text{end} + \text{if}~~\X{rt}{:}\Tblocktype~~(\X{in}{:}\Tinstr_{C'})^\ast~~\text{end} &\Rightarrow& \IF~\X{rt}~\X{in}^\ast~\ELSE~\epsilon~\END \\ &&|& - \text{if}~~\X{rt}{:}\Tblocktype~~(\X{in}_1{:}\Tinstr)^\ast~~ - \text{else}~~(\X{in}_2{:}\Tinstr)^\ast~~\text{end} - &\Rightarrow& \IF~\X{rt}~\X{in}_1^\ast~\ELSE~\X{in}_2^\ast~\END \\ &&|& + \text{if}~~\X{rt}{:}\Tblocktype~~(\X{in}_1{:}\Tinstr_{C'})^\ast~~ + \text{else}~~(\X{in}_2{:}\Tinstr_{C'})^\ast~~\text{end} + &\Rightarrow& \IF~\X{rt}~\X{in}_1^\ast~\ELSE~\X{in}_2^\ast~\END \\ + \production{plain instruction} & \Tplaininstr &::=& + \text{unreachable} &\Rightarrow& \UNREACHABLE \\ &&|& + \text{nop} &\Rightarrow& \NOP \\ &&|& \text{br}~~l{:}\Tlabelidx &\Rightarrow& \BR~l \\ &&|& \text{br\_if}~~l{:}\Tlabelidx &\Rightarrow& \BRIF~l \\ &&|& \text{br\_table}~~l^\ast{:}\Tvec(\Tlabelidx)~~l_N{:}\Tlabelidx @@ -56,7 +64,7 @@ Control Instructions \end{array} .. note:: - The :math:`\text{else}` keyword an :math:`\text{if}` instruction can be omitted if the following instruction sequence is empty. + The :math:`\text{else}` keyword of an :math:`\text{if}` instruction can be omitted if the following instruction sequence is empty. .. _text-instr-parametric: @@ -72,7 +80,7 @@ Parametric Instructions .. math:: \begin{array}{llclll} - \production{instruction} & \Tinstr &::=& \dots \\ &&|& + \production{instruction} & \Tplaininstr &::=& \dots \\ &&|& \text{drop} &\Rightarrow& \DROP \\ &&|& \text{select} &\Rightarrow& \SELECT \\ \end{array} @@ -94,7 +102,7 @@ Variable Instructions .. math:: \begin{array}{llclll} - \production{instruction} & \Tinstr &::=& \dots \\ &&|& + \production{instruction} & \Tplaininstr &::=& \dots \\ &&|& \text{get\_local}~~x{:}\Tlocalidx &\Rightarrow& \GETLOCAL~x \\ &&|& \text{set\_local}~~x{:}\Tlocalidx &\Rightarrow& \SETLOCAL~x \\ &&|& \text{tee\_local}~~x{:}\Tlocalidx &\Rightarrow& \TEELOCAL~x \\ &&|& @@ -130,7 +138,7 @@ Memory Instructions \production{memory alignment} & \Talign_N &::=& \text{align{=}}a{:}\Tu32 &\Rightarrow& a \\ &&|& \epsilon &\Rightarrow& N \\ - \production{instruction} & \Tinstr &::=& \dots \\ &&|& + \production{instruction} & \Tplaininstr &::=& \dots \\ &&|& \text{i32.load}~~m{:}\Tmemarg_4 &\Rightarrow& \I32.\LOAD~m \\ &&|& \text{i64.load}~~m{:}\Tmemarg_8 &\Rightarrow& \I64.\LOAD~m \\ &&|& \text{f32.load}~~m{:}\Tmemarg_4 &\Rightarrow& \F32.\LOAD~m \\ &&|& @@ -171,7 +179,7 @@ Numeric Instructions .. math:: \begin{array}{llclll} - \production{instruction} & \Tinstr &::=& \dots \\&&|& + \production{instruction} & \Tplaininstr &::=& \dots \\&&|& \text{i32.const}~~n{:}\Ti32 &\Rightarrow& \I32.\CONST~n \\ &&|& \text{i64.const}~~n{:}\Ti64 &\Rightarrow& \I64.\CONST~n \\ &&|& \text{f32.const}~~z{:}\Tf32 &\Rightarrow& \F32.\CONST~z \\ &&|& @@ -183,7 +191,7 @@ Numeric Instructions .. math:: \begin{array}{llclll} - \phantom{\production{instruction}} & \phantom{\Tinstr} &\phantom{::=}& \phantom{thisisenough} && \phantom{thisshouldbeenough} \\[-2ex] &&|& + \phantom{\production{instruction}} & \phantom{\Tplaininstr} &\phantom{::=}& \phantom{thisisenough} && \phantom{thisshouldbeenough} \\[-2ex] &&|& \text{i32.clz} &\Rightarrow& \I32.\CLZ \\ &&|& \text{i32.ctz} &\Rightarrow& \I32.\CTZ \\ &&|& \text{i32.popcnt} &\Rightarrow& \I32.\POPCNT \\ &&|& @@ -206,7 +214,7 @@ Numeric Instructions .. math:: \begin{array}{llclll} - \phantom{\production{instruction}} & \phantom{\Tinstr} &\phantom{::=}& \phantom{thisisenough} && \phantom{thisshouldbeenough} \\[-2ex] &&|& + \phantom{\production{instruction}} & \phantom{\Tplaininstr} &\phantom{::=}& \phantom{thisisenough} && \phantom{thisshouldbeenough} \\[-2ex] &&|& \text{i64.clz} &\Rightarrow& \I64.\CLZ \\ &&|& \text{i64.ctz} &\Rightarrow& \I64.\CTZ \\ &&|& \text{i64.popcnt} &\Rightarrow& \I64.\POPCNT \\ &&|& @@ -229,7 +237,7 @@ Numeric Instructions .. math:: \begin{array}{llclll} - \phantom{\production{instruction}} & \phantom{\Tinstr} &\phantom{::=}& \phantom{thisisenough} && \phantom{thisshouldbeenough} \\[-2ex] &&|& + \phantom{\production{instruction}} & \phantom{\Tplaininstr} &\phantom{::=}& \phantom{thisisenough} && \phantom{thisshouldbeenough} \\[-2ex] &&|& \text{f32.abs} &\Rightarrow& \F32.\ABS \\ &&|& \text{f32.neg} &\Rightarrow& \F32.\NEG \\ &&|& \text{f32.ceil} &\Rightarrow& \F32.\CEIL \\ &&|& @@ -248,7 +256,7 @@ Numeric Instructions .. math:: \begin{array}{llclll} - \phantom{\production{instruction}} & \phantom{\Tinstr} &\phantom{::=}& \phantom{thisisenough} && \phantom{thisshouldbeenough} \\[-2ex] &&|& + \phantom{\production{instruction}} & \phantom{\Tplaininstr} &\phantom{::=}& \phantom{thisisenough} && \phantom{thisshouldbeenough} \\[-2ex] &&|& \text{f64.abs} &\Rightarrow& \F64.\ABS \\ &&|& \text{f64.neg} &\Rightarrow& \F64.\NEG \\ &&|& \text{f64.ceil} &\Rightarrow& \F64.\CEIL \\ &&|& @@ -270,7 +278,7 @@ Numeric Instructions .. math:: \begin{array}{llclll} - \phantom{\production{instruction}} & \phantom{\Tinstr} &\phantom{::=}& \phantom{thisisenough} && \phantom{thisshouldbeenough} \\[-2ex] &&|& + \phantom{\production{instruction}} & \phantom{\Tplaininstr} &\phantom{::=}& \phantom{thisisenough} && \phantom{thisshouldbeenough} \\[-2ex] &&|& \text{i32.eqz} &\Rightarrow& \I32.\EQZ \\ &&|& \text{i32.eq} &\Rightarrow& \I32.\EQ \\ &&|& \text{i32.ne} &\Rightarrow& \I32.\NE \\ &&|& @@ -286,7 +294,7 @@ Numeric Instructions .. math:: \begin{array}{llclll} - \phantom{\production{instruction}} & \phantom{\Tinstr} &\phantom{::=}& \phantom{thisisenough} && \phantom{thisshouldbeenough} \\[-2ex] &&|& + \phantom{\production{instruction}} & \phantom{\Tplaininstr} &\phantom{::=}& \phantom{thisisenough} && \phantom{thisshouldbeenough} \\[-2ex] &&|& \text{i64.eqz} &\Rightarrow& \I64.\EQZ \\ &&|& \text{i64.eq} &\Rightarrow& \I64.\EQ \\ &&|& \text{i64.ne} &\Rightarrow& \I64.\NE \\ &&|& @@ -302,7 +310,7 @@ Numeric Instructions .. math:: \begin{array}{llclll} - \phantom{\production{instruction}} & \phantom{\Tinstr} &\phantom{::=}& \phantom{thisisenough} && \phantom{thisshouldbeenough} \\[-2ex] &&|& + \phantom{\production{instruction}} & \phantom{\Tplaininstr} &\phantom{::=}& \phantom{thisisenough} && \phantom{thisshouldbeenough} \\[-2ex] &&|& \text{f32.eq} &\Rightarrow& \F32.\EQ \\ &&|& \text{f32.ne} &\Rightarrow& \F32.\NE \\ &&|& \text{f32.lt} &\Rightarrow& \F32.\LT \\ &&|& @@ -313,7 +321,7 @@ Numeric Instructions .. math:: \begin{array}{llclll} - \phantom{\production{instruction}} & \phantom{\Tinstr} &\phantom{::=}& \phantom{thisisenough} && \phantom{thisshouldbeenough} \\[-2ex] &&|& + \phantom{\production{instruction}} & \phantom{\Tplaininstr} &\phantom{::=}& \phantom{thisisenough} && \phantom{thisshouldbeenough} \\[-2ex] &&|& \text{f64.eq} &\Rightarrow& \F64.\EQ \\ &&|& \text{f64.ne} &\Rightarrow& \F64.\NE \\ &&|& \text{f64.lt} &\Rightarrow& \F64.\LT \\ &&|& @@ -326,7 +334,7 @@ Numeric Instructions .. math:: \begin{array}{llclll} - \phantom{\production{instruction}} & \phantom{\Tinstr} &\phantom{::=}& \phantom{thisisenough} && \phantom{thisshouldbeenough} \\[-2ex] &&|& + \phantom{\production{instruction}} & \phantom{\Tplaininstr} &\phantom{::=}& \phantom{thisisenough} && \phantom{thisshouldbeenough} \\[-2ex] &&|& \text{i32.wrap/i64} &\Rightarrow& \I32.\WRAP\K{/}\I64 \\ &&|& \text{i32.trunc\_s/f32} &\Rightarrow& \I32.\TRUNC\K{\_s/}\F32 \\ &&|& \text{i32.trunc\_u/f32} &\Rightarrow& \I32.\TRUNC\K{\_u/}\F32 \\ &&|& @@ -355,6 +363,28 @@ Numeric Instructions \end{array} +.. _text-foldedinstr: + +Folded Instructions +~~~~~~~~~~~~~~~~~~~ + +.. math:: + \begin{array}{llclll} + \production{folded instruction} & \Tfoldedinstr_C &::=& + \text{(}~\X{in}{:}\Tplaininstr~~(\X{op}{:}\Tfoldedinstr_C)^\ast~\text{)} + &\Rightarrow& \X{op}^\ast~\X{in} \\ &&|& + \text{(}~\text{block}~~\X{rt}{:}\Tblocktype~~(\X{in}{:}\Tinstr_{C'})^\ast~\text{)} + &\Rightarrow& \BLOCK~\X{rt}~\X{in}^\ast~\END \\ &&|& + \text{(}~\text{loop}~~\X{rt}{:}\Tblocktype~~(\X{in}{:}\Tinstr_{C'})^\ast~\text{)} + &\Rightarrow& \LOOP~\X{rt}~\X{in}^\ast~\END \\ &&|& + \text{(}~\text{if}~~\X{rt}{:}\Tblocktype~~\X{in}_0^\ast{:}\Tfoldedinstr_C~~\text{(}~\text{then}~~(\X{in}{:}\Tinstr_{C'})^\ast~\text{)}~~\text{)} + &\Rightarrow& \X{in}_0^\ast~~\IF~\X{rt}~\X{in}^\ast~\ELSE~\epsilon~\END \\ &&|& + \text{(}~\text{if}~~\X{rt}{:}\Tblocktype~~\X{in}_0^\ast{:}\Tfoldedinstr_C~~\text{(}~\text{then}~~(\X{in}_1{:}\Tinstr_{C'})^\ast~\text{)}~~ + \text{(}~\text{else}~~(\X{in}_2{:}\Tinstr_{C'})^\ast~\text{)}~~\text{)} + &\Rightarrow& \X{in}_0^\ast~~\IF~\X{rt}~\X{in}_1^\ast~\ELSE~\X{in}_2^\ast~\END \\ + \end{array} + + .. _text-expr: .. index:: expression pair: text format; expression diff --git a/document/text/modules.rst b/document/text/modules.rst index 4431f17841..fcbcb79ba3 100644 --- a/document/text/modules.rst +++ b/document/text/modules.rst @@ -1,460 +1,314 @@ Modules ------- -The binary encoding of modules is organized into *sections*. -Most sections correspond to one component of a :ref:`module ` record, -except that :ref:`function definitions ` are split into two sections, separating their type declarations in the :ref:`function section ` from their bodies in the :ref:`code section `. - -.. note:: - This separation enables *parallel* and *streaming* compilation of the functions in a module. - - -.. _binary-index: -.. _binary-typeidx: -.. _binary-funcidx: -.. _binary-tableidx: -.. _binary-memidx: -.. _binary-globalidx: -.. _binary-localidx: -.. _binary-labelidx: -.. index:: index, index space, type index, function index, table index, memory index, global index, local index, label index - pair: binary format; type index - pair: binary format; function index - pair: binary format; table index - pair: binary format; memory index - pair: binary format; global index - pair: binary format; local index - pair: binary format; label index - single: abstract syntax; type index - single: abstract syntax; function index - single: abstract syntax; table index - single: abstract syntax; memory index - single: abstract syntax; global index - single: abstract syntax; local index - single: abstract syntax; label index +.. todo:: symbolic indices; free ordering + + +.. _text-index: +.. _text-typeidx: +.. _text-funcidx: +.. _text-tableidx: +.. _text-memidx: +.. _text-globalidx: +.. _text-localidx: +.. _text-labelidx: +.. _text-typebind: +.. _text-funcbind: +.. _text-tablebind: +.. _text-membind: +.. _text-globalbind: +.. _text-localbind: +.. _text-labelbind: +.. index:: index, type index, function index, table index, memory index, global index, local index, label index + pair: text format; type index + pair: text format; function index + pair: text format; table index + pair: text format; memory index + pair: text format; global index + pair: text format; local index + pair: text format; label index Indices ~~~~~~~ -All :ref:`indices ` are encoded with their respective |U32| value. - .. math:: \begin{array}{llclll} - \production{type indices} & \Btypeidx &::=& x{:}\Bu32 &\Rightarrow& x \\ - \production{function indices} & \Bfuncidx &::=& x{:}\Bu32 &\Rightarrow& x \\ - \production{table indices} & \Btableidx &::=& x{:}\Bu32 &\Rightarrow& x \\ - \production{memory indices} & \Bmemidx &::=& x{:}\Bu32 &\Rightarrow& x \\ - \production{global indices} & \Bglobalidx &::=& x{:}\Bu32 &\Rightarrow& x \\ - \production{local indices} & \Blocalidx &::=& x{:}\Bu32 &\Rightarrow& x \\ - \production{label indices} & \Blabelidx &::=& l{:}\Bu32 &\Rightarrow& l \\ + \production{type index} & \Ttypeidx_C &::=& + x{:}\Tu32 &\Rightarrow& x \\ &&|& + v{:}\Tvar &\Rightarrow& x & (C.\TYPES[x] = v) \\ + \production{function index} & \Tfuncidx_C &::=& + x{:}\Tu32 &\Rightarrow& x \\ &&|& + v{:}\Tvar &\Rightarrow& x & (C.\FUNCS[x] = v) \\ + \production{table index} & \Ttableidx_C &::=& + x{:}\Tu32 &\Rightarrow& x \\ &&|& + v{:}\Tvar &\Rightarrow& x & (C.\TABLES[x] = v) \\ + \production{memory index} & \Tmemidx_C &::=& + x{:}\Tu32 &\Rightarrow& x \\ &&|& + v{:}\Tvar &\Rightarrow& x & (C.\MEMS[x] = v) \\ + \production{global index} & \Tglobalidx_C &::=& + x{:}\Tu32 &\Rightarrow& x \\ &&|& + v{:}\Tvar &\Rightarrow& x & (C.\GLOBALS[x] = v) \\ + \production{local index} & \Tlocalidx_C &::=& + x{:}\Tu32 &\Rightarrow& x \\ &&|& + v{:}\Tvar &\Rightarrow& x & (C.\LOCALS[x] = v) \\ + \production{label index} & \Tlabelidx_C &::=& + l{:}\Tu32 &\Rightarrow& l \\ &&|& + v{:}\Tvar &\Rightarrow& x & (C.\LABELS[x] = v) \\ \end{array} - -.. _binary-section: -.. index:: ! section - pair: binary format; section - -Sections -~~~~~~~~ - -Each section consists of - -* a one-byte section *id*, -* the |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 :math:`N` and contents described by the grammar :math:`\B{B}`. - .. math:: - \begin{array}{llclll@{\qquad}l} - \production{sections} & \Bsection_N(\B{B}) &::=& - N{:}\Bbyte~~\X{size}{:}\Bu32~~\X{cont}{:}\B{B} - &\Rightarrow& \X{cont} & (\X{size} = ||\B{B}||) \\ &&|& - \epsilon &\Rightarrow& \epsilon + \begin{array}{llclll} + \production{type binder} & \Ttypebind_C &::=& + \epsilon &\Rightarrow& C \with \TYPES = C.\TYPES~(\epsilon) \\ &&|& + v{:}\Tvar &\Rightarrow& C \with \TYPES = C.\TYPES~v + & (v \notin C.\TYPES) \\ + \production{function binder} & \Tfuncbind_C &::=& + \epsilon &\Rightarrow& C \with \FUNCS = C.\FUNCS~(\epsilon) \\ &&|& + v{:}\Tvar &\Rightarrow& C \with \FUNCS = C.\FUNCS~v + & (v \notin C.\FUNCS) \\ + \production{table binder} & \Ttablebind_C &::=& + \epsilon &\Rightarrow& C \with \TABLES = C.\TABLES~(\epsilon) \\ &&|& + v{:}\Tvar &\Rightarrow& C \with \TABLES = C.\TABLES~v + & (v \notin C.\TABLES) \\ + \production{memory binder} & \Tmembind_C &::=& + \epsilon &\Rightarrow& C \with \MEMS = C.\MEMS~(\epsilon) \\ &&|& + v{:}\Tvar &\Rightarrow& C \with \MEMS = C.\MEMS~v + & (v \notin C.\MEMS) \\ + \production{global binder} & \Tglobalbind_C &::=& + \epsilon &\Rightarrow& C \with \GLOBALS = C.\GLOBALS~(\epsilon) \\ &&|& + v{:}\Tvar &\Rightarrow& C \with \GLOBALS = C.\GLOBALS~v + & (v \notin C.\GLOBALS) \\ + \production{local binder} & \Tlocalbind_C &::=& + \epsilon &\Rightarrow& C \with \LOCALS = C.\LOCALS~(\epsilon) \\ &&|& + v{:}\Tvar &\Rightarrow& C \with \LOCALS = C.\LOCALS~v + & (v \notin C.\LOCALS) \\ + \production{label binder} & \Tlabelbind_C &::=& + \epsilon &\Rightarrow& C \with \LABELS = C.\LABELS~(\epsilon) \\ &&|& + v{:}\Tvar &\Rightarrow& C \with \LABELS = v~C.\LABELS + & (v \notin C.\LABELS) \\ \end{array} -For most sections, the contents :math:`\B{B}` encodes a :ref:`vector `. -In these cases, the empty result :math:`\epsilon` is interpreted as the empty vector. -.. note:: - Other than for unknown :ref:`custom sections `, - the :math:`\X{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 :math:`\B{B}`. +.. _text-type: +.. _text-typeuse: +.. index:: type definition + pair: text format; type definition - -.. _binary-customsec: -.. index:: ! custom section - pair: binary format; custom section - single: section; custom - -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 :ref:`name ` further identifying the custom section, followed by an uninterpreted sequence of bytes for custom use. +Types +~~~~~ .. math:: \begin{array}{llclll} - \production{custom sections} & \Bcustomsec &::=& - \Bsection_0(\Bcustom) \\ - \production{custom data} & \Bcustom &::=& - \Bname~~\Bbyte^\ast \\ + \production{type definition} & \Ttype &::=& + \text{(}~\text{type}~~\X{ft}{:}\Tfunctype~\text{)} + &\Rightarrow& \X{ft} \\ \end{array} -.. note:: - If an implementation interprets the contents of a custom section, then errors in that contents, or the placement of the section, must not invalidate the module. - - -.. _binary-typesec: -.. _binary-type: -.. index:: ! type section, type definition - pair: binary format; type section - single: abstract syntax; type definition - pair: section; type - -Type Section -~~~~~~~~~~~~ - -The *type section* has the id 1. -It decodes into a vector of :ref:`function types ` that represent the |TYPES| component of a :ref:`module `. +.. todo:: inline functypes .. math:: \begin{array}{llclll} - \production{type sections} & \Btypesec &::=& - \X{ft}^\ast{:\,}\Bsection_1(\Bvec(\Bfunctype)) &\Rightarrow& \X{ft}^\ast \\ + \production{type use} & \Ttypeuse &::=& + \text{(}~\text{type}~~x{:}\Ttypeidx~\text{)} + &\Rightarrow& x \\ \end{array} -.. _binary-importsec: -.. _binary-import: -.. index:: ! import section, import, name, function type, table type, memory type, global type - pair: binary format; import - single: abstract syntax; import - pair: section; import +.. _text-import: +.. index:: import, name, function type, table type, memory type, global type + pair: text format; import -Import Section -~~~~~~~~~~~~~~ +Imports +~~~~~~~ -The *import section* has the id 2. -It decodes into a vector of :ref:`imports ` that represent the |IMPORTS| component of a :ref:`module `. +.. todo:: inline imports .. math:: \begin{array}{llclll} - \production{import sections} & \Bimportsec &::=& - \X{im}^\ast{:}\Bsection_2(\Bvec(\Bimport)) &\Rightarrow& \X{im}^\ast \\ - \production{imports} & \Bimport &::=& - \X{mod}{:}\Bname~~\X{nm}{:}\Bname~~d{:}\Bimportdesc + \production{import} & \Timport &::=& + \text{(}~\text{import}~~\X{mod}{:}\Tname~~\X{nm}{:}\Tname~~d{:}\Timportdesc~\text{)} &\Rightarrow& \{ \MODULE~\X{mod}, \NAME~\X{nm}, \DESC~d \} \\ - \production{import descriptions} & \Bimportdesc &::=& - \hex{00}~~x{:}\Btypeidx &\Rightarrow& \FUNC~x \\ &&|& - \hex{01}~~\X{tt}{:}\Btabletype &\Rightarrow& \TABLE~\X{tt} \\ &&|& - \hex{02}~~\X{mt}{:}\Bmemtype &\Rightarrow& \MEM~\X{mt} \\ &&|& - \hex{03}~~\X{gt}{:}\Bglobaltype &\Rightarrow& \GLOBAL~\X{gt} \\ + \production{import description} & \Timportdesc &::=& + \text{(}~\text{func}~~x{:}\Ttypeuse~\text{)} + &\Rightarrow& \FUNC~x \\ &&|& + \text{(}~\text{table}~~\X{tt}{:}\Ttabletype~\text{)} + &\Rightarrow& \TABLE~\X{tt} \\ &&|& + \text{(}~\text{memory}~~\X{mt}{:}\Tmemtype~\text{)} + &\Rightarrow& \MEM~~\X{mt} \\ &&|& + \text{(}~\text{global}~~\X{gt}{:}\Tglobaltype~\text{)} + &\Rightarrow& \GLOBAL~\X{gt} \\ \end{array} -.. _binary-funcsec: -.. _binary-func: -.. index:: ! function section, function, type index, function type - pair: binary format; function - single: abstract syntax; function - pair: section; function +.. _text-func: +.. index:: function, type index, function type + pair: text format; function -Function Section -~~~~~~~~~~~~~~~~ +Functions +~~~~~~~~~ -The *function section* has the id 3. -It decodes into a vector of :ref:`type indices ` that represent the |TYPE| fields of the :ref:`functions ` in the |FUNCS| component of a :ref:`module `. -The |LOCALS| and |BODY| fields of the respective functions are encoded separately in the :ref:`code section `. +.. todo:: inline type, inline import/export, multi-locals .. math:: \begin{array}{llclll} - \production{function sections} & \Bfuncsec &::=& - x^\ast{:}\Bsection_3(\Bvec(\Btypeidx)) &\Rightarrow& x^\ast \\ + \production{function} & \Tfunc &::=& + \text{(}~\text{func}~~x{:}\Ttypeuse~~(t{:}\Tlocal)^\ast~~(\X{in}{:}\Tinstr)^\ast~\text{)} + &\Rightarrow& \{ \TYPE~x, \LOCALS~t^\ast, \BODY~\X{in}^\ast~\END \} \\ + \production{local} & \Tlocal &::=& + \text{(}~\text{local}~~t{:}\Tvaltype~\text{)} + &\Rightarrow& t \\ \end{array} -.. _binary-tablesec: -.. _binary-table: -.. index:: ! table section, table, table type - pair: binary format; table - single: abstract syntax; table - pair: section; table - -Table Section -~~~~~~~~~~~~~ +.. _text-table: +.. index:: table, table type + pair: text format; table -The *table section* has the id 4. -It decodes into a vector of :ref:`tables ` that represent the |TABLES| component of a :ref:`module `. +Tables +~~~~~~ .. math:: \begin{array}{llclll} - \production{table sections} & \Btablesec &::=& - \X{tab}^\ast{:}\Bsection_4(\Bvec(\Btable)) &\Rightarrow& \X{tab}^\ast \\ - \production{tables} & \Btable &::=& - \X{tt}{:}\Btabletype &\Rightarrow& \{ \TYPE~\X{tt} \} \\ + \production{table} & \Ttable &::=& + \text{(}~\text{table}~~\X{tt}{:}\Ttabletype~\text{)} + &\Rightarrow& \{ \TYPE~\X{tt} \} \\ \end{array} -.. _binary-memsec: -.. _binary-mem: -.. index:: ! memory section, memory, memory type - pair: binary format; memory - single: abstract syntax; memory - pair: section; memory - -Memory Section -~~~~~~~~~~~~~~ +.. _text-mem: +.. index:: memory, memory type + pair: text format; memory -The *memory section* has the id 5. -It decodes into a vector of :ref:`memories ` that represent the |MEMS| component of a :ref:`module `. +Memories +~~~~~~~~ .. math:: \begin{array}{llclll} - \production{memory sections} & \Bmemsec &::=& - \X{mem}^\ast{:}\Bsection_5(\Bvec(\Bmem)) &\Rightarrow& \X{mem}^\ast \\ - \production{memories} & \Bmem &::=& - \X{mt}{:}\Bmemtype &\Rightarrow& \{ \TYPE~\X{mt} \} \\ + \production{memory} & \Tmem &::=& + \text{(}~\text{memory}~~\X{mt}{:}\Tmemtype~\text{)} + &\Rightarrow& \{ \TYPE~\X{mt} \} \\ \end{array} -.. _binary-globalsec: -.. _binary-global: -.. index:: ! global section, global, global type, expression - pair: binary format; global - single: abstract syntax; global - pair: section; global +.. _text-global: +.. index:: global, global type, expression + pair: text format; global -Global Section -~~~~~~~~~~~~~~ - -The *global section* has the id 6. -It decodes into a vector of :ref:`globals ` that represent the |GLOBALS| component of a :ref:`module `. +Globals +~~~~~~~ .. math:: \begin{array}{llclll} - \production{global sections} & \Bglobalsec &::=& - \X{glob}^\ast{:}\Bsection_6(\Bvec(\Bglobal)) &\Rightarrow& \X{glob}^\ast \\ - \production{globals} & \Bglobal &::=& - \X{gt}{:}\Bglobaltype~~e{:}\Bexpr - &\Rightarrow& \{ \TYPE~\X{gt}, \INIT~e \} \\ + \production{global} & \Tglobal &::=& + \text{(}~\text{global}~~\X{gt}{:}\Tglobaltype~~(\X{in}{:}\Tinstr)^\ast~\text{)} + &\Rightarrow& \{ \TYPE~\X{gt}, \INIT~\X{in}^\ast~\END \} \\ \end{array} -.. _binary-exportsec: -.. _binary-export: -.. index:: ! export section, export, name, index, function index, table index, memory index, global index - pair: binary format; export - single: abstract syntax; export - pair: section; export +.. _text-export: +.. index:: export, name, index, function index, table index, memory index, global index + pair: text format; export -Export Section -~~~~~~~~~~~~~~ - -The *export section* has the id 7. -It decodes into a vector of :ref:`exports ` that represent the |EXPORTS| component of a :ref:`module `. +Exports +~~~~~~~ .. math:: \begin{array}{llclll} - \production{export sections} & \Bexportsec &::=& - \X{ex}^\ast{:}\Bsection_7(\Bvec(\Bexport)) &\Rightarrow& \X{ex}^\ast \\ - \production{exports} & \Bexport &::=& - \X{nm}{:}\Bname~~d{:}\Bexportdesc + \production{export} & \Texport &::=& + \text{(}~\text{export}~~\X{nm}{:}\Tname~~d{:}\Texportdesc~\text{)} &\Rightarrow& \{ \NAME~\X{nm}, \DESC~d \} \\ - \production{export descriptions} & \Bexportdesc &::=& - \hex{00}~~x{:}\Bfuncidx &\Rightarrow& \FUNC~x \\ &&|& - \hex{01}~~x{:}\Btableidx &\Rightarrow& \TABLE~x \\ &&|& - \hex{02}~~x{:}\Bmemidx &\Rightarrow& \MEM~x \\ &&|& - \hex{03}~~x{:}\Bglobalidx &\Rightarrow& \GLOBAL~x \\ + \production{export description} & \Texportdesc &::=& + \text{(}~\text{func}~~x{:}\Bfuncidx~\text{)} + &\Rightarrow& \FUNC~x \\ &&|& + \text{(}~\text{table}~~x{:}\Btableidx~\text{)} + &\Rightarrow& \TABLE~x \\ &&|& + \text{(}~\text{memory}~~x{:}\Bmemidx~\text{)} + &\Rightarrow& \MEM~x \\ &&|& + \text{(}~\text{global}~~x{:}\Bglobalidx~\text{)} + &\Rightarrow& \GLOBAL~x \\ \end{array} -.. _binary-startsec: -.. _binary-start: -.. index:: ! start section, start function, function index - pair: binary format; start function - single: abstract syntax; start function - single: section; start - single: start function; section +.. _text-start: +.. index:: start function, function index + pair: text format; start function -Start Section -~~~~~~~~~~~~~ - -The *start section* has the id 8. -It decodes into an optional :ref:`start function ` that represents the |START| component of a :ref:`module `. +Start Function +~~~~~~~~~~~~~~ .. math:: \begin{array}{llclll} - \production{start sections} & \Bstartsec &::=& - \X{st}^?{:}\Bsection_8(\Bstart) &\Rightarrow& \X{st}^? \\ - \production{start functions} & \Bstart &::=& - x{:}\Bfuncidx &\Rightarrow& \{ \FUNC~x \} \\ + \production{start function} & \Tstart &::=& + \text{(}~\text{start}~~x{:}\Tfuncidx~\text{)} + &\Rightarrow& \{ \FUNC~x \} \\ \end{array} -.. _binary-elemsec: -.. _binary-elem: -.. index:: ! element section, element, table index, expression, function index - pair: binary format; element - single: abstract syntax; element - pair: section; element +.. _text-elem: +.. index:: element, table index, expression, function index + pair: text format; element single: table; element single: element; segment -Element Section -~~~~~~~~~~~~~~~ - -The *element section* has the id 9. -It decodes into a vector of :ref:`element segments ` that represent the |ELEM| component of a :ref:`module `. +Element Segments +~~~~~~~~~~~~~~~~ .. math:: \begin{array}{llclll} - \production{element sections} & \Belemsec &::=& - \X{seg}^\ast{:}\Bsection_9(\Bvec(\Belem)) &\Rightarrow& \X{seg} \\ - \production{element segments} & \Belem &::=& - x{:}\Btableidx~~e{:}\Bexpr~~y^\ast{:}\Bvec(\Bfuncidx) - &\Rightarrow& \{ \TABLE~x, \OFFSET~e, \INIT~y^\ast \} \\ - \end{array} - - -.. _binary-codesec: -.. _binary-local: -.. index:: ! code section, function, local, type index, function type - pair: binary format; function - single: abstract syntax; function - pair: section; code - -Code Section -~~~~~~~~~~~~ - -The *code section* has the id 10. -It decodes into a vector of *code* entries that are pairs of :ref:`value type ` vectors and :ref:`expressions `. -They represent the |LOCALS| and |BODY| field of the :ref:`functions ` in the |FUNCS| component of a :ref:`module `. -The |TYPE| fields of the respective functions are encoded separately in the :ref:`function section `. - -The encoding of each code entry consists of - -* the |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 :ref:`expression `. - -Local declarations are compressed into a vector whose entries consist of - -* a |U32| *count*, -* a :ref:`value type `, - -denoting *count* locals of the same value type. - -.. math:: - \begin{array}{llclll@{\qquad}l} - \production{code sections} & \Bcodesec &::=& - \X{code}^\ast{:}\Bsection_{10}(\Bvec(\Bcode)) - &\Rightarrow& \X{code}^\ast \\ - \production{code} & \Bcode &::=& - \X{size}{:}\Bu32~~\X{code}{:}\Bfunc - &\Rightarrow& \X{code} & (\X{size} = ||\Bfunc||) \\ - \production{functions} & \Bfunc &::=& - (t^\ast)^\ast{:}\Bvec(\Blocals)~~e{:}\Bexpr - &\Rightarrow& \F{concat}((t^\ast)^\ast), e^\ast - & (|\F{concat}((t^\ast)^\ast)| < 2^{32}) \\ - \production{locals} & \Blocals &::=& - n{:}\Bu32~~t{:}\Bvaltype &\Rightarrow& t^n \\ + \production{element segment} & \Telem &::=& + \text{(}~\text{elem}~~x{:}\Ttableidx~~\text{(}~\text{offset}~~(\X{in}{:}\Tinstr)^\ast~\text{)}~~y^\ast{:}\Tvec(\Tfuncidx)~\text{)} + &\Rightarrow& \{ \TABLE~x, \OFFSET~\X{in}^\ast~\END, \INIT~y^\ast \} \\ \end{array} -Here, :math:`\X{code}` ranges over pairs :math:`(\valtype^\ast, \expr)`. -The meta function :math:`\F{concat}((t^\ast)^\ast)` denotes the sequence of types formed by concatenating all sequences :math:`t_i^\ast` in :math:`(t^\ast)^\ast`. -Any code for which the length of the resulting sequence is out of bounds of the maximum size of a :ref:`vector ` is malformed. -.. note:: - The :math:`\X{size}` is not needed for decoding, but like with :ref:`sections `, 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. - - -.. _binary-datasec: -.. _binary-data: -.. index:: ! data section, data, memory, memory index, expression, byte - pair: binary format; data - single: abstract syntax; data - pair: section; data +.. _text-data: +.. index:: data, memory, memory index, expression, byte + pair: text format; data single: memory; data single: data; segment -Data Section -~~~~~~~~~~~~ - -The *data section* has the id 11. -It decodes into a vector of :ref:`data segments ` that represent the |DATA| component of a :ref:`module `. +Data Segments +~~~~~~~~~~~~~ .. math:: \begin{array}{llclll} - \production{data sections} & \Bdatasec &::=& - \X{seg}^\ast{:}\Bsection_{11}(\Bvec(\Bdata)) &\Rightarrow& \X{seg} \\ - \production{data segments} & \Bdata &::=& - x{:}\Bmemidx~~e{:}\Bexpr~~b^\ast{:}\Bvec(\Bbyte) - &\Rightarrow& \{ \MEM~x, \OFFSET~e, \INIT~b^\ast \} \\ + \production{data segment} & \Tdata &::=& + \text{(}~\text{data}~~x{:}\Tmemidx~~\text{(}~\text{offset}~~(\X{in}{:}\Tinstr)^\ast~\text{)}~~b^\ast{:}\Tstring~\text{)} + &\Rightarrow& \{ \MEM~x, \OFFSET~\X{in}^\ast~\END, \INIT~b^\ast \} \\ \end{array} -.. _binary-module: -.. _binary-magic: -.. _binary-version: -.. index:: module, section, type definition, function type, function, table, memory, global, element, data, start function, import, export, context, version - pair: binary format; module - single: abstract syntax; module +.. _text-module: +.. index:: module, type definition, function type, function, table, memory, global, element, data, start function, import, export, context, version + pair: text format; module Modules ~~~~~~~ -The encoding of a :ref:`module ` starts with a preamble containing a 4-byte magic number and a version field. -The current version of the WebAssembly binary format is 1. - -The preamble is followed by a sequence of :ref:`sections `. -:ref:`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) :ref:`function ` and :ref:`code ` section must match up. +.. todo:: free ordering .. math:: \begin{array}{llcllll} - \production{magic} & \Bmagic &::=& - \hex{00}~\hex{61}~\hex{73}~\hex{6D} \\ - \production{version} & \Bversion &::=& - \hex{01}~\hex{00}~\hex{00}~\hex{00} \\ - \production{modules} & \Bmodule &::=& - \Bmagic \\ &&& - \Bversion \\ &&& - \Bcustomsec^\ast \\ &&& - \functype^\ast{:\,}\Btypesec \\ &&& - \Bcustomsec^\ast \\ &&& - \import^\ast{:\,}\Bimportsec \\ &&& - \Bcustomsec^\ast \\ &&& - \typeidx^n{:\,}\Bfuncsec \\ &&& - \Bcustomsec^\ast \\ &&& - \table^\ast{:\,}\Btablesec \\ &&& - \Bcustomsec^\ast \\ &&& - \mem^\ast{:\,}\Bmemsec \\ &&& - \Bcustomsec^\ast \\ &&& - \global^\ast{:\,}\Bglobalsec \\ &&& - \Bcustomsec^\ast \\ &&& - \export^\ast{:\,}\Bexportsec \\ &&& - \Bcustomsec^\ast \\ &&& - \start^?{:\,}\Bstartsec \\ &&& - \Bcustomsec^\ast \\ &&& - \elem^\ast{:\,}\Belemsec \\ &&& - \Bcustomsec^\ast \\ &&& - \X{code}^n{:\,}\Bcodesec \\ &&& - \Bcustomsec^\ast \\ &&& - \data^\ast{:\,}\Bdatasec \\ &&& - \Bcustomsec^\ast + \production{module} & \Tmodule &::=& + \text{(}~\text{module}~~m{:}\Tmodulebody~\text{)} + &\Rightarrow& m \\ &&|& + m{:}\Tmodulebody + &\Rightarrow& m \\ + \production{module body} & \Tmodulebody &::=& + (\functype{:}\Ttype)^\ast \\ &&& + (\import{:}\Timport)^\ast \\ &&& + (\func{:}\Tfunc)^\ast \\ &&& + (\table{:}\Ttable)^\ast \\ &&& + (\mem{:}\Tmem)^\ast \\ &&& + (\global{:}\Tglobal)^\ast \\ &&& + (\export{:}\Texport)^\ast \\ &&& + (\start{:}\Tstart)^? \\ &&& + (\elem{:}\Telem)^\ast \\ &&& + (\data{:}\Tdata)^\ast &\Rightarrow& \{~ \begin{array}[t]{@{}l@{}} \TYPES~\functype^\ast, \\ - \FUNCS~\func^n, \\ + \FUNCS~\func^\ast, \\ \TABLES~\table^\ast, \\ \MEMS~\mem^\ast, \\ \GLOBALS~\global^\ast, \\ @@ -465,13 +319,3 @@ The lengths of vectors produced by the (possibly empty) :ref:`function Date: Wed, 3 May 2017 18:51:56 +0200 Subject: [PATCH 03/30] Lexical --- document/binary/instructions.rst | 6 - document/binary/types.rst | 12 +- document/binary/values.rst | 13 +- document/math.def | 11 ++ document/text/conventions.rst | 10 +- document/text/index.rst | 1 + document/text/instructions.rst | 6 - document/text/lexical.rst | 78 +++++++++++ document/text/types.rst | 12 +- document/text/values.rst | 222 +++++++++++++++++-------------- interpreter/spec/float.ml | 1 - interpreter/text/lexer.mll | 17 +-- 12 files changed, 230 insertions(+), 159 deletions(-) create mode 100644 document/text/lexical.rst diff --git a/document/binary/instructions.rst b/document/binary/instructions.rst index 4047c740b7..bf4c57568c 100644 --- a/document/binary/instructions.rst +++ b/document/binary/instructions.rst @@ -16,7 +16,6 @@ The only exception are :ref:`structured control instructions ` is encoded with .. _binary-instr-numeric: .. index:: numeric instruction pair: binary format; instruction - single: abstract syntax; instruction Numeric Instructions ~~~~~~~~~~~~~~~~~~~~ @@ -370,7 +365,6 @@ All other numeric instructions are plain opcodes without any immediates. .. _binary-expr: .. index:: expression pair: binary format; expression - single: abstract syntax; expression single: expression; constant Expressions diff --git a/document/binary/types.rst b/document/binary/types.rst index b1ab57a015..ea4bdfb137 100644 --- a/document/binary/types.rst +++ b/document/binary/types.rst @@ -1,7 +1,6 @@ .. _binary-type: .. index:: type pair: binary format; type - single: abstract syntax; type Types ----- @@ -9,7 +8,6 @@ Types .. _binary-valtype: .. index:: value type pair: binary format; value type - single: abstract syntax; value type Value Types ~~~~~~~~~~~ @@ -34,7 +32,6 @@ Value Types .. _binary-blocktype: .. index:: result type, value type pair: binary format; result type - single: abstract syntax; result type Result Types ~~~~~~~~~~~~ @@ -55,7 +52,6 @@ The only :ref:`result types ` occurring in the binary format .. _binary-functype: .. index:: function type, value type, result type pair: binary format; function type - single: abstract syntax; function type Function Types ~~~~~~~~~~~~~~ @@ -73,7 +69,6 @@ Function Types .. _binary-limits: .. index:: limits pair: binary format; limits - single: abstract syntax; limits Limits ~~~~~~ @@ -90,8 +85,7 @@ Limits .. _binary-memtype: .. index:: memory type, limits, page size - single: binary format; memory type - pair: abstract syntax; memory type + pair: binary format; memory type Memory Types ~~~~~~~~~~~~ @@ -110,8 +104,6 @@ Memory Types .. index:: table type, element type, limits pair: binary format; table type pair: binary format; element type - single: abstract syntax; table type - single: abstract syntax; element type Table Types ~~~~~~~~~~~ @@ -131,8 +123,6 @@ Table Types .. index:: global type, mutability, value type pair: binary format; global type pair: binary format; mutability - single: abstract syntax; global type - single: abstract syntax; mutability Global Types ~~~~~~~~~~~~ diff --git a/document/binary/values.rst b/document/binary/values.rst index 6c228b3bc3..4942706087 100644 --- a/document/binary/values.rst +++ b/document/binary/values.rst @@ -1,7 +1,6 @@ .. _binary-value: .. index:: value pair: binary format; value - single: abstract syntax; value Values ------ @@ -10,7 +9,6 @@ Values .. _binary-byte: .. index:: byte pair: binary format; byte - single: abstract syntax; byte Bytes ~~~~~ @@ -34,10 +32,6 @@ Bytes pair: binary format; unsigned integer pair: binary format; signed integer pair: binary format; uninterpreted integer - single: abstract syntax; integer - single: abstract syntax; unsigned integer - single: abstract syntax; signed integer - single: abstract syntax; uninterpreted integer Integers ~~~~~~~~ @@ -90,12 +84,11 @@ As an additional constraint, the total number of bytes encoding a value of type .. _binary-float: .. index:: floating-point number pair: binary format; floating-point number - single: abstract syntax; floating-point number Floating-Point ~~~~~~~~~~~~~~ -:ref:`Floating point ` values are encoded directly by their IEEE bit pattern in `little endian `_ byte order: +:ref:`Floating point ` values are encoded directly by their `IEEE 754 `_ bit pattern in `little endian `_ byte order: .. math:: \begin{array}{llclll@{\qquad\qquad}l} @@ -109,7 +102,6 @@ Here, :math:`\F{reverse}(b^\ast)` denotes the byte sequence :math:`b^\ast` in re .. _binary-vec: .. index:: vector pair: binary format; vector - single: abstract syntax; vector Vectors ~~~~~~~ @@ -126,12 +118,11 @@ Vectors .. _binary-name: .. index:: name, byte pair: binary format; name - single: abstract syntax; name Names ~~~~~ -:ref:`Names ` are encoded like a :ref:`vector ` of bytes containing the `UTF-8 `_ encoding of the name's code point sequence. +:ref:`Names ` are encoded like a :ref:`vector ` of bytes containing the `Unicode `_ UTF-8 encoding of the name's code point sequence. .. math:: \begin{array}{llclll@{\qquad}l} diff --git a/document/math.def b/document/math.def index ce89257679..df487e3144 100644 --- a/document/math.def +++ b/document/math.def @@ -104,6 +104,17 @@ .. Values, textual non-terminals .. |Tbyte| mathdef:: \xref{text/values}{text-byte}{\T{byte}} +.. |Tstring| mathdef:: \xref{text/values}{text-string}{\T{string}} + +.. |Tsign| mathdef:: \xref{text/values}{text-sign}{\T{sign}} +.. |Tdigit| mathdef:: \xref{text/values}{text-digit}{\T{digit}} +.. |Thexdigit| mathdef:: \xref{text/values}{text-hexdigit}{\T{hexdigit}} +.. |Tnum| mathdef:: \xref{text/values}{text-num}{\T{num}} +.. |Thexnum| mathdef:: \xref{text/values}{text-hexnum}{\T{hexnum}} +.. |Tfrac| mathdef:: \xref{text/values}{text-frac}{\T{frac}} +.. |Thexfrac| mathdef:: \xref{text/values}{text-hexfrac}{\T{hexfrac}} +.. |Tfloat| mathdef:: \xref{text/values}{text-float}{\T{float}} +.. |Thexfloat| mathdef:: \xref{text/values}{text-hexfloat}{\T{hexfloat}} .. |TuX#1| mathdef:: {\T{u}#1} .. |TsX#1| mathdef:: {\T{s}#1} diff --git a/document/text/conventions.rst b/document/text/conventions.rst index cb401930b4..0569ad3c42 100644 --- a/document/text/conventions.rst +++ b/document/text/conventions.rst @@ -14,6 +14,8 @@ Thus, the attribute grammar implicitly defines a *parsing* function. Except for a few exceptions, the core of the text grammar closely mirrors the grammar of the abstract syntax. However, it also defines a number of forms that are *syntactic sugar* over the core syntax. +The recommended extension for source files containing WebAssembly modules in text format is ":math:`\T{.wat}`". + .. _text-grammar: .. index:: grammar notation, notation @@ -27,11 +29,13 @@ The following conventions are adopted in defining grammar rules for the text for They mirror the conventions used for :ref:`abstract syntax ` and for the :ref:`binary format `. In order to distinguish symbols of the textual syntax from symbols of the abstract syntax, typewriter font is adopted for the former. -* Terminal symbols are strings given in quotes: :math:`\text{module}`. +* Input characters are written as either :ref:`byte values `, :math:`\hex{0A}`, or literal characters of the 7-bit `ASCII `_ character set that represent their respective character codes. + +* Terminal symbols are strings of `ASCII `_ characters enclosed in quotes: :math:`\text{module}`. * Nonterminal symbols are written in typewriter font: :math:`\T{valtype}, \T{instr}`. -* Arbitrary :ref:`white space ` is allowed in any place where the grammar contains spaces. +* Arbitrary :ref:`white space ` is allowed in any place where the grammar contains spaces, except where noted otherwise, such as the :ref:`lexical syntax `. * :math:`T^n` is a sequence of :math:`n\geq 0` iterations of :math:`T`. @@ -72,7 +76,7 @@ In order to distinguish symbols of the textual syntax from symbols of the abstra The attribute of the complete production then is the abstract syntax for the limit, expressed in terms of the former values. -.. _binary-notation: +.. _text-notation: Auxiliary Notation ~~~~~~~~~~~~~~~~~~ diff --git a/document/text/index.rst b/document/text/index.rst index c0acfb8d43..89889e5cfb 100644 --- a/document/text/index.rst +++ b/document/text/index.rst @@ -7,6 +7,7 @@ Text Format :maxdepth: 2 conventions + lexical values types instructions diff --git a/document/text/instructions.rst b/document/text/instructions.rst index bd0904d045..9f3fbb4a45 100644 --- a/document/text/instructions.rst +++ b/document/text/instructions.rst @@ -22,7 +22,6 @@ Instructions .. _text-instr-control: .. index:: control instructions, structured control, label, block, branch, result type, label index, function index, type index, vector, polymorphism pair: text format; instruction - single: abstract syntax; instruction Control Instructions ~~~~~~~~~~~~~~~~~~~~ @@ -70,7 +69,6 @@ Control Instructions .. _text-instr-parametric: .. index:: value type, polymorphism pair: text format; instruction - single: abstract syntax; instruction Parametric Instructions ~~~~~~~~~~~~~~~~~~~~~~~ @@ -89,7 +87,6 @@ Parametric Instructions .. _text-instr-variable: .. index:: variable instructions, local index, global index pair: text format; instruction - single: abstract syntax; instruction Variable Instructions ~~~~~~~~~~~~~~~~~~~~~ @@ -115,7 +112,6 @@ Variable Instructions .. _text-memarg: .. index:: memory instruction, memory index pair: text format; instruction - single: abstract syntax; instruction Memory Instructions ~~~~~~~~~~~~~~~~~~~ @@ -170,7 +166,6 @@ Memory Instructions .. _text-instr-numeric: .. index:: numeric instruction pair: text format; instruction - single: abstract syntax; instruction Numeric Instructions ~~~~~~~~~~~~~~~~~~~~ @@ -388,7 +383,6 @@ Folded Instructions .. _text-expr: .. index:: expression pair: text format; expression - single: abstract syntax; expression single: expression; constant Expressions diff --git a/document/text/lexical.rst b/document/text/lexical.rst new file mode 100644 index 0000000000..ed2435b635 --- /dev/null +++ b/document/text/lexical.rst @@ -0,0 +1,78 @@ +.. index:: lexical format + +Lexical Format +-------------- + +The text format is assumed to be represented in a superset of `7-bit ASCII `_. +Only printable 7-bit ASCII characters are interpreted in this format, +hence any compatible character encoding, such as `Unicode UTF-8 `_ is applicable. + + +.. _text-stoken: +.. index:: ! token + +Tokens +~~~~~~ + +The character stream in the source text is divided into a sequence of *tokens*. +In this specification, tokens are either defined explicitly by grammar rules, +such as the lexical syntax of :ref:`values `, +or implicitly, by the occurrence of terminal symbols in string form in the non-lexical grammar. + +Tokens are consumed from the input character stream according to the *longest match* rule. +That is, the next token always consists of the longest possible sequence of characters that is recognized as a token. + +Tokens may explicitly be separated by :ref:`space ` characters or :ref:`comments `, +collectively called :ref:`white space `. +White space cannot appear inside a token. + + + +.. _text-space: +.. _text-whitespace: +.. index:: ! white space + +White Space +~~~~~~~~~~~ + +*White space* is any sequence of *space* characters or :ref:`comments `. + +A space character either is the `ASCII `_ *space* (byte :math:`\hex{20}`) or an ASCII *format effector*, that is, *backspace* (:math:`\hex{08}`), *horizontal tabulation* (:math:`\hex{09}`), *line feed* (:math:`\hex{0A}`), *vertical tabulation* (:math:`\hex{0B}`), *form feed* (:math:`\hex{0C}`), or *carriage return* (:math:`\hex{0D}`). + +.. math:: + \begin{array}{llclll@{\qquad\qquad}l} + \production{white space} & \T{whitespace} &::=& + (\T{space} ~|~ \T{comment})^\ast \\ + \production{space} & \T{space} &::=& + \hex{20} ~|~ \hex{08} ~|~ \hex{09} ~|~ \hex{0A} ~|~ \hex{0B} ~|~ \hex{0C} ~|~ \hex{0D} \\ + \end{array} + + +.. text-comment: +.. index:: ! comments + +Comments +~~~~~~~~ + +A *comment* can either be a *line comment*, started with a double semicolon :math:`\text{;\!;}` and extending to the end of the line, +or a *block comment*, enclosed in :math:`\text{(\!;} \dots \text{;\!)}`. +Block comments can be nested. + +.. math:: + \begin{array}{llclll@{\qquad\qquad}l} + \production{comment} & \T{comment} &::=& + \T{linecomment} ~|~ \T{blockcomment} \\ + \production{line comment} & \T{linecomment} &::=& + \text{;\!;}~~\T{linecontent}^\ast~~(\hex{0A} ~|~ \T{eof}) \\ + \production{line content} & \T{linecontent} &::=& + b & (b \neq \hex{0A}) \\ + \production{block comment} & \T{blockcomment} &::=& + \text{(\!;}~~\T{blockcontent}^\ast~~\text{;\!)} \\ + \production{block content} & \T{blockcontent} &::=& + b & (b \neq \text{;} \wedge b \neq \text{(}) \\ &&|& + \text{;}~b & (b \neq \text{)}) \\ &&|& + \text{(}~b & (b \neq \text{;}) \\ &&|& + \T{blockcomment} \\ + \end{array} + +Here, the pseudo token :math:`\T{eof}` indicates the end of the input. diff --git a/document/text/types.rst b/document/text/types.rst index 04a6651731..0d3be7ace8 100644 --- a/document/text/types.rst +++ b/document/text/types.rst @@ -1,7 +1,6 @@ .. _text-type: .. index:: type pair: text format; type - single: abstract syntax; type Types ----- @@ -9,7 +8,6 @@ Types .. _text-valtype: .. index:: value type pair: text format; value type - single: abstract syntax; value type Value Types ~~~~~~~~~~~ @@ -27,7 +25,6 @@ Value Types .. _text-resulttype: .. index:: result type, value type pair: text format; result type - single: abstract syntax; result type Block Types ~~~~~~~~~~~ @@ -45,7 +42,6 @@ Block Types .. _text-functype: .. index:: function type, value type, result type pair: text format; function type - single: abstract syntax; function type Function Types ~~~~~~~~~~~~~~ @@ -67,7 +63,6 @@ Function Types .. _text-limits: .. index:: limits pair: text format; limits - single: abstract syntax; limits Limits ~~~~~~ @@ -82,8 +77,7 @@ Limits .. _text-memtype: .. index:: memory type, limits, page size - single: text format; memory type - pair: abstract syntax; memory type + pair: text format; memory type Memory Types ~~~~~~~~~~~~ @@ -100,8 +94,6 @@ Memory Types .. index:: table type, element type, limits pair: text format; table type pair: text format; element type - single: abstract syntax; table type - single: abstract syntax; element type Table Types ~~~~~~~~~~~ @@ -119,8 +111,6 @@ Table Types .. index:: global type, mutability, value type pair: text format; global type pair: text format; mutability - single: abstract syntax; global type - single: abstract syntax; mutability Global Types ~~~~~~~~~~~~ diff --git a/document/text/values.rst b/document/text/values.rst index eb81d81c87..248566279a 100644 --- a/document/text/values.rst +++ b/document/text/values.rst @@ -1,33 +1,17 @@ .. _text-value: .. index:: value pair: text format; value - single: abstract syntax; value Values ------ - -.. text-byte: -.. index:: byte - pair: text format; byte - single: abstract syntax; byte - -Bytes -~~~~~ - -.. todo:: needed? - -:ref:`Bytes ` encode themselves. - -.. math:: - \begin{array}{llcll@{\qquad}l} - \production{bytes} & \Bbyte &::=& - \hex{00} &\Rightarrow& \hex{00} \\ &&|&& - \dots \\ &&|& - \hex{FF} &\Rightarrow& \hex{FF} \\ - \end{array} +The grammar produtions in this section define *lexical syntax*, +hence no :ref:`white space ` is allowed. +.. _text-sign: +.. _text-digit: +.. _text-hexdigit: .. _text-int: .. _text-sint: .. _text-uint: @@ -36,133 +20,171 @@ Bytes pair: text format; unsigned integer pair: text format; signed integer pair: text format; uninterpreted integer - single: abstract syntax; integer - single: abstract syntax; unsigned integer - single: abstract syntax; signed integer - single: abstract syntax; uninterpreted integer Integers ~~~~~~~~ -All :ref:`integers ` are encoded using the `LEB128 `_ variable-length integer encoding, in either unsigned or signed variant. - -:ref:`Unsigned integers ` are encoded in `unsigned LEB128 `_ format. -As an additional constraint, the total number of bytes encoding a value of type :math:`\uX{N}` must not exceed :math:`\F{ceil}(N/7)` bytes. +All :ref:`integers ` can be written in either decimal or hexadecimal notation. .. math:: \begin{array}{llclll@{\qquad}l} - \production{unsigned integers} & \BuX{N} &::=& - n{:}\Bbyte &\Rightarrow& n & (n < 2^7 \wedge n < 2^N) \\ &&|& - n{:}\Bbyte~~m{:}\BuX{N-7} &\Rightarrow& - 2^7\cdot m + (n-2^7) & (n \geq 2^7 \wedge N > 7) \\ + \production{sign} & \Tsign &::=& + \epsilon \Rightarrow {+}1 ~|~ + \text{+} \Rightarrow {+}1 ~|~ + \text{-} \Rightarrow {-}1 \\ + \production{decimal digit} & \Tdigit &::=& + \text{0} \Rightarrow 0 ~|~ \dots ~|~ \text{9} \Rightarrow 9 \\ + \production{hexadecimal digit} & \Thexdigit &::=& + d{:}\Tdigit \Rightarrow d \\ &&|& + \text{A} \Rightarrow 10 ~|~ \dots ~|~ \text{F} \Rightarrow 15 \\ &&|& + \text{a} \Rightarrow 10 ~|~ \dots ~|~ \text{f} \Rightarrow 15 \\ + \production{decimal number} & \Tnum &::=& + d{:}\Tdigit &\Rightarrow& d \\ &&|& + n{:}\Tnum~~d{:}\Tdigit &\Rightarrow& 10\cdot n + d \\ + \production{hexadecimal number} & \Thexnum &::=& + \text{0x}~~h{:}\Thexdigit &\Rightarrow& h \\ &&|& + n{:}\Thexnum~~h{:}\Thexdigit &\Rightarrow& 16\cdot n + h \\ \end{array} -:ref:`Signed integers ` are encoded in `signed LEB128 `_ format, which uses a 2's complement representation. -As an additional constraint, the total number of bytes encoding a value of type :math:`\sX{N}` must not exceed :math:`\F{ceil}(N/7)` bytes. +Integer literals are distinguished by size and signedness. +Their value must lie within the range of the respective type. .. math:: \begin{array}{llclll@{\qquad}l} - \production{signed integers} & \BsX{N} &::=& - n{:}\Bbyte &\Rightarrow& n & (n < 2^6 \wedge n < 2^{N-1}) \\ &&|& - n{:}\Bbyte &\Rightarrow& n-2^7 & (2^6 \leq n < 2^7 \wedge n \geq 2^7-2^{N-1}) \\ &&|& - n{:}\Bbyte~~m{:}\BsX{N-7} &\Rightarrow& - 2^7\cdot m + (n-2^7) & (n \geq 2^7 \wedge N > 7) \\ + \production{unsigned integer} & \TuX{N} &::=& + n{:}\Tnum &\Rightarrow& n & (n < 2^N) \\ &&|& + n{:}\Thexnum &\Rightarrow& n & (n < 2^N) \\ + \production{signed integer} & \TsX{N} &::=& + s{:}\Tsign~~n{:}\Tnum &\Rightarrow& s\cdot n & (-2^{N-1} \leq s\cdot n < 2^{N-1}) \\ &&|& + s{:}\Tsign~~n{:}\Thexnum &\Rightarrow& s\cdot n & (-2^{N-1} \leq s\cdot n < 2^{N-1}) \\ \end{array} -:ref:`Uninterpreted integers ` are always encoded as signed integers. +:ref:`Uninterpreted integers ` can be written as either signed or unsigned, and are normalized to unsigned in the abstract syntax. .. math:: \begin{array}{llclll@{\qquad\qquad}l} - \production{uninterpreted integers} & \BiX{N} &::=& - n{:}\BsX{N} &\Rightarrow& n + \production{uninterpreted integers} & \TiX{N} &::=& + n{:}\TuX{N} &\Rightarrow& n \\ &&|& + i{:}\TsX{N} &\Rightarrow& n & (i = \signed(n)) \\ \end{array} -.. note:: - While the side conditions :math:`N > 7` in the productions for *non-terminating* bytes restrict the length of the :math:`\uX{}` and :math:`\sX{}` encodings, - "trailing zeros" are still allowed within these bounds. - For example, :math:`\hex{03}` and :math:`\hex{83}~\hex{00}` are both well-formed encodings for the value :math:`3` as a |u8|. - Similarly, either of :math:`\hex{7e}` and :math:`\hex{FE}~\hex{7F}` and :math:`\hex{FE}~\hex{FF}~\hex{7F}` are well-formed encodings of the value :math:`-2` as a |s16|. - - The side conditions on the value :math:`n` of *terminating* bytes further enforce that - any unused bits in these bytes must be :math:`0` for positive values and :math:`1` for negative ones. - For example, :math:`\hex{83}~\hex{10}` is malformed as a |u8| encoding. - Similarly, both :math:`\hex{83}~\hex{3E}` and :math:`\hex{FF}~\hex{7B}` are malformed as |s8| encodings. - -.. _binary-float: +.. _text-frac: +.. _text-hexfrac: +.. _text-float: +.. _text-hexfloat: .. index:: floating-point number - pair: binary format; floating-point number - single: abstract syntax; floating-point number + pair: text format; floating-point number Floating-Point ~~~~~~~~~~~~~~ -:ref:`Floating point ` values are encoded directly by their IEEE bit pattern in `little endian `_ byte order: +:ref:`Floating point ` values can be represented in either decimal or hexadecimal notation. +The value must not be outside the representable range of the corresponding `IEEE 754 `_ type +(that is, it must not overflow to infinity), +but it may be rounded to the nearest representable value. + +.. note:: + Rounding can be avoided by using hexadecimal notation with no more significant bits than supported by the desired type. + +Floating-point values may also be written as constants for *infinity* or *canonical NaN* (*not a number*). +Furthermore, arbitrary NaN values may be expressed by providing an explicit payload value. .. math:: \begin{array}{llclll@{\qquad\qquad}l} - \production{floating-point numbers} & \BfX{N} &::=& - b^\ast{:\,}\Bbyte^{N/8} &\Rightarrow& \F{reverse}(b^\ast) \\ + \production{decimal floating-point fraction} & \Tfrac &::=& + \epsilon &\Rightarrow& 0 \\ &&|& + d{:}\Tdigit~q{:}\Tfrac &\Rightarrow& (d+q)/10 \\ + \production{hexadecimal floating-point fraction} & \Thexfrac &::=& + \epsilon &\Rightarrow& 0 \\ &&|& + h{:}\Thexdigit~q{:}\Thexfrac &\Rightarrow& (h+q)/16 \\ + \production{decimal floating-point number} & \Tfloat &::=& + s{:}\Tsign~p{:}\Tnum~\text{.}~q{:}\Tfrac + &\Rightarrow& s\cdot(p+q) \\ &&|& + s{:}\Tsign~p{:}\Tnum~(\text{E}~|~\text{e})~t{:}\Tsign~e{:}\Tnum + &\Rightarrow& s\cdot p\cdot 10^{t\cdot e} \\ &&|& + s{:}\Tsign~p{:}\Tnum~\text{.}~q{:}\Tfrac~(\text{E}~|~\text{e})~t{:}\Tsign~e{:}\Tnum + &\Rightarrow& s\cdot(p+q)\cdot 10^{t\cdot e} \\ + \production{hexadecimal floating-point number} & \Thexfloat &::=& + s{:}\Tsign~p{:}\Thexnum~\text{.}~q{:}\Thexfrac + &\Rightarrow& s\cdot(p+q) \\ &&|& + s{:}\Tsign~p{:}\Thexnum~(\text{P}~|~\text{p})~t{:}\Tsign~e{:}\Tnum + &\Rightarrow& s\cdot p\cdot 2^{t\cdot e} \\ &&|& + s{:}\Tsign~p{:}\Thexnum~\text{.}~q{:}\Thexfrac~(\text{P}~|~\text{p})~t{:}\Tsign~e{:}\Tnum + &\Rightarrow& s\cdot(p+q)\cdot 2^{t\cdot e} \\ + \production{floating-point value} & \TfX{N} &::=& + z{:}\Tfloat &\Rightarrow& b^\ast & (\ieee_N(z) = b^\ast) \\ &&|& + z{:}\Thexfloat &\Rightarrow& b^\ast & (\ieee_N(z) = b^\ast) \\ &&|& + s{:}\Tsign~\text{inf} &\Rightarrow& b^\ast & (\ieeeinf_N(s) = b^\ast) \\ &&|& + s{:}\Tsign~\text{nan} &\Rightarrow& b^\ast & (\ieeenan_N(s, 0) = b^\ast) \\ &&|& + s{:}\Tsign~\text{nan\!:}~n{:}\Thexnum &\Rightarrow& b^\ast & (\ieeenan_N(s, n) = b^\ast) \\ \end{array} -Here, :math:`\F{reverse}(b^\ast)` denotes the byte sequence :math:`b^\ast` in reversed order. - -.. _binary-vec: +.. _text-vec: .. index:: vector - pair: binary format; vector - single: abstract syntax; vector + pair: text format; vector Vectors ~~~~~~~ -:ref:`Vectors ` are encoded with their length followed by the encoding of their element sequence. +:ref:`Vectors ` are written as ordinary sequences, but with restricted length. + +.. math:: + \begin{array}{llclll@{\qquad\qquad}l} + \production{vector} & \Tvec(\T{A}) &::=& + (x{:}\T{A})^n &\Rightarrow& x^n & (n < 2^{32}) \\ + \end{array} + + +.. _text-byte: +.. _text-string: +.. index:: byte, string + pair: text format; byte + pair: text format; string + +Strings +~~~~~~~ + +*Strings* are sequences of bytes that can represent both textual and binary data. +They are enclosed in `ASCII `_ *quotation marks* (bytes of value \hex{22}) +and may contain any byte that is not an ASCII *quotation marks* (\hex{22}) or ASCII *reverse slant* (backslash, \hex{5C}), +or an *escape sequence* started by an ASCII *reverse slant* (\hex{5C}). .. math:: \begin{array}{llclll@{\qquad\qquad}l} - \production{vectors} & \Bvec(\B{B}) &::=& - n{:}\Bu32~~(x{:}\B{B})^n &\Rightarrow& x^n \\ + \production{byte} & \Tbyte &::=& + b &\Rightarrow& b & (b \neq \text{\backslash} \wedge b \neq \text{"}) \\ &&|& + \text{\backslash}~n{:}\Thexdigit~m{:}\Thexdigit &\Rightarrow& 16\cdot n+m \\ &&|& + \text{\backslash{}t} &\Rightarrow& \hex{09} \\ &&|& + \text{\backslash{}n} &\Rightarrow& \hex{0A} \\ &&|& + \text{\backslash{}"} &\Rightarrow& \hex{22} \\ &&|& + \text{\backslash{}'} &\Rightarrow& \hex{27} \\ &&|& + \text{\backslash\backslash} &\Rightarrow& \hex{5C} \\ + \production{string} & \Tstring &::=& + \text{"}~(b{:}\Tbyte)^\ast~\text{"} + &\Rightarrow& b^\ast \\ \end{array} +.. note:: + Any byte value may occur in a string, + including :math:`\hex{00}` or ASCII control characters. + The bytes are not interpreted in any specific way, + except when the string appears as a :ref:`name `. + -.. _binary-name: +.. _text-name: .. index:: name, byte - pair: binary format; name - single: abstract syntax; name + pair: text format; name Names ~~~~~ -:ref:`Names ` are encoded like a :ref:`vector ` of bytes containing the `UTF-8 `_ encoding of the name's code point sequence. +:ref:`Names ` are strings denoting a byte sequence that must form a valid `Unicode `_ UTF-8 encoding. .. math:: \begin{array}{llclll@{\qquad}l} - \production{names} & \Bname &::=& - n{:}\Bu32~~(\X{uc}{:}\Bcodepoint)^\ast &\Rightarrow& \X{uc}^\ast - & (|\Bcodepoint^\ast| = n) \\ - \production{code points} & \Bcodepoint &::=& - \X{uv}{:}\Bcodeval_N &\Rightarrow& \X{uv} - & (\X{uv} \geq N \wedge (\X{uv} < \unicode{D800} \vee \unicode{E000} \leq \X{uv} < \unicode{110000})) \\ - \production{code values} & \Bcodeval_N &::=& - b_1{:}\Bbyte &\Rightarrow& - b_1 - & (b_1 < \hex{80} \wedge N = \unicode{00}) \\ &&|& - b_1{:}\Bbyte~~b_2{:}\Bcodecont &\Rightarrow& - 2^6\cdot(b_1-\hex{c0}) + b_2 - & (\hex{c0} \leq b_1 < \hex{e0} \wedge N = \unicode{80}) \\ &&|& - b_1{:}\Bbyte~~b_2{:}\Bcodecont~~b_3{:}\Bcodecont &\Rightarrow& - 2^{12}\cdot(b_1-\hex{e0}) + 2^6\cdot b_2 + b_3 - & (\hex{e0} \leq b_1 < \hex{f0} \wedge N = \unicode{800}) \\ &&|& - b_1{:}\Bbyte~~b_2{:}\Bcodecont~~b_3{:}\Bcodecont~~b_4{:}\Bcodecont - &\Rightarrow& - 2^{18}\cdot(b_1-\hex{f0}) + 2^{12}\cdot b_2 + 2^6\cdot b_3 + b_4 - & (\hex{f0} \leq b_1 < \hex{f8} \wedge N = \unicode{10000}) \\ - \production{code continuation} & \Bcodecont &::=& - b{:}\Bbyte &\Rightarrow& b - \hex{80} & (b \geq \hex{80}) \\ + \production{name} & \Tname &::=& + b^\ast{:}\Tstring &\Rightarrow& \X{uc}^n + & (\utf8(\X{uc}^n) = b^\ast \wedge n < 2^{32}) \\ \end{array} - -.. note:: - The :ref:`size `, :math:`||\Bcodepoint^\ast||` denotes the number of bytes in the encoding of the sequence, not the number of code points. - - The index :math:`N` to |Bcodeval| is the minimum value that a given byte sequence may decode into. - The respective side conditions on it exclude encodings using more than the minimal number of bytes to represent a code point. diff --git a/interpreter/spec/float.ml b/interpreter/spec/float.ml index a2f2f007a6..25572bfc42 100644 --- a/interpreter/spec/float.ml +++ b/interpreter/spec/float.ml @@ -226,4 +226,3 @@ struct (* TODO: use sprintf "%h" once we have upgraded to OCaml 4.03 *) string_of_float (to_float a) end - diff --git a/interpreter/text/lexer.mll b/interpreter/text/lexer.mll index 70f4a9c34e..8883593b84 100644 --- a/interpreter/text/lexer.mll +++ b/interpreter/text/lexer.mll @@ -80,15 +80,13 @@ let ext e s u = let opt = Lib.Option.get } -let space = [' ''\t'] +let space = [' ''\x08'-'\x09''\x0b'-'\x0d'] let digit = ['0'-'9'] let hexdigit = ['0'-'9''a'-'f''A'-'F'] let letter = ['a'-'z''A'-'Z'] -let symbol = ['+''-''*''/''\\''^''~''=''<''>''!''?''@''#''$''%''&''|'':''`''.'] -let tick = '\'' +let symbol = ['+''-''*''/''\\''^''~''=''<''>''!''?''@''#''$''%''&''|'':''`''.''\''] let escape = ['n''t''\\''\'''\"'] -let character = - [^'"''\\''\x00'-'\x1f''\x7f'] | '\\'escape | '\\'hexdigit hexdigit +let character = [^'"''\\'] | '\\'escape | '\\'hexdigit hexdigit let sign = ('+' | '-') let num = digit+ @@ -98,13 +96,14 @@ let int = sign nat let float = sign? num '.' digit* | sign? num ('.' digit*)? ('e' | 'E') sign? num - | sign? "0x" hexdigit+ '.'? hexdigit* ('e' | 'E' | 'p') sign? digit+ + | sign? hexnum '.' hexdigit* + | sign? hexnum ('.' hexdigit*)? ('p' | 'P') sign? num | sign? "inf" | sign? "infinity" | sign? "nan" - | sign? "nan:0x" hexdigit+ + | sign? "nan:" hexnum let text = '"' character* '"' -let name = '$' (letter | digit | '_' | tick | symbol)+ +let name = '$' (letter | digit | '_' | symbol)+ let ixx = "i" ("32" | "64") let fxx = "f" ("32" | "64") @@ -122,8 +121,6 @@ rule token = parse | float as s { FLOAT s } | text as s { TEXT (text s) } | '"'character*('\n'|eof) { error lexbuf "unclosed text literal" } - | '"'character*['\x00'-'\x09''\x0b'-'\x1f''\x7f'] - { error lexbuf "illegal control character in text literal" } | '"'character*'\\'_ { error_nest (Lexing.lexeme_end_p lexbuf) lexbuf "illegal escape" } From 748ccac326ea30839d39402c129a5fb8807b37b6 Mon Sep 17 00:00:00 2001 From: Andreas Rossberg Date: Thu, 4 May 2017 01:23:55 +0200 Subject: [PATCH 04/30] Disallow control characters in strings --- document/text/lexical.rst | 6 +++++- document/text/values.rst | 11 +++++------ interpreter/text/lexer.mll | 10 +++++++--- 3 files changed, 17 insertions(+), 10 deletions(-) diff --git a/document/text/lexical.rst b/document/text/lexical.rst index ed2435b635..a3986130a3 100644 --- a/document/text/lexical.rst +++ b/document/text/lexical.rst @@ -3,10 +3,14 @@ Lexical Format -------------- -The text format is assumed to be represented in a superset of `7-bit ASCII `_. +The text format is represented in a superset of `7-bit ASCII `_. Only printable 7-bit ASCII characters are interpreted in this format, hence any compatible character encoding, such as `Unicode UTF-8 `_ is applicable. +.. note:: + Non-ASCII bytes can only occur in :ref:`comments ` and :ref:`string literals `. + Similarly, ASCII control characters other than :ref:`white space ` can only occur in :ref:`comments `. + .. _text-stoken: .. index:: ! token diff --git a/document/text/values.rst b/document/text/values.rst index 248566279a..f8515b52b5 100644 --- a/document/text/values.rst +++ b/document/text/values.rst @@ -148,16 +148,17 @@ Strings *Strings* are sequences of bytes that can represent both textual and binary data. They are enclosed in `ASCII `_ *quotation marks* (bytes of value \hex{22}) -and may contain any byte that is not an ASCII *quotation marks* (\hex{22}) or ASCII *reverse slant* (backslash, \hex{5C}), -or an *escape sequence* started by an ASCII *reverse slant* (\hex{5C}). +and may contain any byte that is not an ASCII control character, ASCII *quotation marks* (\hex{22}), or ASCII *reverse slant* (backslash, \hex{5C}), +except when expressed with an *escape sequence* started by an ASCII *reverse slant* (\hex{5C}). .. math:: \begin{array}{llclll@{\qquad\qquad}l} \production{byte} & \Tbyte &::=& - b &\Rightarrow& b & (b \neq \text{\backslash} \wedge b \neq \text{"}) \\ &&|& + b &\Rightarrow& b & (\hex{20} \leq b < \hex{7F} \wedge b \neq \text{"} \wedge b \neq \text{\backslash}) \\ &&|& \text{\backslash}~n{:}\Thexdigit~m{:}\Thexdigit &\Rightarrow& 16\cdot n+m \\ &&|& \text{\backslash{}t} &\Rightarrow& \hex{09} \\ &&|& \text{\backslash{}n} &\Rightarrow& \hex{0A} \\ &&|& + \text{\backslash{}r} &\Rightarrow& \hex{0D} \\ &&|& \text{\backslash{}"} &\Rightarrow& \hex{22} \\ &&|& \text{\backslash{}'} &\Rightarrow& \hex{27} \\ &&|& \text{\backslash\backslash} &\Rightarrow& \hex{5C} \\ @@ -167,9 +168,7 @@ or an *escape sequence* started by an ASCII *reverse slant* (\hex{5C}). \end{array} .. note:: - Any byte value may occur in a string, - including :math:`\hex{00}` or ASCII control characters. - The bytes are not interpreted in any specific way, + The bytes in a string are not interpreted in any specific way, except when the string appears as a :ref:`name `. diff --git a/interpreter/text/lexer.mll b/interpreter/text/lexer.mll index 8883593b84..cd9ba11f31 100644 --- a/interpreter/text/lexer.mll +++ b/interpreter/text/lexer.mll @@ -84,9 +84,11 @@ let space = [' ''\x08'-'\x09''\x0b'-'\x0d'] let digit = ['0'-'9'] let hexdigit = ['0'-'9''a'-'f''A'-'F'] let letter = ['a'-'z''A'-'Z'] -let symbol = ['+''-''*''/''\\''^''~''=''<''>''!''?''@''#''$''%''&''|'':''`''.''\''] -let escape = ['n''t''\\''\'''\"'] -let character = [^'"''\\'] | '\\'escape | '\\'hexdigit hexdigit +let symbol = + ['+''-''*''/''\\''^''~''=''<''>''!''?''@''#''$''%''&''|'':''`''.''\''] +let escape = ['n''r''t''\\''\'''\"'] +let character = + [^'"''\\''\x00'-'\x1f''\x7f'] | '\\'escape | '\\'hexdigit hexdigit let sign = ('+' | '-') let num = digit+ @@ -121,6 +123,8 @@ rule token = parse | float as s { FLOAT s } | text as s { TEXT (text s) } | '"'character*('\n'|eof) { error lexbuf "unclosed text literal" } + | '"'character*['\x00'-'\x09''\x0b'-'\x1f''\x7f'] + { error lexbuf "illegal control character in text literal" } | '"'character*'\\'_ { error_nest (Lexing.lexeme_end_p lexbuf) lexbuf "illegal escape" } From 006f359d4503926ebde9923b78ba50df1b6d3137 Mon Sep 17 00:00:00 2001 From: rossberg-chromium Date: Thu, 4 May 2017 17:48:09 +0200 Subject: [PATCH 05/30] Lexical; index context --- document/math.def | 18 +++++ document/text/conventions.rst | 36 ++++++++- document/text/instructions.rst | 82 +++++++++---------- document/text/lexical.rst | 87 ++++++++++++-------- document/text/modules.rst | 143 ++++++++++++++++++--------------- document/text/values.rst | 100 ++++++++++++++++++----- 6 files changed, 299 insertions(+), 167 deletions(-) diff --git a/document/math.def b/document/math.def index df487e3144..ee40e2d01b 100644 --- a/document/math.def +++ b/document/math.def @@ -22,6 +22,20 @@ .. Auxiliary definitions for grammars .. |production| mathdef:: \void +.. |with| mathdef:: ~\xref{syntax/conventions}{syntax-record}{\mbox{with}}~ + + +.. Lexical grammar + +.. |Tchar| mathdef:: \xref{text/lexical}{text-char}{\T{char}} +.. |Tspace| mathdef:: \xref{text/lexical}{text-space}{\T{space}} +.. |Tformat| mathdef:: \xref{text/lexical}{text-format}{\T{format}} + +.. |Tcomment| mathdef:: \xref{text/lexical}{text-comment}{\T{comment}} +.. |Tlinecomment| mathdef:: \xref{text/lexical}{text-comment}{\T{linecomment}} +.. |Tblockcomment| mathdef:: \xref{text/lexical}{text-comment}{\T{blockcomment}} +.. |Tlinechar| mathdef:: \xref{text/lexical}{text-comment}{\T{linechar}} +.. |Tblockchar| mathdef:: \xref{text/lexical}{text-comment}{\T{blockchar}} .. Values, terminals @@ -105,6 +119,7 @@ .. |Tbyte| mathdef:: \xref{text/values}{text-byte}{\T{byte}} .. |Tstring| mathdef:: \xref{text/values}{text-string}{\T{string}} +.. |Tstringchar| mathdef:: \xref{text/values}{text-string}{\T{stringchar}} .. |Tsign| mathdef:: \xref{text/values}{text-sign}{\T{sign}} .. |Tdigit| mathdef:: \xref{text/values}{text-digit}{\T{digit}} @@ -146,6 +161,9 @@ .. |Tcodeval| mathdef:: \xref{text/values}{text-name}{\T{codeval}} .. |Tcodecont| mathdef:: \xref{text/values}{text-name}{\T{cont}} +.. |Tid| mathdef:: \xref{text/values}{text-id}{\T{id}} +.. |Tidchar| mathdef:: \xref{text/values}{text-id}{\T{idchar}} + .. Types, terminals diff --git a/document/text/conventions.rst b/document/text/conventions.rst index 0569ad3c42..bbcc2faf75 100644 --- a/document/text/conventions.rst +++ b/document/text/conventions.rst @@ -29,9 +29,7 @@ The following conventions are adopted in defining grammar rules for the text for They mirror the conventions used for :ref:`abstract syntax ` and for the :ref:`binary format `. In order to distinguish symbols of the textual syntax from symbols of the abstract syntax, typewriter font is adopted for the former. -* Input characters are written as either :ref:`byte values `, :math:`\hex{0A}`, or literal characters of the 7-bit `ASCII `_ character set that represent their respective character codes. - -* Terminal symbols are strings of `ASCII `_ characters enclosed in quotes: :math:`\text{module}`. +* Terminal symbols are strings of characters enclosed in quotes: :math:`\text{module}`. * Nonterminal symbols are written in typewriter font: :math:`\T{valtype}, \T{instr}`. @@ -84,3 +82,35 @@ Auxiliary Notation When dealing with binary encodings the following notation is also used: * :math:`\epsilon` denotes the empty byte sequence. + + +.. text-context: +.. index:: ! identifier context, identifier, index, index space + +Contexts +~~~~~~~~ + +The text format allows to use symbolic :ref:`identifiers ` in place of :ref:`indices `. +To resolve these identifiers into concrete indices, +some grammar production are indexed by an *identifier context* that records the declared identifiers in each :ref:`index space `. + +It is convenient to define identifier contexts as :ref:`records ` :math:`I` with abstract syntax: + +.. math:: + \begin{array}{llll} + \production{(identifier context)} & I &::=& + \begin{array}[t]{l@{~}ll} + \{ & \TYPES & (\Tid^?)^\ast, \\ + & \FUNCS & (\Tid^?)^\ast, \\ + & \TABLES & (\Tid^?)^\ast, \\ + & \MEMS & (\Tid^?)^\ast, \\ + & \GLOBALS & (\Tid^?)^\ast, \\ + & \LOCALS & (\Tid^?)^\ast, \\ + & \LABELS & (\Tid^?)^\ast ~\} \\ + \end{array} + \end{array} + +For each index space, an identifier context contains the list of :ref:`identifiers ` assigned to the defined indices. +Unnamed indices are associated with empty (:math:`\epsilon`) entries in these lists. + +It is an invariant of the specification that no component contains duplicate identifiers. diff --git a/document/text/instructions.rst b/document/text/instructions.rst index 9f3fbb4a45..efe8b416ca 100644 --- a/document/text/instructions.rst +++ b/document/text/instructions.rst @@ -9,12 +9,12 @@ Instructions .. math:: \begin{array}{llclll} - \production{instruction} & \Tinstr_C &::=& - \X{in}{:}\Tplaininstr + \production{instruction} & \Tinstr_I &::=& + \X{in}{:}\Tplaininstr_I &\Rightarrow& \X{in} \\ &&|& - \X{in}{:}\Tblockinstr_C + \X{in}{:}\Tblockinstr_I &\Rightarrow& \X{in} \\ &&|& - \X{in}^\ast{:}\Tfoldedinstr_C + \X{in}^\ast{:}\Tfoldedinstr_I &\Rightarrow& \X{in}^\ast \\ \end{array} @@ -40,26 +40,26 @@ Control Instructions .. math:: \begin{array}{llclll} - \production{block instruction} & \Tblockinstr_C &::=& - \text{block}~~\X{rt}{:}\Tblocktype~~(\X{in}{:}\Tinstr_{C'})^\ast~~\text{end} + \production{block instruction} & \Tblockinstr_I &::=& + \text{block}~~I'{:}\Tlabelbind_I~~\X{rt}{:}\Tblocktype~~(\X{in}{:}\Tinstr_{I'})^\ast~~\text{end} &\Rightarrow& \BLOCK~\X{rt}~\X{in}^\ast~\END \\ &&|& - \text{loop}~~\X{rt}{:}\Tblocktype~~(\X{in}{:}\Tinstr_{C'})^\ast~~\text{end} + \text{loop}~~I'{:}\Tlabelbind_I~~\X{rt}{:}\Tblocktype~~(\X{in}{:}\Tinstr_{I'})^\ast~~\text{end} &\Rightarrow& \LOOP~\X{rt}~\X{in}^\ast~\END \\ &&|& - \text{if}~~\X{rt}{:}\Tblocktype~~(\X{in}{:}\Tinstr_{C'})^\ast~~\text{end} + \text{if}~~I'{:}\Tlabelbind_I~~\X{rt}{:}\Tblocktype~~(\X{in}{:}\Tinstr_{I'})^\ast~~\text{end} &\Rightarrow& \IF~\X{rt}~\X{in}^\ast~\ELSE~\epsilon~\END \\ &&|& - \text{if}~~\X{rt}{:}\Tblocktype~~(\X{in}_1{:}\Tinstr_{C'})^\ast~~ - \text{else}~~(\X{in}_2{:}\Tinstr_{C'})^\ast~~\text{end} + \text{if}~~I'{:}\Tlabelbind_I~~\X{rt}{:}\Tblocktype~~(\X{in}_1{:}\Tinstr_{I'})^\ast~~ + \text{else}~~(\X{in}_2{:}\Tinstr_{I'})^\ast~~\text{end} &\Rightarrow& \IF~\X{rt}~\X{in}_1^\ast~\ELSE~\X{in}_2^\ast~\END \\ - \production{plain instruction} & \Tplaininstr &::=& + \production{plain instruction} & \Tplaininstr_I &::=& \text{unreachable} &\Rightarrow& \UNREACHABLE \\ &&|& \text{nop} &\Rightarrow& \NOP \\ &&|& - \text{br}~~l{:}\Tlabelidx &\Rightarrow& \BR~l \\ &&|& - \text{br\_if}~~l{:}\Tlabelidx &\Rightarrow& \BRIF~l \\ &&|& - \text{br\_table}~~l^\ast{:}\Tvec(\Tlabelidx)~~l_N{:}\Tlabelidx + \text{br}~~l{:}\Tlabelidx_I &\Rightarrow& \BR~l \\ &&|& + \text{br\_if}~~l{:}\Tlabelidx_I &\Rightarrow& \BRIF~l \\ &&|& + \text{br\_table}~~l^\ast{:}\Tvec(\Tlabelidx_I)~~l_N{:}\Tlabelidx_I &\Rightarrow& \BRTABLE~l^\ast~l_N \\ &&|& \text{return} &\Rightarrow& \RETURN \\ &&|& - \text{call}~~x{:}\Tfuncidx &\Rightarrow& \CALL~x \\ &&|& - \text{call\_indirect}~~x{:}\Ttypeidx &\Rightarrow& \CALLINDIRECT~x \\ + \text{call}~~x{:}\Tfuncidx_I &\Rightarrow& \CALL~x \\ &&|& + \text{call\_indirect}~~x{:}\Ttypeidx_I &\Rightarrow& \CALLINDIRECT~x \\ \end{array} .. note:: @@ -78,7 +78,7 @@ Parametric Instructions .. math:: \begin{array}{llclll} - \production{instruction} & \Tplaininstr &::=& \dots \\ &&|& + \production{instruction} & \Tplaininstr_I &::=& \dots \\ &&|& \text{drop} &\Rightarrow& \DROP \\ &&|& \text{select} &\Rightarrow& \SELECT \\ \end{array} @@ -99,12 +99,12 @@ Variable Instructions .. math:: \begin{array}{llclll} - \production{instruction} & \Tplaininstr &::=& \dots \\ &&|& - \text{get\_local}~~x{:}\Tlocalidx &\Rightarrow& \GETLOCAL~x \\ &&|& - \text{set\_local}~~x{:}\Tlocalidx &\Rightarrow& \SETLOCAL~x \\ &&|& - \text{tee\_local}~~x{:}\Tlocalidx &\Rightarrow& \TEELOCAL~x \\ &&|& - \text{get\_global}~~x{:}\Tglobalidx &\Rightarrow& \GETGLOBAL~x \\ &&|& - \text{set\_global}~~x{:}\Tglobalidx &\Rightarrow& \SETGLOBAL~x \\ + \production{instruction} & \Tplaininstr_I &::=& \dots \\ &&|& + \text{get\_local}~~x{:}\Tlocalidx_I &\Rightarrow& \GETLOCAL~x \\ &&|& + \text{set\_local}~~x{:}\Tlocalidx_I &\Rightarrow& \SETLOCAL~x \\ &&|& + \text{tee\_local}~~x{:}\Tlocalidx_I &\Rightarrow& \TEELOCAL~x \\ &&|& + \text{get\_global}~~x{:}\Tglobalidx_I &\Rightarrow& \GETGLOBAL~x \\ &&|& + \text{set\_global}~~x{:}\Tglobalidx_I &\Rightarrow& \SETGLOBAL~x \\ \end{array} @@ -134,7 +134,7 @@ Memory Instructions \production{memory alignment} & \Talign_N &::=& \text{align{=}}a{:}\Tu32 &\Rightarrow& a \\ &&|& \epsilon &\Rightarrow& N \\ - \production{instruction} & \Tplaininstr &::=& \dots \\ &&|& + \production{instruction} & \Tplaininstr_I &::=& \dots \\ &&|& \text{i32.load}~~m{:}\Tmemarg_4 &\Rightarrow& \I32.\LOAD~m \\ &&|& \text{i64.load}~~m{:}\Tmemarg_8 &\Rightarrow& \I64.\LOAD~m \\ &&|& \text{f32.load}~~m{:}\Tmemarg_4 &\Rightarrow& \F32.\LOAD~m \\ &&|& @@ -174,7 +174,7 @@ Numeric Instructions .. math:: \begin{array}{llclll} - \production{instruction} & \Tplaininstr &::=& \dots \\&&|& + \production{instruction} & \Tplaininstr_I &::=& \dots \\&&|& \text{i32.const}~~n{:}\Ti32 &\Rightarrow& \I32.\CONST~n \\ &&|& \text{i64.const}~~n{:}\Ti64 &\Rightarrow& \I64.\CONST~n \\ &&|& \text{f32.const}~~z{:}\Tf32 &\Rightarrow& \F32.\CONST~z \\ &&|& @@ -186,7 +186,7 @@ Numeric Instructions .. math:: \begin{array}{llclll} - \phantom{\production{instruction}} & \phantom{\Tplaininstr} &\phantom{::=}& \phantom{thisisenough} && \phantom{thisshouldbeenough} \\[-2ex] &&|& + \phantom{\production{instruction}} & \phantom{\Tplaininstr_I} &\phantom{::=}& \phantom{thisisenough} && \phantom{thisshouldbeenough} \\[-2ex] &&|& \text{i32.clz} &\Rightarrow& \I32.\CLZ \\ &&|& \text{i32.ctz} &\Rightarrow& \I32.\CTZ \\ &&|& \text{i32.popcnt} &\Rightarrow& \I32.\POPCNT \\ &&|& @@ -209,7 +209,7 @@ Numeric Instructions .. math:: \begin{array}{llclll} - \phantom{\production{instruction}} & \phantom{\Tplaininstr} &\phantom{::=}& \phantom{thisisenough} && \phantom{thisshouldbeenough} \\[-2ex] &&|& + \phantom{\production{instruction}} & \phantom{\Tplaininstr_I} &\phantom{::=}& \phantom{thisisenough} && \phantom{thisshouldbeenough} \\[-2ex] &&|& \text{i64.clz} &\Rightarrow& \I64.\CLZ \\ &&|& \text{i64.ctz} &\Rightarrow& \I64.\CTZ \\ &&|& \text{i64.popcnt} &\Rightarrow& \I64.\POPCNT \\ &&|& @@ -232,7 +232,7 @@ Numeric Instructions .. math:: \begin{array}{llclll} - \phantom{\production{instruction}} & \phantom{\Tplaininstr} &\phantom{::=}& \phantom{thisisenough} && \phantom{thisshouldbeenough} \\[-2ex] &&|& + \phantom{\production{instruction}} & \phantom{\Tplaininstr_I} &\phantom{::=}& \phantom{thisisenough} && \phantom{thisshouldbeenough} \\[-2ex] &&|& \text{f32.abs} &\Rightarrow& \F32.\ABS \\ &&|& \text{f32.neg} &\Rightarrow& \F32.\NEG \\ &&|& \text{f32.ceil} &\Rightarrow& \F32.\CEIL \\ &&|& @@ -251,7 +251,7 @@ Numeric Instructions .. math:: \begin{array}{llclll} - \phantom{\production{instruction}} & \phantom{\Tplaininstr} &\phantom{::=}& \phantom{thisisenough} && \phantom{thisshouldbeenough} \\[-2ex] &&|& + \phantom{\production{instruction}} & \phantom{\Tplaininstr_I} &\phantom{::=}& \phantom{thisisenough} && \phantom{thisshouldbeenough} \\[-2ex] &&|& \text{f64.abs} &\Rightarrow& \F64.\ABS \\ &&|& \text{f64.neg} &\Rightarrow& \F64.\NEG \\ &&|& \text{f64.ceil} &\Rightarrow& \F64.\CEIL \\ &&|& @@ -273,7 +273,7 @@ Numeric Instructions .. math:: \begin{array}{llclll} - \phantom{\production{instruction}} & \phantom{\Tplaininstr} &\phantom{::=}& \phantom{thisisenough} && \phantom{thisshouldbeenough} \\[-2ex] &&|& + \phantom{\production{instruction}} & \phantom{\Tplaininstr_I} &\phantom{::=}& \phantom{thisisenough} && \phantom{thisshouldbeenough} \\[-2ex] &&|& \text{i32.eqz} &\Rightarrow& \I32.\EQZ \\ &&|& \text{i32.eq} &\Rightarrow& \I32.\EQ \\ &&|& \text{i32.ne} &\Rightarrow& \I32.\NE \\ &&|& @@ -289,7 +289,7 @@ Numeric Instructions .. math:: \begin{array}{llclll} - \phantom{\production{instruction}} & \phantom{\Tplaininstr} &\phantom{::=}& \phantom{thisisenough} && \phantom{thisshouldbeenough} \\[-2ex] &&|& + \phantom{\production{instruction}} & \phantom{\Tplaininstr_I} &\phantom{::=}& \phantom{thisisenough} && \phantom{thisshouldbeenough} \\[-2ex] &&|& \text{i64.eqz} &\Rightarrow& \I64.\EQZ \\ &&|& \text{i64.eq} &\Rightarrow& \I64.\EQ \\ &&|& \text{i64.ne} &\Rightarrow& \I64.\NE \\ &&|& @@ -305,7 +305,7 @@ Numeric Instructions .. math:: \begin{array}{llclll} - \phantom{\production{instruction}} & \phantom{\Tplaininstr} &\phantom{::=}& \phantom{thisisenough} && \phantom{thisshouldbeenough} \\[-2ex] &&|& + \phantom{\production{instruction}} & \phantom{\Tplaininstr_I} &\phantom{::=}& \phantom{thisisenough} && \phantom{thisshouldbeenough} \\[-2ex] &&|& \text{f32.eq} &\Rightarrow& \F32.\EQ \\ &&|& \text{f32.ne} &\Rightarrow& \F32.\NE \\ &&|& \text{f32.lt} &\Rightarrow& \F32.\LT \\ &&|& @@ -316,7 +316,7 @@ Numeric Instructions .. math:: \begin{array}{llclll} - \phantom{\production{instruction}} & \phantom{\Tplaininstr} &\phantom{::=}& \phantom{thisisenough} && \phantom{thisshouldbeenough} \\[-2ex] &&|& + \phantom{\production{instruction}} & \phantom{\Tplaininstr_I} &\phantom{::=}& \phantom{thisisenough} && \phantom{thisshouldbeenough} \\[-2ex] &&|& \text{f64.eq} &\Rightarrow& \F64.\EQ \\ &&|& \text{f64.ne} &\Rightarrow& \F64.\NE \\ &&|& \text{f64.lt} &\Rightarrow& \F64.\LT \\ &&|& @@ -329,7 +329,7 @@ Numeric Instructions .. math:: \begin{array}{llclll} - \phantom{\production{instruction}} & \phantom{\Tplaininstr} &\phantom{::=}& \phantom{thisisenough} && \phantom{thisshouldbeenough} \\[-2ex] &&|& + \phantom{\production{instruction}} & \phantom{\Tplaininstr_I} &\phantom{::=}& \phantom{thisisenough} && \phantom{thisshouldbeenough} \\[-2ex] &&|& \text{i32.wrap/i64} &\Rightarrow& \I32.\WRAP\K{/}\I64 \\ &&|& \text{i32.trunc\_s/f32} &\Rightarrow& \I32.\TRUNC\K{\_s/}\F32 \\ &&|& \text{i32.trunc\_u/f32} &\Rightarrow& \I32.\TRUNC\K{\_u/}\F32 \\ &&|& @@ -365,17 +365,17 @@ Folded Instructions .. math:: \begin{array}{llclll} - \production{folded instruction} & \Tfoldedinstr_C &::=& - \text{(}~\X{in}{:}\Tplaininstr~~(\X{op}{:}\Tfoldedinstr_C)^\ast~\text{)} + \production{folded instruction} & \Tfoldedinstr_I &::=& + \text{(}~\X{in}{:}\Tplaininstr~~(\X{op}{:}\Tfoldedinstr_I)^\ast~\text{)} &\Rightarrow& \X{op}^\ast~\X{in} \\ &&|& - \text{(}~\text{block}~~\X{rt}{:}\Tblocktype~~(\X{in}{:}\Tinstr_{C'})^\ast~\text{)} + \text{(}~\text{block}~~\X{rt}{:}\Tblocktype~~(\X{in}{:}\Tinstr_{I'})^\ast~\text{)} &\Rightarrow& \BLOCK~\X{rt}~\X{in}^\ast~\END \\ &&|& - \text{(}~\text{loop}~~\X{rt}{:}\Tblocktype~~(\X{in}{:}\Tinstr_{C'})^\ast~\text{)} + \text{(}~\text{loop}~~\X{rt}{:}\Tblocktype~~(\X{in}{:}\Tinstr_{I'})^\ast~\text{)} &\Rightarrow& \LOOP~\X{rt}~\X{in}^\ast~\END \\ &&|& - \text{(}~\text{if}~~\X{rt}{:}\Tblocktype~~\X{in}_0^\ast{:}\Tfoldedinstr_C~~\text{(}~\text{then}~~(\X{in}{:}\Tinstr_{C'})^\ast~\text{)}~~\text{)} + \text{(}~\text{if}~~\X{rt}{:}\Tblocktype~~\X{in}_0^\ast{:}\Tfoldedinstr_I~~\text{(}~\text{then}~~(\X{in}{:}\Tinstr_{I'})^\ast~\text{)}~~\text{)} &\Rightarrow& \X{in}_0^\ast~~\IF~\X{rt}~\X{in}^\ast~\ELSE~\epsilon~\END \\ &&|& - \text{(}~\text{if}~~\X{rt}{:}\Tblocktype~~\X{in}_0^\ast{:}\Tfoldedinstr_C~~\text{(}~\text{then}~~(\X{in}_1{:}\Tinstr_{C'})^\ast~\text{)}~~ - \text{(}~\text{else}~~(\X{in}_2{:}\Tinstr_{C'})^\ast~\text{)}~~\text{)} + \text{(}~\text{if}~~\X{rt}{:}\Tblocktype~~\X{in}_0^\ast{:}\Tfoldedinstr_I~~\text{(}~\text{then}~~(\X{in}_1{:}\Tinstr_{I'})^\ast~\text{)}~~ + \text{(}~\text{else}~~(\X{in}_2{:}\Tinstr_{I'})^\ast~\text{)}~~\text{)} &\Rightarrow& \X{in}_0^\ast~~\IF~\X{rt}~\X{in}_1^\ast~\ELSE~\X{in}_2^\ast~\END \\ \end{array} diff --git a/document/text/lexical.rst b/document/text/lexical.rst index a3986130a3..11609b3d1f 100644 --- a/document/text/lexical.rst +++ b/document/text/lexical.rst @@ -3,54 +3,70 @@ Lexical Format -------------- -The text format is represented in a superset of `7-bit ASCII `_. -Only printable 7-bit ASCII characters are interpreted in this format, -hence any compatible character encoding, such as `Unicode UTF-8 `_ is applicable. + +.. _text-char: +.. index:: ! character + pair: text format; character + +Characters +~~~~~~~~~~ + +The text format assigns meaning to *source text*, which consists of a sequence of *characters*. +The set of significant characters interpreted in the text format is a subset of the characters supported by `7-bit ASCII `_, +but a source text may contain additional characters, +such as other `Unicode `_ *code points*. + +.. math:: + \begin{array}{llll} + \production{character} & \Tchar &::=& + \dots (\mbox{any character}) \\ + \end{array} .. note:: - Non-ASCII bytes can only occur in :ref:`comments ` and :ref:`string literals `. - Similarly, ASCII control characters other than :ref:`white space ` can only occur in :ref:`comments `. + Non-ASCII characters or ASCII control characters other than format characters can only occur in :ref:`comments `, + where they have no effect on the meaning of the source text. .. _text-stoken: .. index:: ! token + single: text format; token Tokens ~~~~~~ -The character stream in the source text is divided into a sequence of *tokens*. -In this specification, tokens are either defined explicitly by grammar rules, +The character stream in the source text is divided, from left to right, into a sequence of *tokens*. +In this specification, tokens are either defined explicitly by lexical grammar rules, such as the lexical syntax of :ref:`values `, -or implicitly, by the occurrence of terminal symbols in string form in the non-lexical grammar. +or implicitly, by the occurrence of terminal symbols in literal form in the non-lexical grammar. -Tokens are consumed from the input character stream according to the *longest match* rule. +Tokens are formed from the input character stream according to the *longest match* rule. That is, the next token always consists of the longest possible sequence of characters that is recognized as a token. -Tokens may explicitly be separated by :ref:`space ` characters or :ref:`comments `, -collectively called :ref:`white space `. -White space cannot appear inside a token. - +Tokens may explicitly be separated by space and formatting characters or :ref:`comments `, +collectively called :ref:`white space `. +Except for :ref:`string ` literals, white space cannot appear inside a token. .. _text-space: -.. _text-whitespace: .. index:: ! white space White Space ~~~~~~~~~~~ -*White space* is any sequence of *space* characters or :ref:`comments `. +*White space* is any sequence of literal space characters, formatting characters, or :ref:`comments `. -A space character either is the `ASCII `_ *space* (byte :math:`\hex{20}`) or an ASCII *format effector*, that is, *backspace* (:math:`\hex{08}`), *horizontal tabulation* (:math:`\hex{09}`), *line feed* (:math:`\hex{0A}`), *vertical tabulation* (:math:`\hex{0B}`), *form feed* (:math:`\hex{0C}`), or *carriage return* (:math:`\hex{0D}`). +A format character corresponds to an `ASCII `_ *format effector*, that is, *backspace* (ASCII :math:`\hex{08}`), *horizontal tabulation* (:math:`\hex{09}`), *line feed* (:math:`\hex{0A}`), *vertical tabulation* (:math:`\hex{0B}`), *form feed* (:math:`\hex{0C}`), or *carriage return* (:math:`\hex{0D}`). .. math:: \begin{array}{llclll@{\qquad\qquad}l} - \production{white space} & \T{whitespace} &::=& - (\T{space} ~|~ \T{comment})^\ast \\ - \production{space} & \T{space} &::=& - \hex{20} ~|~ \hex{08} ~|~ \hex{09} ~|~ \hex{0A} ~|~ \hex{0B} ~|~ \hex{0C} ~|~ \hex{0D} \\ + \production{white space} & \Tspace &::=& + (\text{~~} ~|~ \Tformat ~|~ \Tcomment)^\ast \\ + \production{format} & \Tformat &::=& + \hex{08} ~|~ \hex{09} ~|~ \hex{0A} ~|~ \hex{0B} ~|~ \hex{0C} ~|~ \hex{0D} \\ \end{array} +Here, its binary code in ASCII is used to denote the respective control character. + .. text-comment: .. index:: ! comments @@ -59,24 +75,25 @@ Comments ~~~~~~~~ A *comment* can either be a *line comment*, started with a double semicolon :math:`\text{;\!;}` and extending to the end of the line, -or a *block comment*, enclosed in :math:`\text{(\!;} \dots \text{;\!)}`. +or a *block comment*, enclosed in delimiters :math:`\text{\verb|(;|} \dots \text{\verb|;)|}`. Block comments can be nested. .. math:: \begin{array}{llclll@{\qquad\qquad}l} - \production{comment} & \T{comment} &::=& - \T{linecomment} ~|~ \T{blockcomment} \\ - \production{line comment} & \T{linecomment} &::=& - \text{;\!;}~~\T{linecontent}^\ast~~(\hex{0A} ~|~ \T{eof}) \\ - \production{line content} & \T{linecontent} &::=& - b & (b \neq \hex{0A}) \\ - \production{block comment} & \T{blockcomment} &::=& - \text{(\!;}~~\T{blockcontent}^\ast~~\text{;\!)} \\ - \production{block content} & \T{blockcontent} &::=& - b & (b \neq \text{;} \wedge b \neq \text{(}) \\ &&|& - \text{;}~b & (b \neq \text{)}) \\ &&|& - \text{(}~b & (b \neq \text{;}) \\ &&|& - \T{blockcomment} \\ + \production{comment} & \Tcomment &::=& + \Tlinecomment ~|~ \Tblockcomment \\ + \production{line comment} & \Tlinecomment &::=& + \text{\verb|;;|}~~\Tlinechar^\ast~~(\hex{0A} ~|~ \T{eof}) \\ + \production{line character} & \Tlinechar &::=& + c{:}\Tchar & (c \neq \hex{0A}) \\ + \production{block comment} & \Tblockcomment &::=& + \text{\verb|(;|}~~\Tblockchar^\ast~~\text{\verb|;)|} \\ + \production{block character} & \Tblockchar &::=& + c{:}\Tchar & (c \neq \text{;} \wedge c \neq \text{(}) \\ &&|& + \text{;} & (\mbox{the next character is not}~\text{)}) \\ &&|& + \text{(} & (\mbox{the next character is not}~\text{;}) \\ &&|& + \Tblockcomment \\ \end{array} -Here, the pseudo token :math:`\T{eof}` indicates the end of the input. +Here, the binary ASCII code :math:`\text{0A}` is used to denote the end-of-line character and the pseudo token :math:`\T{eof}` indicates the end of the input. +The *look-ahead* restrictions on |Tblockchar| disambiguate the grammar such that only well-bracketted uses of block comment delimiters are allowed. diff --git a/document/text/modules.rst b/document/text/modules.rst index fcbcb79ba3..78528d843f 100644 --- a/document/text/modules.rst +++ b/document/text/modules.rst @@ -33,27 +33,27 @@ Indices .. math:: \begin{array}{llclll} - \production{type index} & \Ttypeidx_C &::=& + \production{type index} & \Ttypeidx_I &::=& x{:}\Tu32 &\Rightarrow& x \\ &&|& - v{:}\Tvar &\Rightarrow& x & (C.\TYPES[x] = v) \\ - \production{function index} & \Tfuncidx_C &::=& + v{:}\Tid &\Rightarrow& x & (I.\TYPES[x] = v) \\ + \production{function index} & \Tfuncidx_I &::=& x{:}\Tu32 &\Rightarrow& x \\ &&|& - v{:}\Tvar &\Rightarrow& x & (C.\FUNCS[x] = v) \\ - \production{table index} & \Ttableidx_C &::=& + v{:}\Tid &\Rightarrow& x & (I.\FUNCS[x] = v) \\ + \production{table index} & \Ttableidx_I &::=& x{:}\Tu32 &\Rightarrow& x \\ &&|& - v{:}\Tvar &\Rightarrow& x & (C.\TABLES[x] = v) \\ - \production{memory index} & \Tmemidx_C &::=& + v{:}\Tid &\Rightarrow& x & (I.\TABLES[x] = v) \\ + \production{memory index} & \Tmemidx_I &::=& x{:}\Tu32 &\Rightarrow& x \\ &&|& - v{:}\Tvar &\Rightarrow& x & (C.\MEMS[x] = v) \\ - \production{global index} & \Tglobalidx_C &::=& + v{:}\Tid &\Rightarrow& x & (I.\MEMS[x] = v) \\ + \production{global index} & \Tglobalidx_I &::=& + x{:}\Tid &\Rightarrow& x \\ &&|& + v{:}\Tid &\Rightarrow& x & (I.\GLOBALS[x] = v) \\ + \production{local index} & \Tlocalidx_I &::=& x{:}\Tu32 &\Rightarrow& x \\ &&|& - v{:}\Tvar &\Rightarrow& x & (C.\GLOBALS[x] = v) \\ - \production{local index} & \Tlocalidx_C &::=& - x{:}\Tu32 &\Rightarrow& x \\ &&|& - v{:}\Tvar &\Rightarrow& x & (C.\LOCALS[x] = v) \\ - \production{label index} & \Tlabelidx_C &::=& + v{:}\Tid &\Rightarrow& x & (I.\LOCALS[x] = v) \\ + \production{label index} & \Tlabelidx_I &::=& l{:}\Tu32 &\Rightarrow& l \\ &&|& - v{:}\Tvar &\Rightarrow& x & (C.\LABELS[x] = v) \\ + v{:}\Tid &\Rightarrow& x & (I.\LABELS[x] = v) \\ \end{array} .. math:: @@ -82,10 +82,10 @@ Indices \epsilon &\Rightarrow& C \with \LOCALS = C.\LOCALS~(\epsilon) \\ &&|& v{:}\Tvar &\Rightarrow& C \with \LOCALS = C.\LOCALS~v & (v \notin C.\LOCALS) \\ - \production{label binder} & \Tlabelbind_C &::=& - \epsilon &\Rightarrow& C \with \LABELS = C.\LABELS~(\epsilon) \\ &&|& - v{:}\Tvar &\Rightarrow& C \with \LABELS = v~C.\LABELS - & (v \notin C.\LABELS) \\ + \production{label binder} & \Tlabelbind_I &::=& + \epsilon &\Rightarrow& I \with \LABELS = I.\LABELS~(\epsilon) \\ &&|& + v{:}\Tid &\Rightarrow& I \with \LABELS = v~I.\LABELS + & (v \notin I.\LABELS) \\ \end{array} @@ -100,7 +100,7 @@ Types .. math:: \begin{array}{llclll} \production{type definition} & \Ttype &::=& - \text{(}~\text{type}~~\X{ft}{:}\Tfunctype~\text{)} + \text{(}~\text{type}~~\Tid^?~~\X{ft}{:}\Tfunctype~\text{)} &\Rightarrow& \X{ft} \\ \end{array} @@ -108,8 +108,8 @@ Types .. math:: \begin{array}{llclll} - \production{type use} & \Ttypeuse &::=& - \text{(}~\text{type}~~x{:}\Ttypeidx~\text{)} + \production{type use} & \Ttypeuse_I &::=& + \text{(}~\text{type}~~x{:}\Ttypeidx_I~\text{)} &\Rightarrow& x \\ \end{array} @@ -125,17 +125,17 @@ Imports .. math:: \begin{array}{llclll} - \production{import} & \Timport &::=& - \text{(}~\text{import}~~\X{mod}{:}\Tname~~\X{nm}{:}\Tname~~d{:}\Timportdesc~\text{)} + \production{import} & \Timport_I &::=& + \text{(}~\text{import}~~\X{mod}{:}\Tname~~\X{nm}{:}\Tname~~d{:}\Timportdesc_I~\text{)} &\Rightarrow& \{ \MODULE~\X{mod}, \NAME~\X{nm}, \DESC~d \} \\ - \production{import description} & \Timportdesc &::=& - \text{(}~\text{func}~~x{:}\Ttypeuse~\text{)} + \production{import description} & \Timportdesc_I &::=& + \text{(}~\text{func}~~\Tid^?~~x{:}\Ttypeuse_I~\text{)} &\Rightarrow& \FUNC~x \\ &&|& - \text{(}~\text{table}~~\X{tt}{:}\Ttabletype~\text{)} + \text{(}~\text{table}~~\Tid^?~~\X{tt}{:}\Ttabletype~\text{)} &\Rightarrow& \TABLE~\X{tt} \\ &&|& - \text{(}~\text{memory}~~\X{mt}{:}\Tmemtype~\text{)} + \text{(}~\text{memory}~~\Tid^?~~\X{mt}{:}\Tmemtype~\text{)} &\Rightarrow& \MEM~~\X{mt} \\ &&|& - \text{(}~\text{global}~~\X{gt}{:}\Tglobaltype~\text{)} + \text{(}~\text{global}~~\Tid^?~~\X{gt}{:}\Tglobaltype~\text{)} &\Rightarrow& \GLOBAL~\X{gt} \\ \end{array} @@ -151,11 +151,12 @@ Functions .. math:: \begin{array}{llclll} - \production{function} & \Tfunc &::=& - \text{(}~\text{func}~~x{:}\Ttypeuse~~(t{:}\Tlocal)^\ast~~(\X{in}{:}\Tinstr)^\ast~\text{)} - &\Rightarrow& \{ \TYPE~x, \LOCALS~t^\ast, \BODY~\X{in}^\ast~\END \} \\ + \production{function} & \Tfunc_I &::=& + \text{(}~\text{func}~~x{:}\Ttypeuse_I~~(t{:}\Tlocal)^\ast~~(\X{in}{:}\Tinstr_{I'})^\ast~\text{)} + &\Rightarrow& \{ \TYPE~x, \LOCALS~t^\ast, \BODY~\X{in}^\ast~\END \} + & (I' = I \with \LOCALS = (\id(\Tlocal))^\ast) \\ \production{local} & \Tlocal &::=& - \text{(}~\text{local}~~t{:}\Tvaltype~\text{)} + \text{(}~\text{local}~~\Tid^?~~t{:}\Tvaltype~\text{)} &\Rightarrow& t \\ \end{array} @@ -169,8 +170,8 @@ Tables .. math:: \begin{array}{llclll} - \production{table} & \Ttable &::=& - \text{(}~\text{table}~~\X{tt}{:}\Ttabletype~\text{)} + \production{table} & \Ttable_I &::=& + \text{(}~\text{table}~~\Tid^?~~\X{tt}{:}\Ttabletype~\text{)} &\Rightarrow& \{ \TYPE~\X{tt} \} \\ \end{array} @@ -184,8 +185,8 @@ Memories .. math:: \begin{array}{llclll} - \production{memory} & \Tmem &::=& - \text{(}~\text{memory}~~\X{mt}{:}\Tmemtype~\text{)} + \production{memory} & \Tmem_I &::=& + \text{(}~\text{memory}~~\Tid^?~~\X{mt}{:}\Tmemtype~\text{)} &\Rightarrow& \{ \TYPE~\X{mt} \} \\ \end{array} @@ -199,8 +200,8 @@ Globals .. math:: \begin{array}{llclll} - \production{global} & \Tglobal &::=& - \text{(}~\text{global}~~\X{gt}{:}\Tglobaltype~~(\X{in}{:}\Tinstr)^\ast~\text{)} + \production{global} & \Tglobal_I &::=& + \text{(}~\text{global}~~\Tid^?~~\X{gt}{:}\Tglobaltype~~(\X{in}{:}\Tinstr_I)^\ast~\text{)} &\Rightarrow& \{ \TYPE~\X{gt}, \INIT~\X{in}^\ast~\END \} \\ \end{array} @@ -214,17 +215,17 @@ Exports .. math:: \begin{array}{llclll} - \production{export} & \Texport &::=& - \text{(}~\text{export}~~\X{nm}{:}\Tname~~d{:}\Texportdesc~\text{)} + \production{export} & \Texport_I &::=& + \text{(}~\text{export}~~\X{nm}{:}\Tname~~d{:}\Texportdesc_I~\text{)} &\Rightarrow& \{ \NAME~\X{nm}, \DESC~d \} \\ - \production{export description} & \Texportdesc &::=& - \text{(}~\text{func}~~x{:}\Bfuncidx~\text{)} + \production{export description} & \Texportdesc_I &::=& + \text{(}~\text{func}~~x{:}\Bfuncidx_I~\text{)} &\Rightarrow& \FUNC~x \\ &&|& - \text{(}~\text{table}~~x{:}\Btableidx~\text{)} + \text{(}~\text{table}~~x{:}\Btableidx_I~\text{)} &\Rightarrow& \TABLE~x \\ &&|& - \text{(}~\text{memory}~~x{:}\Bmemidx~\text{)} + \text{(}~\text{memory}~~x{:}\Bmemidx_I~\text{)} &\Rightarrow& \MEM~x \\ &&|& - \text{(}~\text{global}~~x{:}\Bglobalidx~\text{)} + \text{(}~\text{global}~~x{:}\Bglobalidx_I~\text{)} &\Rightarrow& \GLOBAL~x \\ \end{array} @@ -238,8 +239,8 @@ Start Function .. math:: \begin{array}{llclll} - \production{start function} & \Tstart &::=& - \text{(}~\text{start}~~x{:}\Tfuncidx~\text{)} + \production{start function} & \Tstart_I &::=& + \text{(}~\text{start}~~x{:}\Tfuncidx_I~\text{)} &\Rightarrow& \{ \FUNC~x \} \\ \end{array} @@ -255,8 +256,8 @@ Element Segments .. math:: \begin{array}{llclll} - \production{element segment} & \Telem &::=& - \text{(}~\text{elem}~~x{:}\Ttableidx~~\text{(}~\text{offset}~~(\X{in}{:}\Tinstr)^\ast~\text{)}~~y^\ast{:}\Tvec(\Tfuncidx)~\text{)} + \production{element segment} & \Telem_I &::=& + \text{(}~\text{elem}~~x{:}\Ttableidx_I~~\text{(}~\text{offset}~~(\X{in}{:}\Tinstr_I)^\ast~\text{)}~~y^\ast{:}\Tvec(\Tfuncidx_I)~\text{)} &\Rightarrow& \{ \TABLE~x, \OFFSET~\X{in}^\ast~\END, \INIT~y^\ast \} \\ \end{array} @@ -272,8 +273,8 @@ Data Segments .. math:: \begin{array}{llclll} - \production{data segment} & \Tdata &::=& - \text{(}~\text{data}~~x{:}\Tmemidx~~\text{(}~\text{offset}~~(\X{in}{:}\Tinstr)^\ast~\text{)}~~b^\ast{:}\Tstring~\text{)} + \production{data segment} & \Tdata_I &::=& + \text{(}~\text{data}~~x{:}\Tmemidx_I~~\text{(}~\text{offset}~~(\X{in}{:}\Tinstr_I)^\ast~\text{)}~~b^\ast{:}\Tstring~\text{)} &\Rightarrow& \{ \MEM~x, \OFFSET~\X{in}^\ast~\END, \INIT~b^\ast \} \\ \end{array} @@ -291,21 +292,21 @@ Modules \begin{array}{llcllll} \production{module} & \Tmodule &::=& \text{(}~\text{module}~~m{:}\Tmodulebody~\text{)} - &\Rightarrow& m \\ &&|& - m{:}\Tmodulebody - &\Rightarrow& m \\ + \quad\Rightarrow\quad m \\ &&|& + m{:}\Tmodulebody \phantom{\text{(}~\text{module}~~~\text{)}} + \quad\Rightarrow\quad m \\ \production{module body} & \Tmodulebody &::=& (\functype{:}\Ttype)^\ast \\ &&& - (\import{:}\Timport)^\ast \\ &&& - (\func{:}\Tfunc)^\ast \\ &&& - (\table{:}\Ttable)^\ast \\ &&& - (\mem{:}\Tmem)^\ast \\ &&& - (\global{:}\Tglobal)^\ast \\ &&& - (\export{:}\Texport)^\ast \\ &&& - (\start{:}\Tstart)^? \\ &&& - (\elem{:}\Telem)^\ast \\ &&& - (\data{:}\Tdata)^\ast - &\Rightarrow& \{~ + (\import{:}\Timport_I)^\ast \\ &&& + (\func{:}\Tfunc_I)^\ast \\ &&& + (\table{:}\Ttable_I)^\ast \\ &&& + (\mem{:}\Tmem_I)^\ast \\ &&& + (\global{:}\Tglobal_I)^\ast \\ &&& + (\export{:}\Texport_I)^\ast \\ &&& + (\start{:}\Tstart_I)^? \\ &&& + (\elem{:}\Telem_I)^\ast \\ &&& + (\data{:}\Tdata_I)^\ast + \quad\Rightarrow\quad \{~ \begin{array}[t]{@{}l@{}} \TYPES~\functype^\ast, \\ \FUNCS~\func^\ast, \\ @@ -317,5 +318,15 @@ Modules \START~\start^?, \\ \IMPORTS~\import^\ast, \\ \EXPORTS~\export^\ast ~\} \\ - \end{array} \\ + \end{array} \\ &&& + \qquad (I = \{~ + \begin{array}[t]{@{}l@{}} + \TYPES~(\id(\Ttype))^\ast, \\ + \FUNCS~\id^\ast(\funcs(\Timport^\ast))~(\id(\Tfunc))^\ast, \\ + \TABLES~\id^\ast(\tables(\Timport^\ast))~(\id(\Ttable))^\ast, \\ + \MEMS~\id^\ast(\mems(\Timport^\ast))~(\id(\Tmem))^\ast, \\ + \GLOBALS~\id^\ast(\globals(\Timport^\ast))~(\id(\Tglobal))^\ast, \\ + \LOCALS~\epsilon, \\ + \LABELS~\epsilon ~\}) \\ + \end{array} \end{array} diff --git a/document/text/values.rst b/document/text/values.rst index f8515b52b5..7920e1a29d 100644 --- a/document/text/values.rst +++ b/document/text/values.rst @@ -80,12 +80,12 @@ Floating-Point ~~~~~~~~~~~~~~ :ref:`Floating point ` values can be represented in either decimal or hexadecimal notation. -The value must not be outside the representable range of the corresponding `IEEE 754 `_ type -(that is, it must not overflow to infinity), +The value of a literal must not lie outside the representable range of the corresponding `IEEE 754 `_ type +(that is, it must not overflow to :math:`\pm`infinity), but it may be rounded to the nearest representable value. .. note:: - Rounding can be avoided by using hexadecimal notation with no more significant bits than supported by the desired type. + Rounding can be prevented by using hexadecimal notation with no more significant bits than supported by the required type. Floating-point values may also be written as constants for *infinity* or *canonical NaN* (*not a number*). Furthermore, arbitrary NaN values may be expressed by providing an explicit payload value. @@ -120,6 +120,8 @@ Furthermore, arbitrary NaN values may be expressed by providing an explicit payl s{:}\Tsign~\text{nan\!:}~n{:}\Thexnum &\Rightarrow& b^\ast & (\ieeenan_N(s, n) = b^\ast) \\ \end{array} +.. todo:: IEEE encoding + .. _text-vec: .. index:: vector @@ -146,31 +148,34 @@ Vectors Strings ~~~~~~~ -*Strings* are sequences of bytes that can represent both textual and binary data. -They are enclosed in `ASCII `_ *quotation marks* (bytes of value \hex{22}) -and may contain any byte that is not an ASCII control character, ASCII *quotation marks* (\hex{22}), or ASCII *reverse slant* (backslash, \hex{5C}), -except when expressed with an *escape sequence* started by an ASCII *reverse slant* (\hex{5C}). +*Strings* denote sequences of bytes that can represent both textual and binary data. +They are enclosed in quotation marks +and may contain any *printable* `ASCII `_ character other than quotation marks (:math:`\text{"}`) or backslash (:math:`\text{\verb|\|}`), +except when expressed with an *escape sequence* started by a backslash. .. math:: \begin{array}{llclll@{\qquad\qquad}l} - \production{byte} & \Tbyte &::=& - b &\Rightarrow& b & (\hex{20} \leq b < \hex{7F} \wedge b \neq \text{"} \wedge b \neq \text{\backslash}) \\ &&|& - \text{\backslash}~n{:}\Thexdigit~m{:}\Thexdigit &\Rightarrow& 16\cdot n+m \\ &&|& - \text{\backslash{}t} &\Rightarrow& \hex{09} \\ &&|& - \text{\backslash{}n} &\Rightarrow& \hex{0A} \\ &&|& - \text{\backslash{}r} &\Rightarrow& \hex{0D} \\ &&|& - \text{\backslash{}"} &\Rightarrow& \hex{22} \\ &&|& - \text{\backslash{}'} &\Rightarrow& \hex{27} \\ &&|& - \text{\backslash\backslash} &\Rightarrow& \hex{5C} \\ \production{string} & \Tstring &::=& - \text{"}~(b{:}\Tbyte)^\ast~\text{"} - &\Rightarrow& b^\ast \\ + \text{"}~(b{:}\Tstringchar)^\ast~\text{"} + \quad\Rightarrow\quad b^\ast \\ + \production{string character} & \Tstringchar &::=& + \text{~~} ~~\Rightarrow~~ \hex{20} ~~~|~~~ + \text{!} ~~\Rightarrow~~ \hex{21} \\ &&|& + \text{\#} ~~\Rightarrow~~ \hex{23} ~~~|~~~ + \cdots ~~~|~~~ + \text{[} ~~\Rightarrow~~ \hex{5B} \\ &&|& + \text{]} ~~\Rightarrow~~ \hex{5D} ~~~|~~~ + \cdots ~~~|~~~ + \text{\verb|~|} ~~\Rightarrow~~ \hex{7E} \\ &&|& + \text{\verb|\t|} ~~\Rightarrow~~ \hex{09} \\ &&|& + \text{\verb|\n|} ~~\Rightarrow~~ \hex{0A} \\ &&|& + \text{\verb|\r|} ~~\Rightarrow~~ \hex{0D} \\ &&|& + \text{\verb|\"|} ~~\Rightarrow~~ \hex{22} \\ &&|& + \text{\verb|\'|} ~~\Rightarrow~~ \hex{27} \\ &&|& + \text{\verb|\\|} ~~\Rightarrow~~ \hex{5C} \\ &&|& + \text{\verb|\|}~n{:}\Thexdigit~m{:}\Thexdigit ~~\Rightarrow~~ 16\cdot n+m \\ \end{array} -.. note:: - The bytes in a string are not interpreted in any specific way, - except when the string appears as a :ref:`name `. - .. _text-name: .. index:: name, byte @@ -187,3 +192,54 @@ Names b^\ast{:}\Tstring &\Rightarrow& \X{uc}^n & (\utf8(\X{uc}^n) = b^\ast \wedge n < 2^{32}) \\ \end{array} + +.. todo:: UTF-8 decoding + + +.. _text-id: +.. index:: ! identifiers + pair: text format; identifiers + +Identifiers +~~~~~~~~~~~ + +:ref:`Indices ` can be given in both numeric and symbolic form. +Symbolic *identifiers* standing for indices start with :math:`\text{$}`, followed by any sequence of printable `ASCII `_ characters that does not contain a space, quotation mark, comma, semicolon, or bracket (parentheses, square brackets, or braces). + +.. math:: + \begin{array}{llclll@{\qquad}l} + \production{identifier} & \Tid &::=& + \text{$}~(b{:}\Tidchar)^+ \\ + \production{identifier character} & \Tidchar &::=& + \text{0} ~~|~~ \dots ~~|~~ \text{9} \\ &&|& + \text{A} ~~|~~ \dots ~~|~~ \text{Z} \\ &&|& + \text{a} ~~|~~ \dots ~~|~~ \text{z} \\ &&|& + \text{!} ~~|~~ + \text{\#} ~~|~~ + \text{\$} ~~|~~ + \text{\%} ~~|~~ + \text{\&} ~~|~~ + \text{\verb|'|} ~~|~~ + \text{*} ~~|~~ + \text{+} ~~|~~ + \text{-} ~~|~~ + \text{.} ~~|~~ + \text{/} \\ &&|& + \text{:} ~~|~~ + \text{<} ~~|~~ + \text{=} ~~|~~ + \text{>} ~~|~~ + \text{?} ~~|~~ + \text{@} ~~|~~ + \text{\verb|\|} ~~|~~ + \text{\verb|^|} ~~|~~ + \text{\verb|_|} ~~|~~ + \text{\verb|`|} ~~|~~ + \text{|} ~~|~~ + \text{\verb|~|} \\ + \end{array} + +.. math (commented out) + b \Rightarrow b + && (\hex{21} \leq b \leq \hex{7E} \wedge + b \notin \{\text{,}, \text{;}, \text{(}, \text{)}, \text{[}, \text{]}, \text{\{}, \text{\}}\}) \\ From 26b9df9a24e089b4cacd845e508b63b59ab25830 Mon Sep 17 00:00:00 2001 From: Andreas Rossberg Date: Fri, 5 May 2017 14:12:41 +0200 Subject: [PATCH 06/30] Unicode --- document/math.def | 7 ++- document/text/conventions.rst | 8 +++- document/text/lexical.rst | 24 +++++----- document/text/values.rst | 83 +++++++++++++++++++++++++---------- 4 files changed, 83 insertions(+), 39 deletions(-) diff --git a/document/math.def b/document/math.def index ee40e2d01b..da5eb49fd0 100644 --- a/document/math.def +++ b/document/math.def @@ -25,7 +25,7 @@ .. |with| mathdef:: ~\xref{syntax/conventions}{syntax-record}{\mbox{with}}~ -.. Lexical grammar +.. Lexical grammar, non-terminals .. |Tchar| mathdef:: \xref{text/lexical}{text-char}{\T{char}} .. |Tspace| mathdef:: \xref{text/lexical}{text-space}{\T{space}} @@ -38,6 +38,11 @@ .. |Tblockchar| mathdef:: \xref{text/lexical}{text-comment}{\T{blockchar}} +.. Lexical grammar, meta functions + +.. |utf8| mathdef:: \xref{text/values}{text-bytes}{\F{utf8}} + + .. Values, terminals .. |hex#1| mathdef:: \mathtt{0x#1} diff --git a/document/text/conventions.rst b/document/text/conventions.rst index bbcc2faf75..cd10437679 100644 --- a/document/text/conventions.rst +++ b/document/text/conventions.rst @@ -8,8 +8,10 @@ The textual format for WebAssembly :ref:`modules ` is a rendering of th Like the :ref:`binary format `, the text format is defined by an *attribute grammar*. A text string is a well-formed description of a module if and only if it is generated by the grammar. -Each production of this grammar has exactly one synthesized attribute: the abstract syntax that the respective byte sequence encodes. +Each production of this grammar has at most one synthesized attribute: the abstract syntax that the respective byte sequence encodes. Thus, the attribute grammar implicitly defines a *parsing* function. +Some productions also take a :ref:`context ` as an inherited attribute +that records bound :ref:`identifers `. Except for a few exceptions, the core of the text grammar closely mirrors the grammar of the abstract syntax. However, it also defines a number of forms that are *syntactic sugar* over the core syntax. @@ -29,7 +31,9 @@ The following conventions are adopted in defining grammar rules for the text for They mirror the conventions used for :ref:`abstract syntax ` and for the :ref:`binary format `. In order to distinguish symbols of the textual syntax from symbols of the abstract syntax, typewriter font is adopted for the former. -* Terminal symbols are strings of characters enclosed in quotes: :math:`\text{module}`. +* Terminal symbols are either literal strings of characters enclosed in quotes: :math:`\text{module}`, + or expressed as `Unicode `_ code points: :math:`\unicode{0A}. + (All characters written literally are contained in the `7-bit ASCII `_ subset of Unicode.) * Nonterminal symbols are written in typewriter font: :math:`\T{valtype}, \T{instr}`. diff --git a/document/text/lexical.rst b/document/text/lexical.rst index 11609b3d1f..13418d7b2f 100644 --- a/document/text/lexical.rst +++ b/document/text/lexical.rst @@ -12,19 +12,17 @@ Characters ~~~~~~~~~~ The text format assigns meaning to *source text*, which consists of a sequence of *characters*. -The set of significant characters interpreted in the text format is a subset of the characters supported by `7-bit ASCII `_, -but a source text may contain additional characters, -such as other `Unicode `_ *code points*. +Characters are assumed to be represented as valid `Unicode `_ *code points*. .. math:: \begin{array}{llll} \production{character} & \Tchar &::=& - \dots (\mbox{any character}) \\ + \unicode{00} ~|~ \dots ~|~ \unicode{D800} ~|~ \unicode{E000} ~|~ \dots ~|~ \unicode{10FFFF} \\ \end{array} .. note:: - Non-ASCII characters or ASCII control characters other than format characters can only occur in :ref:`comments `, - where they have no effect on the meaning of the source text. + The set of characters interpreted in the text format is a subset of the characters supported by `7-bit ASCII `_, + but a source text may contain other characters in :ref:`comments ` or :ref:`string ` literals. .. _text-stoken: @@ -55,18 +53,16 @@ White Space *White space* is any sequence of literal space characters, formatting characters, or :ref:`comments `. -A format character corresponds to an `ASCII `_ *format effector*, that is, *backspace* (ASCII :math:`\hex{08}`), *horizontal tabulation* (:math:`\hex{09}`), *line feed* (:math:`\hex{0A}`), *vertical tabulation* (:math:`\hex{0B}`), *form feed* (:math:`\hex{0C}`), or *carriage return* (:math:`\hex{0D}`). +A format character corresponds to an `ASCII `_ *format effector*, that is, *backspace* (:math:`\unicode{08}`), *horizontal tabulation* (:math:`\unicode{09}`), *line feed* (:math:`\unicode{0A}`), *vertical tabulation* (:math:`\unicode{0B}`), *form feed* (:math:`\unicode{0C}`), or *carriage return* (:math:`\unicode{0D}`). .. math:: \begin{array}{llclll@{\qquad\qquad}l} \production{white space} & \Tspace &::=& (\text{~~} ~|~ \Tformat ~|~ \Tcomment)^\ast \\ \production{format} & \Tformat &::=& - \hex{08} ~|~ \hex{09} ~|~ \hex{0A} ~|~ \hex{0B} ~|~ \hex{0C} ~|~ \hex{0D} \\ + \unicode{08} ~|~ \unicode{09} ~|~ \unicode{0A} ~|~ \unicode{0B} ~|~ \unicode{0C} ~|~ \unicode{0D} \\ \end{array} -Here, its binary code in ASCII is used to denote the respective control character. - .. text-comment: .. index:: ! comments @@ -83,9 +79,9 @@ Block comments can be nested. \production{comment} & \Tcomment &::=& \Tlinecomment ~|~ \Tblockcomment \\ \production{line comment} & \Tlinecomment &::=& - \text{\verb|;;|}~~\Tlinechar^\ast~~(\hex{0A} ~|~ \T{eof}) \\ + \text{\verb|;;|}~~\Tlinechar^\ast~~(\unicode{0A} ~|~ \T{eof}) \\ \production{line character} & \Tlinechar &::=& - c{:}\Tchar & (c \neq \hex{0A}) \\ + c{:}\Tchar & (c \neq \unicode{0A}) \\ \production{block comment} & \Tblockcomment &::=& \text{\verb|(;|}~~\Tblockchar^\ast~~\text{\verb|;)|} \\ \production{block character} & \Tblockchar &::=& @@ -95,5 +91,5 @@ Block comments can be nested. \Tblockcomment \\ \end{array} -Here, the binary ASCII code :math:`\text{0A}` is used to denote the end-of-line character and the pseudo token :math:`\T{eof}` indicates the end of the input. -The *look-ahead* restrictions on |Tblockchar| disambiguate the grammar such that only well-bracketted uses of block comment delimiters are allowed. +Here, the pseudo token :math:`\T{eof}` indicates the end of the input. +The *look-ahead* restrictions on the productions for |Tblockchar| disambiguate the grammar such that only well-bracketed uses of block comment delimiters are allowed. diff --git a/document/text/values.rst b/document/text/values.rst index 7920e1a29d..d578dc3c0e 100644 --- a/document/text/values.rst +++ b/document/text/values.rst @@ -29,15 +29,19 @@ All :ref:`integers ` can be written in either decimal or hexadecimal .. math:: \begin{array}{llclll@{\qquad}l} \production{sign} & \Tsign &::=& - \epsilon \Rightarrow {+}1 ~|~ - \text{+} \Rightarrow {+}1 ~|~ + \epsilon \Rightarrow {+}1 ~~|~~ + \text{+} \Rightarrow {+}1 ~~|~~ \text{-} \Rightarrow {-}1 \\ \production{decimal digit} & \Tdigit &::=& - \text{0} \Rightarrow 0 ~|~ \dots ~|~ \text{9} \Rightarrow 9 \\ + \text{0} \Rightarrow 0 ~~|~~ \dots ~~|~~ \text{9} \Rightarrow 9 \\ \production{hexadecimal digit} & \Thexdigit &::=& d{:}\Tdigit \Rightarrow d \\ &&|& - \text{A} \Rightarrow 10 ~|~ \dots ~|~ \text{F} \Rightarrow 15 \\ &&|& - \text{a} \Rightarrow 10 ~|~ \dots ~|~ \text{f} \Rightarrow 15 \\ + \text{A} \Rightarrow 10 ~~|~~ \dots ~~|~~ \text{F} \Rightarrow 15 \\ &&|& + \text{a} \Rightarrow 10 ~~|~~ \dots ~~|~~ \text{f} \Rightarrow 15 \\ + \end{array} + +.. math:: + \begin{array}{llclll@{\qquad}l} \production{decimal number} & \Tnum &::=& d{:}\Tdigit &\Rightarrow& d \\ &&|& n{:}\Tnum~~d{:}\Tdigit &\Rightarrow& 10\cdot n + d \\ @@ -148,17 +152,32 @@ Vectors Strings ~~~~~~~ -*Strings* denote sequences of bytes that can represent both textual and binary data. +*Strings* denote sequences of characters that can represent both textual and binary data. They are enclosed in quotation marks -and may contain any *printable* `ASCII `_ character other than quotation marks (:math:`\text{"}`) or backslash (:math:`\text{\verb|\|}`), +and may contain any character other than `ASCII `_ control characters, quotation marks (:math:`\text{"}`), or backslash (:math:`\text{\verb|\|}`), except when expressed with an *escape sequence* started by a backslash. .. math:: \begin{array}{llclll@{\qquad\qquad}l} \production{string} & \Tstring &::=& - \text{"}~(b{:}\Tstringchar)^\ast~\text{"} - \quad\Rightarrow\quad b^\ast \\ + \text{"}~(c{:}\Tstringchar)^\ast~\text{"} + &\Rightarrow& c^\ast \\ \production{string character} & \Tstringchar &::=& + c{:}\Tchar &\Rightarrow& c \qquad + & (c \geq \unicode{20} \wedge c \neq \unicode{7F} \wedge c \neq \text{"} c \neq \text{\verb|\|}) \\ &&|& + \text{\verb|\t|} &\Rightarrow& \unicode{09} \\ &&|& + \text{\verb|\n|} &\Rightarrow& \unicode{0A} \\ &&|& + \text{\verb|\r|} &\Rightarrow& \unicode{0D} \\ &&|& + \text{\verb|\"|} &\Rightarrow& \unicode{22} \\ &&|& + \text{\verb|\'|} &\Rightarrow& \unicode{27} \\ &&|& + \text{\verb|\\|} &\Rightarrow& \unicode{5C} \\ &&|& + \text{\verb|\|}~n{:}\Thexdigit~m{:}\Thexdigit + &\Rightarrow& \unicode{(16\cdot n+m)} \\ &&|& + \text{\verb|\u|\{}~n{:}\Thexnum~\text{\}} + &\Rightarrow& \unicode{(n)} & (n < \hex{110000}) \\ + \end{array} + +.. commented out \text{~~} ~~\Rightarrow~~ \hex{20} ~~~|~~~ \text{!} ~~\Rightarrow~~ \hex{21} \\ &&|& \text{\#} ~~\Rightarrow~~ \hex{23} ~~~|~~~ @@ -167,13 +186,36 @@ except when expressed with an *escape sequence* started by a backslash. \text{]} ~~\Rightarrow~~ \hex{5D} ~~~|~~~ \cdots ~~~|~~~ \text{\verb|~|} ~~\Rightarrow~~ \hex{7E} \\ &&|& - \text{\verb|\t|} ~~\Rightarrow~~ \hex{09} \\ &&|& - \text{\verb|\n|} ~~\Rightarrow~~ \hex{0A} \\ &&|& - \text{\verb|\r|} ~~\Rightarrow~~ \hex{0D} \\ &&|& - \text{\verb|\"|} ~~\Rightarrow~~ \hex{22} \\ &&|& - \text{\verb|\'|} ~~\Rightarrow~~ \hex{27} \\ &&|& - \text{\verb|\\|} ~~\Rightarrow~~ \hex{5C} \\ &&|& - \text{\verb|\|}~n{:}\Thexdigit~m{:}\Thexdigit ~~\Rightarrow~~ 16\cdot n+m \\ + + Due to the limitations of the :ref:`binary format `, the length of strings is limited by the length of their `Unicode `_ UTF-8 encoding. + + The auxiliary |utf8| function is defined as follows: + + .. math:: + \begin{array}{lcl@{\qquad}l} + \utf8(c^\ast) &=& (\utf8(c))^\ast \\[1ex] + \utf8(c) &=& b & (c < \unicode{80} \wedge c = b) \\ + \utf8(c) &=& b_1~b_2 & (\unicode{80} \leq c < \unicode{800} \wedge c = 2^6\cdot(b_1-\hex{C0})+(b_2-\hex{80})) \\ + \utf8(c) &=& b_1~b_2~b_3 & (\unicode{800} \leq c < \unicode{10000} \wedge c = 2^{12}\cdot(b_1-\hex{C0})+2^6\cdot(b_2-\hex{80})+(b_3-\hex{80})) \\ + \utf8(c) &=& b_1~b_2~b_3~b_4 & (\unicode{10000} \leq c < \unicode{110000} \wedge c = 2^{18}\cdot(b_1-\hex{C0})+2^{12}\cdot(b_2-\hex{80})+2^6\cdot(b_3-\hex{80})+(b_4-\hex{80})) \\ + \end{array} + + +.. _text-bytes: +.. index:: bytes, byte + pair: text format; bytes + +Bytes +~~~~~ + +:ref:`Bytes ` are strings denoting a sequence of raw :ref:`bytes `. +They may contain only code points that are within range for a byte. + +.. math:: + \begin{array}{llclll@{\qquad}l} + \production{bytes} & \Tbytes &::=& + c^\ast{:}\Tstring &\Rightarrow& b^\ast + & ((\unicode{(b)} = c \leq \unicode{FF})^\ast) \\ \end{array} @@ -184,17 +226,14 @@ except when expressed with an *escape sequence* started by a backslash. Names ~~~~~ -:ref:`Names ` are strings denoting a byte sequence that must form a valid `Unicode `_ UTF-8 encoding. +:ref:`Names ` are strings denoting a literal character sequence. .. math:: \begin{array}{llclll@{\qquad}l} \production{name} & \Tname &::=& - b^\ast{:}\Tstring &\Rightarrow& \X{uc}^n - & (\utf8(\X{uc}^n) = b^\ast \wedge n < 2^{32}) \\ + c^\ast{:}\Tstring &\Rightarrow& c^\ast \\ \end{array} -.. todo:: UTF-8 decoding - .. _text-id: .. index:: ! identifiers @@ -209,7 +248,7 @@ Symbolic *identifiers* standing for indices start with :math:`\text{$}`, followe .. math:: \begin{array}{llclll@{\qquad}l} \production{identifier} & \Tid &::=& - \text{$}~(b{:}\Tidchar)^+ \\ + \text{$}~(c{:}\Tidchar)^+ \\ \production{identifier character} & \Tidchar &::=& \text{0} ~~|~~ \dots ~~|~~ \text{9} \\ &&|& \text{A} ~~|~~ \dots ~~|~~ \text{Z} \\ &&|& From 6cfc342add4313cb8ae83eeeffcbac2c07faaf50 Mon Sep 17 00:00:00 2001 From: rossberg-chromium Date: Mon, 8 May 2017 14:17:19 +0200 Subject: [PATCH 07/30] Finish --- document/binary/modules.rst | 6 +-- document/binary/values.rst | 4 +- document/math.def | 8 ++-- document/syntax/conventions.rst | 2 + document/syntax/values.rst | 22 +++++++---- document/text/conventions.rst | 5 ++- document/text/lexical.rst | 10 +++-- document/text/values.rst | 69 +++++++++------------------------ interpreter/Makefile | 2 +- interpreter/text/lexer.mll | 34 +++++++++++----- 10 files changed, 80 insertions(+), 82 deletions(-) diff --git a/document/binary/modules.rst b/document/binary/modules.rst index aa904566f2..766d0daaef 100644 --- a/document/binary/modules.rst +++ b/document/binary/modules.rst @@ -343,14 +343,14 @@ denoting *count* locals of the same value type. &\Rightarrow& \X{code} & (\X{size} = ||\Bfunc||) \\ \production{functions} & \Bfunc &::=& (t^\ast)^\ast{:}\Bvec(\Blocals)~~e{:}\Bexpr - &\Rightarrow& \F{concat}((t^\ast)^\ast), e^\ast - & (|\F{concat}((t^\ast)^\ast)| < 2^{32}) \\ + &\Rightarrow& \concat((t^\ast)^\ast), e^\ast + & (|\concat((t^\ast)^\ast)| < 2^{32}) \\ \production{locals} & \Blocals &::=& n{:}\Bu32~~t{:}\Bvaltype &\Rightarrow& t^n \\ \end{array} Here, :math:`\X{code}` ranges over pairs :math:`(\valtype^\ast, \expr)`. -The meta function :math:`\F{concat}((t^\ast)^\ast)` denotes the sequence of types formed by concatenating all sequences :math:`t_i^\ast` in :math:`(t^\ast)^\ast`. +The meta function :math:`\F{concat}((t^\ast)^\ast)` concatenates all sequences :math:`t_i^\ast` in :math:`(t^\ast)^\ast`. Any code for which the length of the resulting sequence is out of bounds of the maximum size of a :ref:`vector ` is malformed. .. note:: diff --git a/document/binary/values.rst b/document/binary/values.rst index 4942706087..330aea72fa 100644 --- a/document/binary/values.rst +++ b/document/binary/values.rst @@ -27,7 +27,7 @@ Bytes .. _binary-int: .. _binary-sint: .. _binary-uint: -.. index:: integer, unsigned integer, signed integer, uninterpreted integer +.. index:: integer, unsigned integer, signed integer, uninterpreted integer, LEB128 pair: binary format; integer pair: binary format; unsigned integer pair: binary format; signed integer @@ -116,7 +116,7 @@ Vectors .. _binary-name: -.. index:: name, byte +.. index:: name, byte, Unicode, UTF-8 pair: binary format; name Names diff --git a/document/math.def b/document/math.def index da5eb49fd0..59652ac0fa 100644 --- a/document/math.def +++ b/document/math.def @@ -22,6 +22,7 @@ .. Auxiliary definitions for grammars .. |production| mathdef:: \void +.. |concat| mathdef:: \xref{syntax/conventions}{syntax-concat}{\F{concat}} .. |with| mathdef:: ~\xref{syntax/conventions}{syntax-record}{\mbox{with}}~ @@ -40,7 +41,7 @@ .. Lexical grammar, meta functions -.. |utf8| mathdef:: \xref{text/values}{text-bytes}{\F{utf8}} +.. |utf8| mathdef:: \xref{syntax/values}{syntax-utf8}{\F{utf8}} .. Values, terminals @@ -123,8 +124,6 @@ .. Values, textual non-terminals .. |Tbyte| mathdef:: \xref{text/values}{text-byte}{\T{byte}} -.. |Tstring| mathdef:: \xref{text/values}{text-string}{\T{string}} -.. |Tstringchar| mathdef:: \xref{text/values}{text-string}{\T{stringchar}} .. |Tsign| mathdef:: \xref{text/values}{text-sign}{\T{sign}} .. |Tdigit| mathdef:: \xref{text/values}{text-digit}{\T{digit}} @@ -161,6 +160,9 @@ .. |Tf64| mathdef:: \xref{text/values}{text-float}{\TfX{\T{64}}} .. |Tvec| mathdef:: \xref{text/values}{text-vec}{\T{vec}} +.. |Tstring| mathdef:: \xref{text/values}{text-string}{\T{string}} +.. |Tstringelem| mathdef:: \xref{text/values}{text-string}{\T{stringelem}} +.. |Tstringchar| mathdef:: \xref{text/values}{text-string}{\T{stringchar}} .. |Tname| mathdef:: \xref{text/values}{text-name}{\T{name}} .. |Tcodepoint| mathdef:: \xref{text/values}{text-name}{\T{codepoint}} .. |Tcodeval| mathdef:: \xref{text/values}{text-name}{\T{codeval}} diff --git a/document/syntax/conventions.rst b/document/syntax/conventions.rst index 63413f5459..2a0884c2ba 100644 --- a/document/syntax/conventions.rst +++ b/document/syntax/conventions.rst @@ -47,6 +47,8 @@ When dealing with syntactic constructs the following notation is also used: * :math:`s[i]` denotes the :math:`i`-th element of a sequence :math:`s`, starting from :math:`0`. +* :math:`\concat(s^\ast)` denotes the flat sequence formed by concatenating all sequences :math:`s_i^\ast` in :math:`s^\ast`. + Productions of the following form are interpreted as *records* that map a fixed set of fields :math:`\K{field}_i` to values :math:`x_i`, respectively: .. math:: diff --git a/document/syntax/values.rst b/document/syntax/values.rst index 6093043380..e0741bf14d 100644 --- a/document/syntax/values.rst +++ b/document/syntax/values.rst @@ -112,7 +112,8 @@ A vector can have at most :math:`2^{32}-1` elements. .. _syntax-name: -.. index:: ! name, byte +.. _syntax-utf8: +.. index:: ! name, byte, Unicode, UTF-8, code point pair: abstract syntax; name Names @@ -123,17 +124,24 @@ Names .. math:: \begin{array}{llll} \production{names} & \name &::=& - \codepoint^\ast \\ + \codepoint^\ast & (|\utf(\codepoint^\ast)| < 2^{32}) \\ \production{code points} & \codepoint &::=& \unicode{0000} ~|~ \dots ~|~ \unicode{D7FF} ~|~ \unicode{E000} ~|~ \dots ~|~ \unicode{10FFFF} \\ \end{array} -.. todo:: - The definition of a name as an arbitrary sequence of scalar code points is too general. - So would be the definition of a vector. - Only names whose UTF-8 encoding is within the bounds of the maximum vector lengths must be included. - How specify this? +Due to the limitations of the :ref:`binary format `, +the lengths of a name is bounded by the length of its `UTF-8 `_ encoding. +The auxiliary |utf8| function expressing this encoding is defined as follows: + +.. math:: + \begin{array}{lcl@{\qquad}l} + \utf8(c^\ast) &=& (\utf8(c))^\ast \\[1ex] + \utf8(c) &=& b & (c < \unicode{80} \wedge c = b) \\ + \utf8(c) &=& b_1~b_2 & (\unicode{80} \leq c < \unicode{800} \wedge c = 2^6\cdot(b_1-\hex{C0})+(b_2-\hex{80})) \\ + \utf8(c) &=& b_1~b_2~b_3 & (\unicode{800} \leq c < \unicode{10000} \wedge c = 2^{12}\cdot(b_1-\hex{C0})+2^6\cdot(b_2-\hex{80})+(b_3-\hex{80})) \\ + \utf8(c) &=& b_1~b_2~b_3~b_4 & (\unicode{10000} \leq c < \unicode{110000} \wedge c = 2^{18}\cdot(b_1-\hex{C0})+2^{12}\cdot(b_2-\hex{80})+2^6\cdot(b_3-\hex{80})+(b_4-\hex{80})) \\ + \end{array} Convention diff --git a/document/text/conventions.rst b/document/text/conventions.rst index cd10437679..69f9336751 100644 --- a/document/text/conventions.rst +++ b/document/text/conventions.rst @@ -1,4 +1,4 @@ -.. index:: ! text format +.. index:: ! text format, Unicode, UTF-8 Conventions ----------- @@ -17,10 +17,11 @@ Except for a few exceptions, the core of the text grammar closely mirrors the gr However, it also defines a number of forms that are *syntactic sugar* over the core syntax. The recommended extension for source files containing WebAssembly modules in text format is ":math:`\T{.wat}`". +Files with this extension are assumed to be encoded in `Unicode UTF-8 `_. .. _text-grammar: -.. index:: grammar notation, notation +.. index:: grammar notation, notation, Unicode single: text format; grammar pair: text format; notation diff --git a/document/text/lexical.rst b/document/text/lexical.rst index 13418d7b2f..ff7c8a002a 100644 --- a/document/text/lexical.rst +++ b/document/text/lexical.rst @@ -5,7 +5,7 @@ Lexical Format .. _text-char: -.. index:: ! character +.. index:: ! character, Unicode, ASCII, code point pair: text format; character Characters @@ -26,7 +26,7 @@ Characters are assumed to be represented as valid `Unicode ` literals, white space cannot appear insid .. _text-space: -.. index:: ! white space +.. index:: ! white space, character, ASCII + single: text format; white space White Space ~~~~~~~~~~~ @@ -65,7 +66,8 @@ A format character corresponds to an `ASCII `_ control characters, quotation marks (:math:`\text{"}`), or backslash (:math:`\text{\verb|\|}`), except when expressed with an *escape sequence* started by a backslash. +Each character in a string literal represents the byte sequence corresponding to its `Unicode `_ UTF-8 encoding, +except for hexadecimal escape sequences :math:`\text{\verb|\|}hh`, which represent raw bytes of the respective value. + .. math:: \begin{array}{llclll@{\qquad\qquad}l} \production{string} & \Tstring &::=& - \text{"}~(c{:}\Tstringchar)^\ast~\text{"} - &\Rightarrow& c^\ast \\ + \text{"}~(b^\ast{:}\Tstringelem)^\ast~\text{"} + &\Rightarrow& \concat((b^\ast)^\ast) + & (|\concat((b^\ast)^\ast)| < 2^{32}) \\ + \production{string element} & \Tstringelem &::=& + c{:}\Tstringchar &\Rightarrow& \utf8(c) \\ &&|& + \text{\verb|\|}~n{:}\Thexdigit~m{:}\Thexdigit + &\Rightarrow& 16\cdot n+m \\ \production{string character} & \Tstringchar &::=& c{:}\Tchar &\Rightarrow& c \qquad & (c \geq \unicode{20} \wedge c \neq \unicode{7F} \wedge c \neq \text{"} c \neq \text{\verb|\|}) \\ &&|& @@ -171,69 +179,30 @@ except when expressed with an *escape sequence* started by a backslash. \text{\verb|\"|} &\Rightarrow& \unicode{22} \\ &&|& \text{\verb|\'|} &\Rightarrow& \unicode{27} \\ &&|& \text{\verb|\\|} &\Rightarrow& \unicode{5C} \\ &&|& - \text{\verb|\|}~n{:}\Thexdigit~m{:}\Thexdigit - &\Rightarrow& \unicode{(16\cdot n+m)} \\ &&|& \text{\verb|\u|\{}~n{:}\Thexnum~\text{\}} - &\Rightarrow& \unicode{(n)} & (n < \hex{110000}) \\ - \end{array} - -.. commented out - \text{~~} ~~\Rightarrow~~ \hex{20} ~~~|~~~ - \text{!} ~~\Rightarrow~~ \hex{21} \\ &&|& - \text{\#} ~~\Rightarrow~~ \hex{23} ~~~|~~~ - \cdots ~~~|~~~ - \text{[} ~~\Rightarrow~~ \hex{5B} \\ &&|& - \text{]} ~~\Rightarrow~~ \hex{5D} ~~~|~~~ - \cdots ~~~|~~~ - \text{\verb|~|} ~~\Rightarrow~~ \hex{7E} \\ &&|& - - Due to the limitations of the :ref:`binary format `, the length of strings is limited by the length of their `Unicode `_ UTF-8 encoding. - - The auxiliary |utf8| function is defined as follows: - - .. math:: - \begin{array}{lcl@{\qquad}l} - \utf8(c^\ast) &=& (\utf8(c))^\ast \\[1ex] - \utf8(c) &=& b & (c < \unicode{80} \wedge c = b) \\ - \utf8(c) &=& b_1~b_2 & (\unicode{80} \leq c < \unicode{800} \wedge c = 2^6\cdot(b_1-\hex{C0})+(b_2-\hex{80})) \\ - \utf8(c) &=& b_1~b_2~b_3 & (\unicode{800} \leq c < \unicode{10000} \wedge c = 2^{12}\cdot(b_1-\hex{C0})+2^6\cdot(b_2-\hex{80})+(b_3-\hex{80})) \\ - \utf8(c) &=& b_1~b_2~b_3~b_4 & (\unicode{10000} \leq c < \unicode{110000} \wedge c = 2^{18}\cdot(b_1-\hex{C0})+2^{12}\cdot(b_2-\hex{80})+2^6\cdot(b_3-\hex{80})+(b_4-\hex{80})) \\ - \end{array} - - -.. _text-bytes: -.. index:: bytes, byte - pair: text format; bytes - -Bytes -~~~~~ - -:ref:`Bytes ` are strings denoting a sequence of raw :ref:`bytes `. -They may contain only code points that are within range for a byte. - -.. math:: - \begin{array}{llclll@{\qquad}l} - \production{bytes} & \Tbytes &::=& - c^\ast{:}\Tstring &\Rightarrow& b^\ast - & ((\unicode{(b)} = c \leq \unicode{FF})^\ast) \\ + &\Rightarrow& \unicode{(n)} & (n < \hex{D800} \vee \hex{E000} \leq n < \hex{110000}) \\ \end{array} .. _text-name: -.. index:: name, byte +.. index:: name, byte, character, code point pair: text format; name Names ~~~~~ :ref:`Names ` are strings denoting a literal character sequence. +It must form a valid `UTF-8 `_ encoding that is interpreted as a string of Unicode code points. .. math:: \begin{array}{llclll@{\qquad}l} \production{name} & \Tname &::=& - c^\ast{:}\Tstring &\Rightarrow& c^\ast \\ + b^\ast{:}\Tstring &\Rightarrow& c^\ast & (b^\ast = \utf8(c^\ast)) \\ \end{array} +.. note:: + Strings that do not contain any uses of hexadecimal byte escapes are always valid names. + .. _text-id: .. index:: ! identifiers diff --git a/interpreter/Makefile b/interpreter/Makefile index 4aab91505e..fe40d15980 100644 --- a/interpreter/Makefile +++ b/interpreter/Makefile @@ -112,7 +112,7 @@ run/%: $(NAME) ./$(NAME) $(@:run/%=../test/core/%.wast) clean: - rm -rf _build/jslib + rm -rf _build/jslib wasm.mlpack $(OCB) -clean diff --git a/interpreter/text/lexer.mll b/interpreter/text/lexer.mll index cd9ba11f31..c6af499743 100644 --- a/interpreter/text/lexer.mll +++ b/interpreter/text/lexer.mll @@ -25,13 +25,21 @@ let text s = let c = if s.[!i] <> '\\' then s.[!i] else match (incr i; s.[!i]) with | 'n' -> '\n' + | 'r' -> '\r' | 't' -> '\t' | '\\' -> '\\' | '\'' -> '\'' | '\"' -> '\"' - | d -> + | 'u' -> + let j = !i + 2 in + i := String.index_from s j '}'; + let n = int_of_string ("0x" ^ String.sub s j (!i - j)) in + let bs = Utf8.encode n in + Buffer.add_substring b bs 0 (String.length bs - 1); + bs.[String.length bs - 1] + | h -> incr i; - Char.chr (int_of_string ("0x" ^ String.make 1 d ^ String.make 1 s.[!i])) + Char.chr (int_of_string ("0x" ^ String.make 1 h ^ String.make 1 s.[!i])) in Buffer.add_char b c; incr i done; @@ -81,29 +89,35 @@ let opt = Lib.Option.get } let space = [' ''\x08'-'\x09''\x0b'-'\x0d'] + +let sign = '+' | '-' let digit = ['0'-'9'] let hexdigit = ['0'-'9''a'-'f''A'-'F'] +let num = digit+ +let hexnum = hexdigit+ + let letter = ['a'-'z''A'-'Z'] let symbol = ['+''-''*''/''\\''^''~''=''<''>''!''?''@''#''$''%''&''|'':''`''.''\''] + let escape = ['n''r''t''\\''\'''\"'] let character = - [^'"''\\''\x00'-'\x1f''\x7f'] | '\\'escape | '\\'hexdigit hexdigit + [^'"''\\''\x00'-'\x1f''\x7f'] + | '\\'escape + | '\\'hexdigit hexdigit + | "\\u{" hexnum '}' -let sign = ('+' | '-') -let num = digit+ -let hexnum = "0x" hexdigit+ -let nat = num | hexnum +let nat = num | "0x" hexnum let int = sign nat let float = sign? num '.' digit* | sign? num ('.' digit*)? ('e' | 'E') sign? num - | sign? hexnum '.' hexdigit* - | sign? hexnum ('.' hexdigit*)? ('p' | 'P') sign? num + | sign? "0x" hexnum '.' hexdigit* + | sign? "0x" hexnum ('.' hexdigit*)? ('p' | 'P') sign? num | sign? "inf" | sign? "infinity" | sign? "nan" - | sign? "nan:" hexnum + | sign? "nan:" "0x" hexnum let text = '"' character* '"' let name = '$' (letter | digit | '_' | symbol)+ From 5cac42def23a6aeccd3cca422edf4043a1ef3697 Mon Sep 17 00:00:00 2001 From: rossberg-chromium Date: Mon, 8 May 2017 18:24:32 +0200 Subject: [PATCH 08/30] Locals, params --- document/math.def | 6 ++ document/text/conventions.rst | 9 ++- document/text/instructions.rst | 76 +++++++++++++++---- document/text/modules.rst | 129 ++++++++++++++++++++------------- document/text/types.rst | 25 +++++-- document/text/values.rst | 18 ++--- interpreter/README.md | 4 +- interpreter/host/import.ml | 4 +- interpreter/host/js.ml | 2 +- interpreter/host/run.ml | 18 ++--- interpreter/spec/ast.ml | 12 +++ interpreter/text/lexer.mll | 2 +- interpreter/text/parser.mly | 24 +++--- 13 files changed, 221 insertions(+), 108 deletions(-) diff --git a/document/math.def b/document/math.def index 59652ac0fa..6003e7990d 100644 --- a/document/math.def +++ b/document/math.def @@ -490,8 +490,14 @@ .. |Talign| mathdef:: \xref{text/instructions}{text-memarg}{\T{align}} .. |Toffset| mathdef:: \xref{text/instructions}{text-memarg}{\T{offset}} +.. |Tlabel| mathdef:: \xref{text/instructions}{text-label}{\T{label}} .. |Tinstr| mathdef:: \xref{text/instructions}{text-instr}{\T{instr}} .. |Tplaininstr| mathdef:: \xref{text/instructions}{text-plaininstr}{\T{plaininstr}} .. |Tblockinstr| mathdef:: \xref{text/instructions}{text-blockinstr}{\T{blockinstr}} .. |Tfoldedinstr| mathdef:: \xref{text/instructions}{text-foldedinstr}{\T{foldedinstr}} .. |Texpr| mathdef:: \xref{text/instructions}{text-expr}{\T{expr}} + + +.. Context, textual + +.. |TYPEDEFS| mathdef:: \K{typedefs} diff --git a/document/text/conventions.rst b/document/text/conventions.rst index 69f9336751..380e8be9cd 100644 --- a/document/text/conventions.rst +++ b/document/text/conventions.rst @@ -1,4 +1,4 @@ -.. index:: ! text format, Unicode, UTF-8 +.. index:: ! text format, Unicode, UTF-8, S-expression Conventions ----------- @@ -90,6 +90,7 @@ When dealing with binary encodings the following notation is also used: .. text-context: +.. text-context-wf: .. index:: ! identifier context, identifier, index, index space Contexts @@ -98,6 +99,7 @@ Contexts The text format allows to use symbolic :ref:`identifiers ` in place of :ref:`indices `. To resolve these identifiers into concrete indices, some grammar production are indexed by an *identifier context* that records the declared identifiers in each :ref:`index space `. +In addition, the context records the types defined in the module, so that parameter indices can be computed. It is convenient to define identifier contexts as :ref:`records ` :math:`I` with abstract syntax: @@ -111,11 +113,12 @@ It is convenient to define identifier contexts as :ref:`records ` & \MEMS & (\Tid^?)^\ast, \\ & \GLOBALS & (\Tid^?)^\ast, \\ & \LOCALS & (\Tid^?)^\ast, \\ - & \LABELS & (\Tid^?)^\ast ~\} \\ + & \LABELS & (\Tid^?)^\ast, \\ + & \TYPEDEFS & \functype^\ast ~\} \\ \end{array} \end{array} For each index space, an identifier context contains the list of :ref:`identifiers ` assigned to the defined indices. Unnamed indices are associated with empty (:math:`\epsilon`) entries in these lists. -It is an invariant of the specification that no component contains duplicate identifiers. +An identifier context is *well-formed* if no index space contains duplicate identifiers. diff --git a/document/text/instructions.rst b/document/text/instructions.rst index efe8b416ca..ea1d55b285 100644 --- a/document/text/instructions.rst +++ b/document/text/instructions.rst @@ -4,8 +4,8 @@ Instructions ------------ -.. todo:: symbolic labels - +Instructions are syntactically distinguished into *plain* and *structured* instructions. +Both can also be written in :ref:`folded ` form. .. math:: \begin{array}{llclll} @@ -19,6 +19,26 @@ Instructions \end{array} +.. _text-label: +.. index:: index, label index + pair: text format; label index + +Labels +~~~~~~ + +All :ref:`indices ` can be given either in raw numeric or in symbolic form. +:ref:`Labels ` are the only symbolic indices that can be defined locally in an :ref:`instruction sequence `. +The following grammar handles the corresponding update to the :ref:`identifier context ` by producing a context with an additional label entry. + +.. math:: + \begin{array}{llclll} + \production{label} & \Tlabel_I &::=& + \epsilon &\Rightarrow& I \with \LABELS~(\epsilon)~I.\LABELS \\ &&|& + v{:}\Tid &\Rightarrow& I \with \LABELS~v~I.\LABELS + & (v \notin I.\LABELS) \\ + \end{array} + + .. _text-instr-control: .. index:: control instructions, structured control, label, block, branch, result type, label index, function index, type index, vector, polymorphism pair: text format; instruction @@ -41,13 +61,13 @@ Control Instructions .. math:: \begin{array}{llclll} \production{block instruction} & \Tblockinstr_I &::=& - \text{block}~~I'{:}\Tlabelbind_I~~\X{rt}{:}\Tblocktype~~(\X{in}{:}\Tinstr_{I'})^\ast~~\text{end} + \text{block}~~I'{:}\Tlabel_I~~\X{rt}{:}\Tresulttype~~(\X{in}{:}\Tinstr_{I'})^\ast~~\text{end} &\Rightarrow& \BLOCK~\X{rt}~\X{in}^\ast~\END \\ &&|& - \text{loop}~~I'{:}\Tlabelbind_I~~\X{rt}{:}\Tblocktype~~(\X{in}{:}\Tinstr_{I'})^\ast~~\text{end} + \text{loop}~~I'{:}\Tlabel_I~~\X{rt}{:}\Tresulttype~~(\X{in}{:}\Tinstr_{I'})^\ast~~\text{end} &\Rightarrow& \LOOP~\X{rt}~\X{in}^\ast~\END \\ &&|& - \text{if}~~I'{:}\Tlabelbind_I~~\X{rt}{:}\Tblocktype~~(\X{in}{:}\Tinstr_{I'})^\ast~~\text{end} + \text{if}~~I'{:}\Tlabel_I~~\X{rt}{:}\Tresulttype~~(\X{in}{:}\Tinstr_{I'})^\ast~~\text{end} &\Rightarrow& \IF~\X{rt}~\X{in}^\ast~\ELSE~\epsilon~\END \\ &&|& - \text{if}~~I'{:}\Tlabelbind_I~~\X{rt}{:}\Tblocktype~~(\X{in}_1{:}\Tinstr_{I'})^\ast~~ + \text{if}~~I'{:}\Tlabel_I~~\X{rt}{:}\Tresulttype~~(\X{in}_1{:}\Tinstr_{I'})^\ast~~ \text{else}~~(\X{in}_2{:}\Tinstr_{I'})^\ast~~\text{end} &\Rightarrow& \IF~\X{rt}~\X{in}_1^\ast~\ELSE~\X{in}_2^\ast~\END \\ \production{plain instruction} & \Tplaininstr_I &::=& @@ -62,8 +82,19 @@ Control Instructions \text{call\_indirect}~~x{:}\Ttypeidx_I &\Rightarrow& \CALLINDIRECT~x \\ \end{array} -.. note:: - The :math:`\text{else}` keyword of an :math:`\text{if}` instruction can be omitted if the following instruction sequence is empty. + +Abbreviations +............. + +The :math:`\text{else}` keyword of an :math:`\text{if}` instruction can be omitted if the following instruction sequence is empty. + +.. math:: + \begin{array}{llclll} + \production{block instruction} & + \text{if}~~\Tlabel~~\Tresulttype~~\Tinstr^\ast~~\text{end} + &\equiv& + \text{if}~~\Tlabel~~\Tresulttype~~\Tinstr^\ast~~\text{else}~~\text{end} + \end{array} .. _text-instr-parametric: @@ -358,23 +389,42 @@ Numeric Instructions \end{array} -.. _text-foldedinstr: +.. index:: ! folded instruction, S-expression + Folded Instructions ~~~~~~~~~~~~~~~~~~~ +As a further abbreviation, instructions can also be written in *folded* S-expression form. + .. math:: + \begin{array}{lllll} + \production{instruction} & + \text{(}~\Tplaininstr~~\Tfoldedinstr^\ast~\text{)} + &\equiv\quad \Tfoldedinstr^\ast~~\Tplaininstr \\ & + \text{(}~\text{block}~~\Tlabel~~\Tresulttype~~\Tinstr^\ast~\text{)} + &\equiv\quad \text{block}~~\Tlabel~~\Tresulttype~~\Tinstr^\ast~~\text{end} \\ & + \text{(}~\text{loop}~~\Tresulttype~~\Tinstr^\ast~\text{)} + &\equiv\quad \text{loop}~~\Tlabel~~\Tresulttype~~\Tinstr^\ast~~\text{end} \\ & + \text{(}~\text{if}~~\Tlabel~~\Tresulttype~~\Tfoldedinstr + &\hspace{-1ex} \text{(}~\text{then}~~\Tinstr_1^\ast~\text{)}~~\text{(}~\text{else}~~\Tinstr_2^\ast~\text{)}^?~~\text{)} + \quad\equiv \\ &\qquad + \Tfoldedinstr~~\text{if}~~\Tresulttype \hspace{-2em}& + ~\Tinstr_1^\ast~~\text{else}~~(\Tinstr_2^\ast)^?~\text{end} \\ + \end{array} + +.. math (commented out) \begin{array}{llclll} \production{folded instruction} & \Tfoldedinstr_I &::=& \text{(}~\X{in}{:}\Tplaininstr~~(\X{op}{:}\Tfoldedinstr_I)^\ast~\text{)} &\Rightarrow& \X{op}^\ast~\X{in} \\ &&|& - \text{(}~\text{block}~~\X{rt}{:}\Tblocktype~~(\X{in}{:}\Tinstr_{I'})^\ast~\text{)} + \text{(}~\text{block}~~\X{rt}{:}\Tresulttype~~(\X{in}{:}\Tinstr_{I'})^\ast~\text{)} &\Rightarrow& \BLOCK~\X{rt}~\X{in}^\ast~\END \\ &&|& - \text{(}~\text{loop}~~\X{rt}{:}\Tblocktype~~(\X{in}{:}\Tinstr_{I'})^\ast~\text{)} + \text{(}~\text{loop}~~\X{rt}{:}\Tresulttype~~(\X{in}{:}\Tinstr_{I'})^\ast~\text{)} &\Rightarrow& \LOOP~\X{rt}~\X{in}^\ast~\END \\ &&|& - \text{(}~\text{if}~~\X{rt}{:}\Tblocktype~~\X{in}_0^\ast{:}\Tfoldedinstr_I~~\text{(}~\text{then}~~(\X{in}{:}\Tinstr_{I'})^\ast~\text{)}~~\text{)} + \text{(}~\text{if}~~\X{rt}{:}\Tresulttype~~\X{in}_0^\ast{:}\Tfoldedinstr_I~~\text{(}~\text{then}~~(\X{in}{:}\Tinstr_{I'})^\ast~\text{)}~~\text{)} &\Rightarrow& \X{in}_0^\ast~~\IF~\X{rt}~\X{in}^\ast~\ELSE~\epsilon~\END \\ &&|& - \text{(}~\text{if}~~\X{rt}{:}\Tblocktype~~\X{in}_0^\ast{:}\Tfoldedinstr_I~~\text{(}~\text{then}~~(\X{in}_1{:}\Tinstr_{I'})^\ast~\text{)}~~ + \text{(}~\text{if}~~\X{rt}{:}\Tresulttype~~\X{in}_0^\ast{:}\Tfoldedinstr_I~~\text{(}~\text{then}~~(\X{in}_1{:}\Tinstr_{I'})^\ast~\text{)}~~ \text{(}~\text{else}~~(\X{in}_2{:}\Tinstr_{I'})^\ast~\text{)}~~\text{)} &\Rightarrow& \X{in}_0^\ast~~\IF~\X{rt}~\X{in}_1^\ast~\ELSE~\X{in}_2^\ast~\END \\ \end{array} diff --git a/document/text/modules.rst b/document/text/modules.rst index 78528d843f..63898c18a2 100644 --- a/document/text/modules.rst +++ b/document/text/modules.rst @@ -1,7 +1,7 @@ Modules ------- -.. todo:: symbolic indices; free ordering +.. todo:: free ordering .. _text-index: @@ -12,13 +12,7 @@ Modules .. _text-globalidx: .. _text-localidx: .. _text-labelidx: -.. _text-typebind: -.. _text-funcbind: -.. _text-tablebind: -.. _text-membind: -.. _text-globalbind: -.. _text-localbind: -.. _text-labelbind: +.. _text-label: .. index:: index, type index, function index, table index, memory index, global index, local index, label index pair: text format; type index pair: text format; function index @@ -31,6 +25,9 @@ Modules Indices ~~~~~~~ +All :ref:`indices ` can be given either in raw numeric or in symbolic form. +In the latter case, they are looked up in the suitable space of the :ref:`identifier context `. + .. math:: \begin{array}{llclll} \production{type index} & \Ttypeidx_I &::=& @@ -56,38 +53,6 @@ Indices v{:}\Tid &\Rightarrow& x & (I.\LABELS[x] = v) \\ \end{array} -.. math:: - \begin{array}{llclll} - \production{type binder} & \Ttypebind_C &::=& - \epsilon &\Rightarrow& C \with \TYPES = C.\TYPES~(\epsilon) \\ &&|& - v{:}\Tvar &\Rightarrow& C \with \TYPES = C.\TYPES~v - & (v \notin C.\TYPES) \\ - \production{function binder} & \Tfuncbind_C &::=& - \epsilon &\Rightarrow& C \with \FUNCS = C.\FUNCS~(\epsilon) \\ &&|& - v{:}\Tvar &\Rightarrow& C \with \FUNCS = C.\FUNCS~v - & (v \notin C.\FUNCS) \\ - \production{table binder} & \Ttablebind_C &::=& - \epsilon &\Rightarrow& C \with \TABLES = C.\TABLES~(\epsilon) \\ &&|& - v{:}\Tvar &\Rightarrow& C \with \TABLES = C.\TABLES~v - & (v \notin C.\TABLES) \\ - \production{memory binder} & \Tmembind_C &::=& - \epsilon &\Rightarrow& C \with \MEMS = C.\MEMS~(\epsilon) \\ &&|& - v{:}\Tvar &\Rightarrow& C \with \MEMS = C.\MEMS~v - & (v \notin C.\MEMS) \\ - \production{global binder} & \Tglobalbind_C &::=& - \epsilon &\Rightarrow& C \with \GLOBALS = C.\GLOBALS~(\epsilon) \\ &&|& - v{:}\Tvar &\Rightarrow& C \with \GLOBALS = C.\GLOBALS~v - & (v \notin C.\GLOBALS) \\ - \production{local binder} & \Tlocalbind_C &::=& - \epsilon &\Rightarrow& C \with \LOCALS = C.\LOCALS~(\epsilon) \\ &&|& - v{:}\Tvar &\Rightarrow& C \with \LOCALS = C.\LOCALS~v - & (v \notin C.\LOCALS) \\ - \production{label binder} & \Tlabelbind_I &::=& - \epsilon &\Rightarrow& I \with \LABELS = I.\LABELS~(\epsilon) \\ &&|& - v{:}\Tid &\Rightarrow& I \with \LABELS = v~I.\LABELS - & (v \notin I.\LABELS) \\ - \end{array} - .. _text-type: .. _text-typeuse: @@ -114,6 +79,13 @@ Types \end{array} +Abbreviations +............. + +A |Ttypeuse| may be replaced by inline function parameters and result annotations. +@@@@ + + .. _text-import: .. index:: import, name, function type, table type, memory type, global type pair: text format; import @@ -147,19 +119,58 @@ Imports Functions ~~~~~~~~~ -.. todo:: inline type, inline import/export, multi-locals +.. todo:: inline type, inline import/export .. math:: \begin{array}{llclll} \production{function} & \Tfunc_I &::=& - \text{(}~\text{func}~~x{:}\Ttypeuse_I~~(t{:}\Tlocal)^\ast~~(\X{in}{:}\Tinstr_{I'})^\ast~\text{)} - &\Rightarrow& \{ \TYPE~x, \LOCALS~t^\ast, \BODY~\X{in}^\ast~\END \} - & (I' = I \with \LOCALS = (\id(\Tlocal))^\ast) \\ + \text{(}~\text{func}~~\Tid^?~~x{:}\Ttypeuse_I~~ + (t_1{:}\Tparam)^\ast~~(t_2{:}\Tresult)^\ast~~(t_3{:}\Tlocal)^\ast~~ + (\X{in}{:}\Tinstr_{I'})^\ast~\text{)} + &\Rightarrow& \{ \TYPE~x, \LOCALS~t^\ast, \BODY~\X{in}^\ast~\END \} \\ &&& \qquad + (\begin{array}[n]{@{}l@{}} + I' = I \with \LOCALS~\F{id}(\Tparam)^\ast)~\F{id}(\Tlocal)^\ast \\ + I.\TYPEDEFS[x] = t_4^n \to t_5^n \\ + t_1^\ast \to t_2^\ast = [] \to [] \vee ) + \end{array} \\ \production{local} & \Tlocal &::=& \text{(}~\text{local}~~\Tid^?~~t{:}\Tvaltype~\text{)} &\Rightarrow& t \\ \end{array} +The definition of the local :ref:`identifier context ` :math:`I'` uses the following auxiliary notation to filter out optional identifiers from parameters and locals: + +.. math:: + \begin{array}{lcl@{\qquad\qquad}l} + \F{id}(\text{(}~\text{param}~\Tid^?~\dots~\text{)}) &=& \Tid^? \\ + \F{id}(\text{(}~\text{local}~\Tid^?~\dots~\text{)}) &=& \Tid^? \\ + \end{array} + + +Abbreviations +............. + +A number of abbreviations are defined for functions. + +Multiple anonymous locals may be combined into a single declaration: + +.. math:: + \begin{array}{llclll} + \production{local} & + \text{(}~~\text{local}~~\Tvaltype^\ast~~\text{)} &\equiv& + (\text{(}~~\text{local}~~\Tvaltype~~\text{)})^\ast \\ + \end{array} + +The function type may be specified inline: + +.. math:: + \begin{array}{llclll} + \production{function} & + \text{(}~\text{func}~~\Tid^?~~\Ttypeuse~~\Tparam^\ast~~\Tresult_I~~\dots~\text{)} &\equiv& + \text{(}~\text{func}~~\Tid^?~~\Ttypeuse~~\Tparam^\ast~~\Tresult_I~~\dots~\text{)} \\ & + \text{(}~\text{func}~~\Tid^?~~\Ttypeuse~~\Tparam^\ast~~\Tresult_I~~\dots~\text{)} &\equiv& + \end{array} + .. _text-table: .. index:: table, table type @@ -306,7 +317,7 @@ Modules (\start{:}\Tstart_I)^? \\ &&& (\elem{:}\Telem_I)^\ast \\ &&& (\data{:}\Tdata_I)^\ast - \quad\Rightarrow\quad \{~ + \quad\Rightarrow\quad \\ &&&\qquad \{~ \begin{array}[t]{@{}l@{}} \TYPES~\functype^\ast, \\ \FUNCS~\func^\ast, \\ @@ -321,12 +332,28 @@ Modules \end{array} \\ &&& \qquad (I = \{~ \begin{array}[t]{@{}l@{}} - \TYPES~(\id(\Ttype))^\ast, \\ - \FUNCS~\id^\ast(\funcs(\Timport^\ast))~(\id(\Tfunc))^\ast, \\ - \TABLES~\id^\ast(\tables(\Timport^\ast))~(\id(\Ttable))^\ast, \\ - \MEMS~\id^\ast(\mems(\Timport^\ast))~(\id(\Tmem))^\ast, \\ - \GLOBALS~\id^\ast(\globals(\Timport^\ast))~(\id(\Tglobal))^\ast, \\ + \TYPES~(\F{id}(\Ttype))^\ast, \\ + \FUNCS~\F{funcids}(\Timport^\ast)~(\F{id}(\Tfunc))^\ast, \\ + \TABLES~\F{tableids}(\Timport^\ast)~(\F{id}(\Ttable))^\ast, \\ + \MEMS~\F{memids}(\Timport^\ast)~(\F{id}(\Tmem))^\ast, \\ + \GLOBALS~\F{globalids}(\Timport^\ast)~(\F{id}(\Tglobal))^\ast, \\ \LOCALS~\epsilon, \\ - \LABELS~\epsilon ~\}) \\ + \LABELS~\epsilon ~\}~\mbox{well-formed}) \\ \end{array} \end{array} + +The definition of the :ref:`identifier context ` :math:`I` uses the following auxiliary notation to filters out optional identifiers from definitions and imports in an order-preserving fashion: + +.. math:: + \begin{array}{lcl@{\qquad\qquad}l} + \F{id}(\text{(}~\text{type}~\Tid^?~\dots~\text{)}) &=& \Tid^? \\ + \F{id}(\text{(}~\text{func}~\Tid^?~\dots~\text{)}) &=& \Tid^? \\ + \F{id}(\text{(}~\text{table}~\Tid^?~\dots~\text{)}) &=& \Tid^? \\ + \F{id}(\text{(}~\text{memory}~\Tid^?~\dots~\text{)}) &=& \Tid^? \\ + \F{id}(\text{(}~\text{global}~\Tid^?~\dots~\text{)}) &=& \Tid^? \\[1ex] + \F{desc}(\text{(}~\text{import}~\dots~\Timportdesc~\text{)}) &=& \Timportdesc \\[1ex] + \F{funcids}(\Timport^\ast) &=& [\Tid^? ~|~ \text{(}~\text{func}~\Tid^?~\dots~\text{)} \in \F{desc}(\Timport)^\ast] \\ + \F{tableids}(\Timport^\ast) &=& [\Tid^? ~|~ \text{(}~\text{table}~\Tid^?~\dots~\text{)} \in \F{desc}(\Timport)^\ast] \\ + \F{memids}(\Timport^\ast) &=& [\Tid^? ~|~ \text{(}~\text{memory}~\Tid^?~\dots~\text{)} \in \F{desc}(\Timport)^\ast] \\ + \F{globalids}(\Timport^\ast) &=& [\Tid^? ~|~ \text{(}~\text{global}~\Tid^?~\dots~\text{)} \in \F{desc}(\Timport)^\ast] \\ + \end{array} diff --git a/document/text/types.rst b/document/text/types.rst index 0d3be7ace8..2219c20113 100644 --- a/document/text/types.rst +++ b/document/text/types.rst @@ -26,17 +26,17 @@ Value Types .. index:: result type, value type pair: text format; result type -Block Types -~~~~~~~~~~~ +Result Types +~~~~~~~~~~~~ .. math:: \begin{array}{llclll@{\qquad\qquad}l} - \production{result type} & \Tblocktype &::=& + \production{result type} & \Tresulttype &::=& (t{:}\Tresult)^? &\Rightarrow& [t^?] \\ \end{array} .. note:: - In future versions of WebAssembly, this scheme may be extended to support multiple results or more general block types. + In future versions of WebAssembly, this scheme may be extended to support multiple results or more general result types. .. _text-functype: @@ -52,13 +52,28 @@ Function Types \text{(}~\text{func}~~t_1^\ast{:\,}\Tvec(\Tparam)~~t_2^\ast{:\,}\Tvec(\Tresult)~\text{)} &\Rightarrow& [t_1^\ast] \to [t_2^\ast] \\ \production{parameter} & \Tparam &::=& - \text{(}~\text{param}~~t{:}\Tvaltype~\text{)} + \text{(}~\text{param}~~\Tid^?~~t{:}\Tvaltype~\text{)} &\Rightarrow& t \\ \production{result} & \Tresult &::=& \text{(}~\text{result}~~t{:}\Tvaltype~\text{)} &\Rightarrow& t \\ \end{array} +Abbreviations +............. + +Multiple anonymous parameters or results may be combined into a single declaration: + +.. math:: + \begin{array}{llclll} + \production{parameter} & + \text{(}~~\text{param}~~\Tvaltype^\ast~~\text{)} &\equiv& + (\text{(}~~\text{param}~~\Tvaltype~~\text{)})^\ast \\ + \production{result} & + \text{(}~~\text{result}~~\Tvaltype^\ast~~\text{)} &\equiv& + (\text{(}~~\text{result}~~\Tvaltype~~\text{)})^\ast \\ + \end{array} + .. _text-limits: .. index:: limits diff --git a/document/text/values.rst b/document/text/values.rst index df63cae0d4..5298c30b2b 100644 --- a/document/text/values.rst +++ b/document/text/values.rst @@ -46,7 +46,7 @@ All :ref:`integers ` can be written in either decimal or hexadecimal d{:}\Tdigit &\Rightarrow& d \\ &&|& n{:}\Tnum~~d{:}\Tdigit &\Rightarrow& 10\cdot n + d \\ \production{hexadecimal number} & \Thexnum &::=& - \text{0x}~~h{:}\Thexdigit &\Rightarrow& h \\ &&|& + h{:}\Thexdigit &\Rightarrow& h \\ &&|& n{:}\Thexnum~~h{:}\Thexdigit &\Rightarrow& 16\cdot n + h \\ \end{array} @@ -57,10 +57,10 @@ Their value must lie within the range of the respective type. \begin{array}{llclll@{\qquad}l} \production{unsigned integer} & \TuX{N} &::=& n{:}\Tnum &\Rightarrow& n & (n < 2^N) \\ &&|& - n{:}\Thexnum &\Rightarrow& n & (n < 2^N) \\ + \text{0x}~~n{:}\Thexnum &\Rightarrow& n & (n < 2^N) \\ \production{signed integer} & \TsX{N} &::=& s{:}\Tsign~~n{:}\Tnum &\Rightarrow& s\cdot n & (-2^{N-1} \leq s\cdot n < 2^{N-1}) \\ &&|& - s{:}\Tsign~~n{:}\Thexnum &\Rightarrow& s\cdot n & (-2^{N-1} \leq s\cdot n < 2^{N-1}) \\ + s{:}\Tsign~~\text{0x}~~n{:}\Thexnum &\Rightarrow& s\cdot n & (-2^{N-1} \leq s\cdot n < 2^{N-1}) \\ \end{array} :ref:`Uninterpreted integers ` can be written as either signed or unsigned, and are normalized to unsigned in the abstract syntax. @@ -110,18 +110,18 @@ Furthermore, arbitrary NaN values may be expressed by providing an explicit payl s{:}\Tsign~p{:}\Tnum~\text{.}~q{:}\Tfrac~(\text{E}~|~\text{e})~t{:}\Tsign~e{:}\Tnum &\Rightarrow& s\cdot(p+q)\cdot 10^{t\cdot e} \\ \production{hexadecimal floating-point number} & \Thexfloat &::=& - s{:}\Tsign~p{:}\Thexnum~\text{.}~q{:}\Thexfrac + s{:}\Tsign~\text{0x}~p{:}\Thexnum~\text{.}~q{:}\Thexfrac &\Rightarrow& s\cdot(p+q) \\ &&|& - s{:}\Tsign~p{:}\Thexnum~(\text{P}~|~\text{p})~t{:}\Tsign~e{:}\Tnum + s{:}\Tsign~\text{0x}~p{:}\Thexnum~(\text{P}~|~\text{p})~t{:}\Tsign~e{:}\Tnum &\Rightarrow& s\cdot p\cdot 2^{t\cdot e} \\ &&|& - s{:}\Tsign~p{:}\Thexnum~\text{.}~q{:}\Thexfrac~(\text{P}~|~\text{p})~t{:}\Tsign~e{:}\Tnum + s{:}\Tsign~\text{0x}~p{:}\Thexnum~\text{.}~q{:}\Thexfrac~(\text{P}~|~\text{p})~t{:}\Tsign~e{:}\Tnum &\Rightarrow& s\cdot(p+q)\cdot 2^{t\cdot e} \\ \production{floating-point value} & \TfX{N} &::=& z{:}\Tfloat &\Rightarrow& b^\ast & (\ieee_N(z) = b^\ast) \\ &&|& z{:}\Thexfloat &\Rightarrow& b^\ast & (\ieee_N(z) = b^\ast) \\ &&|& s{:}\Tsign~\text{inf} &\Rightarrow& b^\ast & (\ieeeinf_N(s) = b^\ast) \\ &&|& s{:}\Tsign~\text{nan} &\Rightarrow& b^\ast & (\ieeenan_N(s, 0) = b^\ast) \\ &&|& - s{:}\Tsign~\text{nan\!:}~n{:}\Thexnum &\Rightarrow& b^\ast & (\ieeenan_N(s, n) = b^\ast) \\ + s{:}\Tsign~\text{nan\!:}~\text{0x}~n{:}\Thexnum &\Rightarrow& b^\ast & (\ieeenan_N(s, n) = b^\ast) \\ \end{array} .. todo:: IEEE encoding @@ -134,7 +134,7 @@ Furthermore, arbitrary NaN values may be expressed by providing an explicit payl Vectors ~~~~~~~ -:ref:`Vectors ` are written as ordinary sequences, but with restricted length. +:ref:`Vectors ` are written as plain sequences, but with restricted length. .. math:: \begin{array}{llclll@{\qquad\qquad}l} @@ -212,7 +212,7 @@ Identifiers ~~~~~~~~~~~ :ref:`Indices ` can be given in both numeric and symbolic form. -Symbolic *identifiers* standing for indices start with :math:`\text{$}`, followed by any sequence of printable `ASCII `_ characters that does not contain a space, quotation mark, comma, semicolon, or bracket (parentheses, square brackets, or braces). +Symbolic *identifiers* standing for indices start with :math:`\text{$}`, followed by any sequence of printable `ASCII `_ characters that does not contain a space, quotation mark, comma, semicolon, or bracket. .. math:: \begin{array}{llclll@{\qquad}l} diff --git a/interpreter/README.md b/interpreter/README.md index c0b42b7754..55ce83c9e5 100644 --- a/interpreter/README.md +++ b/interpreter/README.md @@ -167,7 +167,7 @@ The implementation consumes a WebAssembly AST given in S-expression syntax. Here value: | var: | name: $( | | _ | . | + | - | * | / | \ | ^ | ~ | = | < | > | ! | ? | @ | # | $ | % | & | | | : | ' | `)+ -string: "( | \n | \t | \\ | \' | \" | \)*" +string: "( | \n | \t | \\ | \' | \" | \ | \u{+})*" type: i32 | i64 | f32 | f64 elem_type: anyfunc @@ -283,6 +283,8 @@ A module of the form `(module +)` is given in binary form and will be de The segment strings in the memory field are used to initialize the consecutive memory at the given offset. The `` in the expansion of the two short-hand forms for `table` and `memory` is the minimal size that can hold the segment: the number of ``s for tables, and the accumulative length of the strings rounded up to page size for memories. +In addition to the grammar rules above, the fields of a module may appear in any order, except that all imports must occur before the first proper definition of a function, table, memory, or global. + Comments can be written in one of two ways: ``` diff --git a/interpreter/host/import.ml b/interpreter/host/import.ml index 0e658dc002..5c7051be27 100644 --- a/interpreter/host/import.ml +++ b/interpreter/host/import.ml @@ -14,7 +14,7 @@ let lookup (m : module_) (im : import) : Instance.extern = let t = import_type m im in try Registry.find module_name !registry item_name t with Not_found -> Unknown.error im.at - ("unknown import \"" ^ String.escaped (Utf8.encode module_name) ^ - "\".\"" ^ String.escaped (Utf8.encode item_name) ^ "\"") + ("unknown import \"" ^ string_of_name module_name ^ + "\".\"" ^ string_of_name item_name ^ "\"") let link m = List.map (lookup m) m.it.imports diff --git a/interpreter/host/js.ml b/interpreter/host/js.ml index 1d66dc18d9..6a8231db35 100644 --- a/interpreter/host/js.ml +++ b/interpreter/host/js.ml @@ -170,7 +170,7 @@ let lookup (mods : modules) x_opt name at = else "unknown module " ^ of_var_opt mods x_opt ^ " within script")) in try ExportMap.find name exports with Not_found -> raise (Eval.Crash (at, "unknown export \"" ^ - String.escaped (Utf8.encode name) ^ "\" within module")) + string_of_name name ^ "\" within module")) (* Wrappers *) diff --git a/interpreter/host/run.ml b/interpreter/host/run.ml index 1f7a9c22c7..f84311fd53 100644 --- a/interpreter/host/run.ml +++ b/interpreter/host/run.ml @@ -188,8 +188,6 @@ let input_stdin run = (* Printing *) -let string_of_name n = String.escaped (Utf8.encode n) - let print_import m im = let open Types in let category, annotation = @@ -199,9 +197,9 @@ let print_import m im = | ExternalMemoryType t -> "memory", string_of_memory_type t | ExternalGlobalType t -> "global", string_of_global_type t in - Printf.printf " import %s %S %S : %s\n" - category (string_of_name im.it.Ast.module_name) - (string_of_name im.it.Ast.item_name) annotation + Printf.printf " import %s \"%s\" \"%s\" : %s\n" + category (Ast.string_of_name im.it.Ast.module_name) + (Ast.string_of_name im.it.Ast.item_name) annotation let print_export m ex = let open Types in @@ -212,8 +210,8 @@ let print_export m ex = | ExternalMemoryType t -> "memory", string_of_memory_type t | ExternalGlobalType t -> "global", string_of_global_type t in - Printf.printf " export %s %S : %s\n" - category (string_of_name ex.it.Ast.name) annotation + Printf.printf " export %s \"%s\" : %s\n" + category (Ast.string_of_name ex.it.Ast.name) annotation let print_module x_opt m = Printf.printf "module%s :\n" @@ -275,7 +273,7 @@ let run_definition def = let run_action act = match act.it with | Invoke (x_opt, name, vs) -> - trace ("Invoking function \"" ^ string_of_name name ^ "\"..."); + trace ("Invoking function \"" ^ Ast.string_of_name name ^ "\"..."); let inst = lookup_instance x_opt act.at in (match Instance.export inst name with | Some (Instance.ExternalFunc f) -> @@ -285,7 +283,7 @@ let run_action act = ) | Get (x_opt, name) -> - trace ("Getting global \"" ^ string_of_name name ^ "\"..."); + trace ("Getting global \"" ^ Ast.string_of_name name ^ "\"..."); let inst = lookup_instance x_opt act.at in (match Instance.export inst name with | Some (Instance.ExternalGlobal v) -> [v] @@ -425,7 +423,7 @@ let rec run_command cmd = | Register (name, x_opt) -> quote := cmd :: !quote; if not !Flags.dry then begin - trace ("Registering module \"" ^ string_of_name name ^ "\"..."); + trace ("Registering module \"" ^ Ast.string_of_name name ^ "\"..."); let inst = lookup_instance x_opt cmd.at in registry := Map.add (Utf8.encode name) inst !registry; Import.register name (lookup_registry (Utf8.encode name)) diff --git a/interpreter/spec/ast.ml b/interpreter/spec/ast.ml index 3604bbc1e7..0415be7140 100644 --- a/interpreter/spec/ast.ml +++ b/interpreter/spec/ast.ml @@ -236,3 +236,15 @@ let export_type (m : module_) (ex : export) : external_type = | GlobalExport x -> let gts = globals its @ List.map (fun g -> g.it.gtype) m.it.globals in ExternalGlobalType (nth gts x.it) + +let string_of_name n = + let s = Utf8.encode n in + let b = Buffer.create (3 * String.length s) in + let escape c = + if '\x20' <= c && c < '\x7f' then + Buffer.add_char b c + else + Buffer.add_string b (Printf.sprintf "\\%02x" (Char.code c)) + in + String.iter escape s; + Buffer.contents b diff --git a/interpreter/text/lexer.mll b/interpreter/text/lexer.mll index c6af499743..a3663084db 100644 --- a/interpreter/text/lexer.mll +++ b/interpreter/text/lexer.mll @@ -34,7 +34,7 @@ let text s = let j = !i + 2 in i := String.index_from s j '}'; let n = int_of_string ("0x" ^ String.sub s j (!i - j)) in - let bs = Utf8.encode n in + let bs = Utf8.encode [n] in Buffer.add_substring b bs 0 (String.length bs - 1); bs.[String.length bs - 1] | h -> diff --git a/interpreter/text/parser.mly b/interpreter/text/parser.mly index 31db274ebd..5ac160346f 100644 --- a/interpreter/text/parser.mly +++ b/interpreter/text/parser.mly @@ -137,22 +137,22 @@ let anon_label (c : context) = let empty_type = FuncType ([], []) -let explicit_sig (c : context) var_sem ty at = - let x = var_sem c type_ in - if - x.it < Lib.List32.length c.types.tlist && - ty <> empty_type && - ty <> Lib.List32.nth c.types.tlist x.it - then - error at "signature mismatch"; - x - let inline_type (c : context) ty at = match Lib.List.index_of ty c.types.tlist with | Some i -> Int32.of_int i @@ at | None -> let i = Lib.List32.length c.types.tlist in ignore (anon_type c ty); i @@ at +let inline_type_explicit (c : context) x ty at = + if + ty <> empty_type && + (x.it >= Lib.List32.length c.types.tlist || + ty <> Lib.List32.nth c.types.tlist x.it) + then + error at "inline function type does not match explicit type" + else + x + %} %token NAT INT FLOAT TEXT VAR VALUE_TYPE ANYFUNC MUT LPAR RPAR @@ -425,14 +425,14 @@ func : { let at = at () in fun c -> let x = $3 c anon_func bind_func @@ at in - let t = explicit_sig c $5 (fst $6) at in + let t = inline_type_explicit c ($5 c type_) (fst $6) at in (fun () -> {(snd $6 (enter_func c)) with ftype = t} @@ at), $4 (FuncExport x) c } /* Duplicate above for empty inline_export_opt to avoid LR(1) conflict. */ | LPAR FUNC bind_var_opt type_use func_fields RPAR { let at = at () in fun c -> ignore ($3 c anon_func bind_func); - let t = explicit_sig c $4 (fst $5) at in + let t = inline_type_explicit c ($4 c type_) (fst $5) at in (fun () -> {(snd $5 (enter_func c)) with ftype = t} @@ at), [] } | LPAR FUNC bind_var_opt inline_export func_fields RPAR /* Sugar */ From de44c0c6f9b02f966d1819acc3c69a57fc5c7f50 Mon Sep 17 00:00:00 2001 From: Andreas Rossberg Date: Tue, 9 May 2017 11:42:28 +0200 Subject: [PATCH 09/30] Reject malformed UTF-8 sources --- document/text/lexical.rst | 7 +++++-- interpreter/spec/ast.ml | 9 ++++----- interpreter/text/lexer.mll | 31 ++++++++++++++++++++++++------- test/core/comments.wast | Bin 652 -> 701 bytes 4 files changed, 33 insertions(+), 14 deletions(-) diff --git a/document/text/lexical.rst b/document/text/lexical.rst index ff7c8a002a..0834a4cdb8 100644 --- a/document/text/lexical.rst +++ b/document/text/lexical.rst @@ -54,16 +54,19 @@ White Space *White space* is any sequence of literal space characters, formatting characters, or :ref:`comments `. -A format character corresponds to an `ASCII `_ *format effector*, that is, *backspace* (:math:`\unicode{08}`), *horizontal tabulation* (:math:`\unicode{09}`), *line feed* (:math:`\unicode{0A}`), *vertical tabulation* (:math:`\unicode{0B}`), *form feed* (:math:`\unicode{0C}`), or *carriage return* (:math:`\unicode{0D}`). +The allowed formatting characters correspond to a subset of the `ASCII `_ *format effectors*, namely, *horizontal tabulation* (:math:`\unicode{09}`), *line feed* (:math:`\unicode{0A}`), or *carriage return* (:math:`\unicode{0D}`). .. math:: \begin{array}{llclll@{\qquad\qquad}l} \production{white space} & \Tspace &::=& (\text{~~} ~|~ \Tformat ~|~ \Tcomment)^\ast \\ \production{format} & \Tformat &::=& - \unicode{08} ~|~ \unicode{09} ~|~ \unicode{0A} ~|~ \unicode{0B} ~|~ \unicode{0C} ~|~ \unicode{0D} \\ + \unicode{09} ~|~ \unicode{0A} ~|~ \unicode{0D} \\ \end{array} +.. note:: + Other formatting and control characters are allowed inside :ref:`comments `. + .. text-comment: .. index:: ! comment, character diff --git a/interpreter/spec/ast.ml b/interpreter/spec/ast.ml index 0415be7140..dc99c3e84b 100644 --- a/interpreter/spec/ast.ml +++ b/interpreter/spec/ast.ml @@ -240,11 +240,10 @@ let export_type (m : module_) (ex : export) : external_type = let string_of_name n = let s = Utf8.encode n in let b = Buffer.create (3 * String.length s) in - let escape c = - if '\x20' <= c && c < '\x7f' then - Buffer.add_char b c - else - Buffer.add_string b (Printf.sprintf "\\%02x" (Char.code c)) + let escape = function + | '\"' -> Buffer.add_string b "\\\"" + | c when '\x20' <= c && c < '\x7f' -> Buffer.add_char b c + | c -> Buffer.add_string b (Printf.sprintf "\\%02x" (Char.code c)) in String.iter escape s; Buffer.contents b diff --git a/interpreter/text/lexer.mll b/interpreter/text/lexer.mll index a3663084db..7e59283798 100644 --- a/interpreter/text/lexer.mll +++ b/interpreter/text/lexer.mll @@ -88,8 +88,6 @@ let ext e s u = let opt = Lib.Option.get } -let space = [' ''\x08'-'\x09''\x0b'-'\x0d'] - let sign = '+' | '-' let digit = ['0'-'9'] let hexdigit = ['0'-'9''a'-'f''A'-'F'] @@ -100,9 +98,25 @@ let letter = ['a'-'z''A'-'Z'] let symbol = ['+''-''*''/''\\''^''~''=''<''>''!''?''@''#''$''%''&''|'':''`''.''\''] +let space = [' ''\t''\n''\r'] +let ascii = ['\x00'-'\x7f'] +let ascii_no_nl = ['\x00'-'\x09''\x0b'-'\x7f'] +let utf8cont = ['\x80'-'\xbf'] +let utf8enc = + ['\xc2'-'\xdf'] utf8cont + | ['\xe0'] ['\xa0'-'\xbf'] utf8cont + | ['\xed'] ['\x80'-'\x9f'] utf8cont + | ['\xe1'-'\xec''\xee'-'\xef'] utf8cont utf8cont + | ['\xf0'] ['\x90'-'\xbf'] utf8cont utf8cont + | ['\xf4'] ['\x80'-'\x8f'] utf8cont utf8cont + | ['\xf1'-'\xf3'] utf8cont utf8cont utf8cont +let utf8 = ascii | utf8enc +let utf8_no_nl = ascii_no_nl | utf8enc + let escape = ['n''r''t''\\''\'''\"'] let character = - [^'"''\\''\x00'-'\x1f''\x7f'] + [^'"''\\''\x00'-'\x1f''\x7f'-'\xff'] + | utf8enc | '\\'escape | '\\'hexdigit hexdigit | "\\u{" hexnum '}' @@ -332,17 +346,20 @@ rule token = parse | name as s { VAR s } - | ";;"[^'\n']*eof { EOF } - | ";;"[^'\n']*'\n' { Lexing.new_line lexbuf; token lexbuf } + | ";;"utf8_no_nl*eof { EOF } + | ";;"utf8_no_nl*'\n' { Lexing.new_line lexbuf; token lexbuf } + | ";;"utf8_no_nl* { token lexbuf (* causes error on following position *) } | "(;" { comment (Lexing.lexeme_start_p lexbuf) lexbuf; token lexbuf } | space { token lexbuf } | '\n' { Lexing.new_line lexbuf; token lexbuf } | eof { EOF } - | _ { error lexbuf "unknown operator" } + | utf8 { error lexbuf "unknown operator" } + | _ { error lexbuf "malformed UTF-8 encoding" } and comment start = parse | ";)" { () } | "(;" { comment (Lexing.lexeme_start_p lexbuf) lexbuf; comment start lexbuf } | '\n' { Lexing.new_line lexbuf; comment start lexbuf } | eof { error_nest start lexbuf "unclosed comment" } - | _ { comment start lexbuf } + | utf8 { comment start lexbuf } + | _ { error lexbuf "malformed UTF-8 encoding" } diff --git a/test/core/comments.wast b/test/core/comments.wast index 07a6298c4fea799851e0b42c8f269a25aa678366..90a64b42d9ec854f6522e940c0466eb6c1ca6de9 100644 GIT binary patch delta 77 zcmeBS-OIXxkI~H9TEQ{c+0#?Oz(Ci~O-I4pjZ4Ftfsu)sg_Vt+gOiJ!hnJ6EKu}0n hL{v;%LQ+avMpjO~eli!MEbIFjv))hIY|0qU2mluF4zvIO delta 52 zcmdnX+QYhmk5OI2+9Ngd@cdMT@WXqGic69+QuC}exwtf}-!9nucE_x@JNiJ3O`Fpg G!x;f54;NVg From ac11a6c8e7f209b65ac82c5ab7ad9c2353ad5c52 Mon Sep 17 00:00:00 2001 From: Andreas Rossberg Date: Tue, 9 May 2017 15:37:42 +0200 Subject: [PATCH 10/30] Inline types --- document/text/modules.rst | 79 ++++++++++++++++++++++++++------------- 1 file changed, 54 insertions(+), 25 deletions(-) diff --git a/document/text/modules.rst b/document/text/modules.rst index 63898c18a2..b77b8db495 100644 --- a/document/text/modules.rst +++ b/document/text/modules.rst @@ -55,7 +55,6 @@ In the latter case, they are looked up in the suitable space of the :ref:`identi .. _text-type: -.. _text-typeuse: .. index:: type definition pair: text format; type definition @@ -69,21 +68,64 @@ Types &\Rightarrow& \X{ft} \\ \end{array} -.. todo:: inline functypes + +.. _text-typeuse: +.. index:: type use + pair: text format; type use + +Type Uses +~~~~~~~~~ + +A *type use* is a reference to a :ref:`type definition `. +It may optionally be augmented by inline function :ref:`parameters ` and :ref:`result ` annotations. +That allows declaring symbolic :ref:`identifiers ` for the :ref:`local indices ` of parameters. +If any inline annotation is given, then it must be complete and match the referenced type. .. math:: \begin{array}{llclll} \production{type use} & \Ttypeuse_I &::=& \text{(}~\text{type}~~x{:}\Ttypeidx_I~\text{)} - &\Rightarrow& x \\ + \quad\Rightarrow\quad x, I' \\ &&& \qquad + (\begin{array}[t]{@{}l@{}} + I.\TYPEDEFS[x] = [t_1^n] \to [t_2^\ast] \wedge + I' = I \with \LOCALS~(\epsilon)^n) \\ + \end{array} \\ &&|& + \text{(}~\text{type}~~x{:}\Ttypeidx_I~\text{)} + ~~(t_1{:}\Tparam)^\ast~~(t_2{:}\Tresult)^\ast + \quad\Rightarrow\quad x, I' \\ &&&\qquad + (\begin{array}[t]{@{}l@{}} + I.\TYPEDEFS[x] = [t_1^\ast] \to [t_2^\ast] \wedge + I' = I \with \LOCALS~\F{id}(\Tparam)^\ast) \\ + \end{array} \\ \end{array} +The resulting attribute of a |Ttypeuse| is a pair consisting of both the referenced :ref:`type index ` and the updated :ref:`identifier context ` including the parameter identifiers. +The following auxiliary notation filters out optional identifiers from parameters: + +.. math:: + \begin{array}{lcl@{\qquad\qquad}l} + \F{id}(\text{(}~\text{param}~\Tid^?~\dots~\text{)}) &=& \Tid^? \\ + \end{array} + +.. note:: + Both productions overlap for the case that the function type is :math:`[] \to []`. + However, in that case, they also produce the same results, so that the choice is immaterial. + Abbreviations ............. -A |Ttypeuse| may be replaced by inline function parameters and result annotations. -@@@@ +A |Ttypeuse| may also be replaced entirely by inline function :ref:`parameters ` and :ref:`result ` annotations. +In that case, the :ref:`type index ` of the first matching :ref:`type definition ` is automatically inserted. +If no matching definition exists + +.. math:: + \begin{array}{llclll} + \production{type use} & + \text{(}~\text{func}~~\Tid^?~~\Ttypeuse~~\Tparam^\ast~~\Tresult_I~~\dots~\text{)} &\equiv& + \text{(}~\text{func}~~\Tid^?~~\Ttypeuse~~\Tparam^\ast~~\Tresult_I~~\dots~\text{)} \\ & + \text{(}~\text{func}~~\Tid^?~~\Ttypeuse~~\Tparam^\ast~~\Tresult_I~~\dots~\text{)} &\equiv& + \end{array} .. _text-import: @@ -101,7 +143,7 @@ Imports \text{(}~\text{import}~~\X{mod}{:}\Tname~~\X{nm}{:}\Tname~~d{:}\Timportdesc_I~\text{)} &\Rightarrow& \{ \MODULE~\X{mod}, \NAME~\X{nm}, \DESC~d \} \\ \production{import description} & \Timportdesc_I &::=& - \text{(}~\text{func}~~\Tid^?~~x{:}\Ttypeuse_I~\text{)} + \text{(}~\text{func}~~\Tid^?~~x,I'{:}\Ttypeuse_I~\text{)} &\Rightarrow& \FUNC~x \\ &&|& \text{(}~\text{table}~~\Tid^?~~\X{tt}{:}\Ttabletype~\text{)} &\Rightarrow& \TABLE~\X{tt} \\ &&|& @@ -124,25 +166,21 @@ Functions .. math:: \begin{array}{llclll} \production{function} & \Tfunc_I &::=& - \text{(}~\text{func}~~\Tid^?~~x{:}\Ttypeuse_I~~ - (t_1{:}\Tparam)^\ast~~(t_2{:}\Tresult)^\ast~~(t_3{:}\Tlocal)^\ast~~ - (\X{in}{:}\Tinstr_{I'})^\ast~\text{)} + \text{(}~\text{func}~~\Tid^?~~x,I'{:}\Ttypeuse_I~~ + (t{:}\Tlocal)^\ast~~(\X{in}{:}\Tinstr_{I'})^\ast~\text{)} &\Rightarrow& \{ \TYPE~x, \LOCALS~t^\ast, \BODY~\X{in}^\ast~\END \} \\ &&& \qquad (\begin{array}[n]{@{}l@{}} - I' = I \with \LOCALS~\F{id}(\Tparam)^\ast)~\F{id}(\Tlocal)^\ast \\ - I.\TYPEDEFS[x] = t_4^n \to t_5^n \\ - t_1^\ast \to t_2^\ast = [] \to [] \vee ) + I'' = I' \with \LOCALS~(I'.\LOCALS)~\F{id}(\Tlocal)^\ast) \\ \end{array} \\ \production{local} & \Tlocal &::=& \text{(}~\text{local}~~\Tid^?~~t{:}\Tvaltype~\text{)} &\Rightarrow& t \\ \end{array} -The definition of the local :ref:`identifier context ` :math:`I'` uses the following auxiliary notation to filter out optional identifiers from parameters and locals: +The definition of the local :ref:`identifier context ` :math:`I''` uses the following auxiliary notation to filter out optional identifiers from locals: .. math:: \begin{array}{lcl@{\qquad\qquad}l} - \F{id}(\text{(}~\text{param}~\Tid^?~\dots~\text{)}) &=& \Tid^? \\ \F{id}(\text{(}~\text{local}~\Tid^?~\dots~\text{)}) &=& \Tid^? \\ \end{array} @@ -161,16 +199,6 @@ Multiple anonymous locals may be combined into a single declaration: (\text{(}~~\text{local}~~\Tvaltype~~\text{)})^\ast \\ \end{array} -The function type may be specified inline: - -.. math:: - \begin{array}{llclll} - \production{function} & - \text{(}~\text{func}~~\Tid^?~~\Ttypeuse~~\Tparam^\ast~~\Tresult_I~~\dots~\text{)} &\equiv& - \text{(}~\text{func}~~\Tid^?~~\Ttypeuse~~\Tparam^\ast~~\Tresult_I~~\dots~\text{)} \\ & - \text{(}~\text{func}~~\Tid^?~~\Ttypeuse~~\Tparam^\ast~~\Tresult_I~~\dots~\text{)} &\equiv& - \end{array} - .. _text-table: .. index:: table, table type @@ -338,7 +366,8 @@ Modules \MEMS~\F{memids}(\Timport^\ast)~(\F{id}(\Tmem))^\ast, \\ \GLOBALS~\F{globalids}(\Timport^\ast)~(\F{id}(\Tglobal))^\ast, \\ \LOCALS~\epsilon, \\ - \LABELS~\epsilon ~\}~\mbox{well-formed}) \\ + \LABELS~\epsilon, + \TYPEDEFS~\functype^\ast ~\}~\mbox{well-formed}) \\ \end{array} \end{array} From 818b4cccf194e366cf56c9533341b019d91a7999 Mon Sep 17 00:00:00 2001 From: rossberg-chromium Date: Wed, 10 May 2017 15:16:54 +0200 Subject: [PATCH 11/30] Free module ordering --- document/math.def | 12 +++- document/syntax/conventions.rst | 5 ++ document/text/conventions.rst | 11 +++- document/text/instructions.rst | 5 ++ document/text/modules.rst | 111 ++++++++++++++++++++++++++++---- 5 files changed, 129 insertions(+), 15 deletions(-) diff --git a/document/math.def b/document/math.def index 6003e7990d..cf7a2e769a 100644 --- a/document/math.def +++ b/document/math.def @@ -23,7 +23,9 @@ .. |production| mathdef:: \void .. |concat| mathdef:: \xref{syntax/conventions}{syntax-concat}{\F{concat}} -.. |with| mathdef:: ~\xref{syntax/conventions}{syntax-record}{\mbox{with}}~ +.. |with| mathdef:: \xref{syntax/conventions}{syntax-record}{\mathrel{\mbox{with}}} +.. |compose| mathdef:: \xref{syntax/conventions}{syntax-record}{\oplus} +.. |bigcompose| mathdef:: \xref{syntax/conventions}{syntax-record}{\bigoplus} .. Lexical grammar, non-terminals @@ -359,7 +361,8 @@ .. Modules, textual non-terminals .. |Tmodule| mathdef:: \xref{text/modules}{text-module}{\T{module}} -.. |Tmodulebody| mathdef:: \xref{text/modules}{text-module}{\T{modulebody}} +.. |Tmodulebody| mathdef:: \xref{text/modules}{text-modulebody}{\T{modulebody}} +.. |Tmodulefield| mathdef:: \xref{text/modules}{text-modulefield}{\T{modulefield}} .. |Ttype| mathdef:: \xref{text/modules}{text-type}{\T{type}} .. |Ttypeuse| mathdef:: \xref{text/modules}{text-typeuse}{\T{typeuse}} .. |Tfunc| mathdef:: \xref{text/modules}{text-func}{\T{func}} @@ -501,3 +504,8 @@ .. Context, textual .. |TYPEDEFS| mathdef:: \K{typedefs} + + +.. Contexts, meta functions + +.. |idcwellformed| mathdef:: ~\xref{text/conventions}{text-context-wf}{\mbox{well-formed}} diff --git a/document/syntax/conventions.rst b/document/syntax/conventions.rst index 2a0884c2ba..1e04a2cd04 100644 --- a/document/syntax/conventions.rst +++ b/document/syntax/conventions.rst @@ -57,3 +57,8 @@ Productions of the following form are interpreted as *records* that map a fixed The following notation is adopted for manipulating such records: * :math:`r.\K{field}` denotes the :math:`\K{field}` component of :math:`r`. + +* :math:`r_1 \compose r_2` denotes the composition of two records whose fields are sequences by appending each sequence pointwise: + + .. math:: + \{ \K{field}_1\,A_1^\ast, \K{field}_2\,A_2^\ast, \dots \} \compose \{ \K{field}_1\,B_1^\ast, \K{field}_2\,B_2^\ast, \dots \} = \{ \K{field}_1\,A_1^\ast~B_1^\ast, \K{field}_2\,A_2^\ast~B_2^\ast, \dots \} diff --git a/document/text/conventions.rst b/document/text/conventions.rst index 380e8be9cd..6d5db7cd0f 100644 --- a/document/text/conventions.rst +++ b/document/text/conventions.rst @@ -89,8 +89,8 @@ When dealing with binary encodings the following notation is also used: * :math:`\epsilon` denotes the empty byte sequence. -.. text-context: -.. text-context-wf: +.. _text-context: +.. _text-context-wf: .. index:: ! identifier context, identifier, index, index space Contexts @@ -122,3 +122,10 @@ For each index space, an identifier context contains the list of :ref:`identifie Unnamed indices are associated with empty (:math:`\epsilon`) entries in these lists. An identifier context is *well-formed* if no index space contains duplicate identifiers. + + +Conventions +........... + +To avoid unnecessary clutter, empty components are omitted when writing out identifier contexts. +For example, the record :math:`\{\}` is shorthand for an :ref:`identifier context ` whose components are all empty. diff --git a/document/text/instructions.rst b/document/text/instructions.rst index ea1d55b285..34c91d9068 100644 --- a/document/text/instructions.rst +++ b/document/text/instructions.rst @@ -429,6 +429,11 @@ As a further abbreviation, instructions can also be written in *folded* S-expres &\Rightarrow& \X{in}_0^\ast~~\IF~\X{rt}~\X{in}_1^\ast~\ELSE~\X{in}_2^\ast~\END \\ \end{array} +.. note:: + Folded instructions are solely syntactic sugar, + no additional syntactic or type checking is implied. + In particular, the number of syntactic operands to an instruction can differ from the number of values that the instruction consumes from the :ref:`stack `, because an individual operand instruction may produce less or more than one value. + .. _text-expr: .. index:: expression diff --git a/document/text/modules.rst b/document/text/modules.rst index b77b8db495..1cc943a41b 100644 --- a/document/text/modules.rst +++ b/document/text/modules.rst @@ -1,8 +1,6 @@ Modules ------- -.. todo:: free ordering - .. _text-index: .. _text-typeidx: @@ -88,14 +86,14 @@ If any inline annotation is given, then it must be complete and match the refere \quad\Rightarrow\quad x, I' \\ &&& \qquad (\begin{array}[t]{@{}l@{}} I.\TYPEDEFS[x] = [t_1^n] \to [t_2^\ast] \wedge - I' = I \with \LOCALS~(\epsilon)^n) \\ + I' = \{\LOCALS~(\epsilon)^n\}) \\ \end{array} \\ &&|& \text{(}~\text{type}~~x{:}\Ttypeidx_I~\text{)} ~~(t_1{:}\Tparam)^\ast~~(t_2{:}\Tresult)^\ast \quad\Rightarrow\quad x, I' \\ &&&\qquad (\begin{array}[t]{@{}l@{}} I.\TYPEDEFS[x] = [t_1^\ast] \to [t_2^\ast] \wedge - I' = I \with \LOCALS~\F{id}(\Tparam)^\ast) \\ + I' = \{\LOCALS~\F{id}(\Tparam)\}^\ast \idcwellformed) \\ \end{array} \\ \end{array} @@ -111,6 +109,8 @@ The following auxiliary notation filters out optional identifiers from parameter Both productions overlap for the case that the function type is :math:`[] \to []`. However, in that case, they also produce the same results, so that the choice is immaterial. + The :ref:`well-formedness ` condition on :math:`I'` ensures that the parameters do not contain duplicate identifier. + Abbreviations ............. @@ -167,10 +167,10 @@ Functions \begin{array}{llclll} \production{function} & \Tfunc_I &::=& \text{(}~\text{func}~~\Tid^?~~x,I'{:}\Ttypeuse_I~~ - (t{:}\Tlocal)^\ast~~(\X{in}{:}\Tinstr_{I'})^\ast~\text{)} + (t{:}\Tlocal)^\ast~~(\X{in}{:}\Tinstr_{I''})^\ast~\text{)} &\Rightarrow& \{ \TYPE~x, \LOCALS~t^\ast, \BODY~\X{in}^\ast~\END \} \\ &&& \qquad (\begin{array}[n]{@{}l@{}} - I'' = I' \with \LOCALS~(I'.\LOCALS)~\F{id}(\Tlocal)^\ast) \\ + I'' = I' \compose \{\LOCALS~\F{id}(\Tlocal)^\ast\} \idcwellformed) \\ \end{array} \\ \production{local} & \Tlocal &::=& \text{(}~\text{local}~~\Tid^?~~t{:}\Tvaltype~\text{)} @@ -185,6 +185,10 @@ The definition of the local :ref:`identifier context ` :math:`I''` \end{array} +.. note:: + The :ref:`well-formedness ` condition on :math:`I'` ensures that parameters and locals do not contain duplicate identifier. + + Abbreviations ............. @@ -319,15 +323,50 @@ Data Segments .. _text-module: +.. _text-modulebody: +.. _text-modulefield: .. index:: module, type definition, function type, function, table, memory, global, element, data, start function, import, export, context, version pair: text format; module Modules ~~~~~~~ -.. todo:: free ordering - .. math:: + \begin{array}{lll} + \production{module} & \Tmodule & + \begin{array}[t]{@{}clll} + ::=& + \text{(}~\text{module}~~(m{:}\Tmodulefield_I)^\ast~\text{)} + &\Rightarrow& \bigcompose m^\ast + \\& (I = \bigcompose \F{idc}(\Tmodulefield)^\ast \idcwellformed) \\ + \end{array} \\ + \production{module field} & \Tmodulefield_I & + \begin{array}[t]{@{}clll} + ::=& + \functype{:}\Ttype &\Rightarrow& \{\TYPES~\functype\} \\ |& + \import{:}\Timport_I &\Rightarrow& \{\IMPORTS~\import\} \\ |& + \func{:}\Tfunc_I &\Rightarrow& \{\FUNCS~\func\} \\ |& + \table{:}\Ttable_I &\Rightarrow& \{\TABLES~\table\} \\ |& + \mem{:}\Tmem_I &\Rightarrow& \{\MEMS~\mem\} \\ |& + \global{:}\Tglobal_I &\Rightarrow& \{\GLOBALS~\global\} \\ |& + \export{:}\Texport_I &\Rightarrow& \{\EXPORTS~\export\} \\ |& + \start{:}\Tstart_I &\Rightarrow& \{\START~\start\} \\ |& + \elem{:}\Telem_I &\Rightarrow& \{\ELEM~\elem\} \\ |& + \data{:}\Tdata_I &\Rightarrow& \{\DATA~\data\} \\ + \end{array} + \end{array} + +.. math (commented out) + \production{module} & \Tmodule &::=& + \text{(}~\text{module}~~m{:}\Tmodulebody_I~\text{)} + &\Rightarrow& m + \qquad (I = \F{idc}(\Tmodulebody)~\mbox{well-formed}) \\ &&|& + m{:}\Tmodulebody_I \phantom{\text{(}~\text{module}~~~\text{)}} + &\Rightarrow& m + \qquad (I = \F{idc}(\Tmodulebody)~\mbox{well-formed}) \\ + \production{module body} & \Tmodulebody_I &::=& + (m{:}\Tmodulefield_I)^\ast &\Rightarrow& \{\}~(\compose~m)^\ast \\ + \begin{array}{llcllll} \production{module} & \Tmodule &::=& \text{(}~\text{module}~~m{:}\Tmodulebody~\text{)} @@ -371,18 +410,68 @@ Modules \end{array} \end{array} -The definition of the :ref:`identifier context ` :math:`I` uses the following auxiliary notation to filters out optional identifiers from definitions and imports in an order-preserving fashion: +Here, the notation :math:`\bigcompose r^\ast` is shorthand for :ref:`composing ` a sequence of :ref:`module ` or :ref:`identifier context ` records, respectively; +if the sequence is empty, then all fields of the resulting record are empty. +Moreover, the following restrictions are imposed on the composition of :ref:`modules `: :math:`m_1 \compose m_2` is defined if and only if + +* :math:`m_1.\START = \epsilon \vee m_2.\START = \epsilon` + +* :math:`m_2.\IMPORTS = \epsilon \vee m_1.\FUNCS = m_1.\TABLES = m_1.\MEMS = m_1.\GLOBALS = \epsilon` + +.. note:: + The first condition ensures that there is at most one start function. + The second condition enforces that all :ref:`imports ` must occur before any regular definition of a :ref:`function `, :ref:`table `, :ref:`memory `, or :ref:`global `, + thereby maintaining the ordering of the respective :ref:`index spaces `. + +The definition of the initial :ref:`identifier context ` :math:`I` uses the following auxiliary definition which maps each relevant definition to a singular context with one (possibly empty) identifier: .. math:: - \begin{array}{lcl@{\qquad\qquad}l} + \begin{array}{@{}lcl@{\qquad\qquad}l} + \F{idc}(\text{(}~\text{type}~\Tid^?~\dots~\text{)}) &=& + \{\TYPES~(\Tid^?)\} \\ + \F{idc}(\text{(}~\text{func}~\Tid^?~\dots~\text{)}) &=& + \{\FUNCS~(\Tid^?)\} \\ + \F{idc}(\text{(}~\text{table}~\Tid^?~\dots~\text{)}) &=& + \{\TABLES~(\Tid^?)\} \\ + \F{idc}(\text{(}~\text{memory}~\Tid^?~\dots~\text{)}) &=& + \{\MEMS~(\Tid^?)\} \\ + \F{idc}(\text{(}~\text{global}~\Tid^?~\dots~\text{)}) &=& + \{\GLOBALS~(\Tid^?)\} \\ + \F{idc}(\text{(}~\text{import}~\dots~\text{(}~\text{func}~\Tid^?~\dots~\text{)}~\text{)}) &=& + \{\FUNCS~(\Tid^?)\} \\ + \F{idc}(\text{(}~\text{import}~\dots~\text{(}~\text{table}~\Tid^?~\dots~\text{)}~\text{)}) &=& + \{\TABLES~(\Tid^?)\} \\ + \F{idc}(\text{(}~\text{import}~\dots~\text{(}~\text{memory}~\Tid^?~\dots~\text{)}~\text{)}) &=& + \{\MEMS~(\Tid^?)\} \\ + \F{idc}(\text{(}~\text{import}~\dots~\text{(}~\text{global}~\Tid^?~\dots~\text{)}~\text{)}) &=& + \{\GLOBALS~(\Tid^?)\} \\ + \F{idc}(\text{(}~\dots~\text{)}) &=& + \{\} \\ + \end{array} + + +.. math + \F{idc}(\epsilon) &=& + \{\} \\ + \F{idc}(\Tmodulebody~\Tmodulefield) &=& + \F{idc}(\Tmodulebody) \compose \F{idc}(\Tmodulefield) \\[1ex] + + The definition of the :ref:`identifier context ` :math:`I` uses the following auxiliary notation to filters out optional identifiers from definitions and imports in an order-preserving fashion: + + \begin{array}{@{}l@{}} + \begin{array}{@{}lcl@{\qquad\qquad}l} \F{id}(\text{(}~\text{type}~\Tid^?~\dots~\text{)}) &=& \Tid^? \\ \F{id}(\text{(}~\text{func}~\Tid^?~\dots~\text{)}) &=& \Tid^? \\ \F{id}(\text{(}~\text{table}~\Tid^?~\dots~\text{)}) &=& \Tid^? \\ \F{id}(\text{(}~\text{memory}~\Tid^?~\dots~\text{)}) &=& \Tid^? \\ \F{id}(\text{(}~\text{global}~\Tid^?~\dots~\text{)}) &=& \Tid^? \\[1ex] - \F{desc}(\text{(}~\text{import}~\dots~\Timportdesc~\text{)}) &=& \Timportdesc \\[1ex] \F{funcids}(\Timport^\ast) &=& [\Tid^? ~|~ \text{(}~\text{func}~\Tid^?~\dots~\text{)} \in \F{desc}(\Timport)^\ast] \\ \F{tableids}(\Timport^\ast) &=& [\Tid^? ~|~ \text{(}~\text{table}~\Tid^?~\dots~\text{)} \in \F{desc}(\Timport)^\ast] \\ \F{memids}(\Timport^\ast) &=& [\Tid^? ~|~ \text{(}~\text{memory}~\Tid^?~\dots~\text{)} \in \F{desc}(\Timport)^\ast] \\ \F{globalids}(\Timport^\ast) &=& [\Tid^? ~|~ \text{(}~\text{global}~\Tid^?~\dots~\text{)} \in \F{desc}(\Timport)^\ast] \\ + \end{array} \\ + \F{desc}(\text{(}~\text{import}~\dots~\Timportdesc~\text{)}) \quad=\quad \Timportdesc \end{array} + +.. note:: + The :ref:`well-formedness ` condition on :math:`I` ensures that no namespace contains duplicate identifiers. From 5658fab687ed59003e2795bf2562a83e87a0ba26 Mon Sep 17 00:00:00 2001 From: rossberg-chromium Date: Wed, 10 May 2017 15:25:06 +0200 Subject: [PATCH 12/30] Free module ordering --- document/text/instructions.rst | 27 +++++++++++++++++---------- 1 file changed, 17 insertions(+), 10 deletions(-) diff --git a/document/text/instructions.rst b/document/text/instructions.rst index 34c91d9068..62355196eb 100644 --- a/document/text/instructions.rst +++ b/document/text/instructions.rst @@ -18,6 +18,8 @@ Both can also be written in :ref:`folded ` form. &\Rightarrow& \X{in}^\ast \\ \end{array} +:ref:`Folded instructions` are a syntactic abbreviation for grouping instructions. + .. _text-label: .. index:: index, label index @@ -33,8 +35,8 @@ The following grammar handles the corresponding update to the :ref:`identifier c .. math:: \begin{array}{llclll} \production{label} & \Tlabel_I &::=& - \epsilon &\Rightarrow& I \with \LABELS~(\epsilon)~I.\LABELS \\ &&|& - v{:}\Tid &\Rightarrow& I \with \LABELS~v~I.\LABELS + \epsilon &\Rightarrow& \{\LABELS~(\epsilon)\} \compose I \\ &&|& + v{:}\Tid &\Rightarrow& \{\LABELS~v\} \compose I \\ & (v \notin I.\LABELS) \\ \end{array} @@ -61,15 +63,20 @@ Control Instructions .. math:: \begin{array}{llclll} \production{block instruction} & \Tblockinstr_I &::=& - \text{block}~~I'{:}\Tlabel_I~~\X{rt}{:}\Tresulttype~~(\X{in}{:}\Tinstr_{I'})^\ast~~\text{end} - &\Rightarrow& \BLOCK~\X{rt}~\X{in}^\ast~\END \\ &&|& - \text{loop}~~I'{:}\Tlabel_I~~\X{rt}{:}\Tresulttype~~(\X{in}{:}\Tinstr_{I'})^\ast~~\text{end} - &\Rightarrow& \LOOP~\X{rt}~\X{in}^\ast~\END \\ &&|& - \text{if}~~I'{:}\Tlabel_I~~\X{rt}{:}\Tresulttype~~(\X{in}{:}\Tinstr_{I'})^\ast~~\text{end} - &\Rightarrow& \IF~\X{rt}~\X{in}^\ast~\ELSE~\epsilon~\END \\ &&|& + \text{block}~~I'{:}\Tlabel_I~~\X{rt}{:}\Tresulttype~~(\X{in}{:}\Tinstr_{I'})^\ast~~\text{end}~~\Tid^? + &\Rightarrow& \BLOCK~\X{rt}~\X{in}^\ast~\END + \\ &&& (\Tid^? = \epsilon \vee \Tid^? = \Tlabel) \\ &&|& + \text{loop}~~I'{:}\Tlabel_I~~\X{rt}{:}\Tresulttype~~(\X{in}{:}\Tinstr_{I'})^\ast~~\text{end}~~\Tid^? + &\Rightarrow& \LOOP~\X{rt}~\X{in}^\ast~\END + \\ &&& (\Tid^? = \epsilon \vee \Tid^? = \Tlabel) \\ &&|& \text{if}~~I'{:}\Tlabel_I~~\X{rt}{:}\Tresulttype~~(\X{in}_1{:}\Tinstr_{I'})^\ast~~ - \text{else}~~(\X{in}_2{:}\Tinstr_{I'})^\ast~~\text{end} - &\Rightarrow& \IF~\X{rt}~\X{in}_1^\ast~\ELSE~\X{in}_2^\ast~\END \\ + \text{else}~~\Tid_1^?~~(\X{in}_2{:}\Tinstr_{I'})^\ast~~\text{end}~~\Tid_2^? + &\Rightarrow& \IF~\X{rt}~\X{in}_1^\ast~\ELSE~\X{in}_2^\ast~\END + \\ &&& (\Tid_1^? = \epsilon \vee \Tid_1^? = \Tlabel, \Tid_2^? = \epsilon \vee \Tid_2^? = \Tlabel) \\ + \end{array} + +.. math:: + \begin{array}{llclll} \production{plain instruction} & \Tplaininstr_I &::=& \text{unreachable} &\Rightarrow& \UNREACHABLE \\ &&|& \text{nop} &\Rightarrow& \NOP \\ &&|& From dfaa467e1c2466b14bf2b8f4741dc1e4e0d26ca6 Mon Sep 17 00:00:00 2001 From: rossberg-chromium Date: Wed, 10 May 2017 17:57:18 +0200 Subject: [PATCH 13/30] More abbreviations --- document/text/conventions.rst | 5 +- document/text/instructions.rst | 75 ++++++------ document/text/modules.rst | 204 +++++++++++++++++++++++++++------ document/text/values.rst | 12 +- 4 files changed, 214 insertions(+), 82 deletions(-) diff --git a/document/text/conventions.rst b/document/text/conventions.rst index 6d5db7cd0f..dea4e05d02 100644 --- a/document/text/conventions.rst +++ b/document/text/conventions.rst @@ -84,11 +84,14 @@ In order to distinguish symbols of the textual syntax from symbols of the abstra Auxiliary Notation ~~~~~~~~~~~~~~~~~~ -When dealing with binary encodings the following notation is also used: +When dealing with source text the following notation is also used: * :math:`\epsilon` denotes the empty byte sequence. +.. todo:: Explain abbreviations + + .. _text-context: .. _text-context-wf: .. index:: ! identifier context, identifier, index, index space diff --git a/document/text/instructions.rst b/document/text/instructions.rst index 62355196eb..b6888727a4 100644 --- a/document/text/instructions.rst +++ b/document/text/instructions.rst @@ -28,7 +28,8 @@ Both can also be written in :ref:`folded ` form. Labels ~~~~~~ -All :ref:`indices ` can be given either in raw numeric or in symbolic form. +:ref:`Structured control instructions ` can be annotated with an optional symbolic :ref:`label identifier ` that can be used in place of the corresponding numeric :ref:`label index ` in :ref:`branches `. + :ref:`Labels ` are the only symbolic indices that can be defined locally in an :ref:`instruction sequence `. The following grammar handles the corresponding update to the :ref:`identifier context ` by producing a context with an additional label entry. @@ -36,10 +37,15 @@ The following grammar handles the corresponding update to the :ref:`identifier c \begin{array}{llclll} \production{label} & \Tlabel_I &::=& \epsilon &\Rightarrow& \{\LABELS~(\epsilon)\} \compose I \\ &&|& - v{:}\Tid &\Rightarrow& \{\LABELS~v\} \compose I \\ + v{:}\Tid &\Rightarrow& \{\LABELS~v\} \compose I & (v \notin I.\LABELS) \\ \end{array} +.. note:: + The new label entry is inserted at the *beginning* of the label list in the identifier context. + This effectively shifts all existing labels by one, + mirroring the fact that control instructions are indexed relatively not absolutely. + .. _text-instr-control: .. index:: control instructions, structured control, label, block, branch, result type, label index, function index, type index, vector, polymorphism @@ -48,33 +54,39 @@ The following grammar handles the corresponding update to the :ref:`identifier c Control Instructions ~~~~~~~~~~~~~~~~~~~~ -.. _text-nop: -.. _text-unreachable: .. _text-block: .. _text-loop: .. _text-if: -.. _text-br: -.. _text-br_if: -.. _text-br_table: -.. _text-return: -.. _text-call: -.. _text-call_indirect: + +:ref:`Structured control instructions ` can bind an optional symbolic :ref:`label identifier `. +The same identifier may optionally be repeated after the corresponding :math:`\T{end}` and :math:`\T{else}` pseudo instructions. .. math:: \begin{array}{llclll} \production{block instruction} & \Tblockinstr_I &::=& \text{block}~~I'{:}\Tlabel_I~~\X{rt}{:}\Tresulttype~~(\X{in}{:}\Tinstr_{I'})^\ast~~\text{end}~~\Tid^? - &\Rightarrow& \BLOCK~\X{rt}~\X{in}^\ast~\END - \\ &&& (\Tid^? = \epsilon \vee \Tid^? = \Tlabel) \\ &&|& + \\ &&&\qquad \Rightarrow\quad \BLOCK~\X{rt}~\X{in}^\ast~\END + \qquad\quad (\Tid^? = \epsilon \vee \Tid^? = \Tlabel) \\ &&|& \text{loop}~~I'{:}\Tlabel_I~~\X{rt}{:}\Tresulttype~~(\X{in}{:}\Tinstr_{I'})^\ast~~\text{end}~~\Tid^? - &\Rightarrow& \LOOP~\X{rt}~\X{in}^\ast~\END - \\ &&& (\Tid^? = \epsilon \vee \Tid^? = \Tlabel) \\ &&|& + \\ &&&\qquad \Rightarrow\quad \LOOP~\X{rt}~\X{in}^\ast~\END + \qquad\qquad (\Tid^? = \epsilon \vee \Tid^? = \Tlabel) \\ &&|& \text{if}~~I'{:}\Tlabel_I~~\X{rt}{:}\Tresulttype~~(\X{in}_1{:}\Tinstr_{I'})^\ast~~ \text{else}~~\Tid_1^?~~(\X{in}_2{:}\Tinstr_{I'})^\ast~~\text{end}~~\Tid_2^? - &\Rightarrow& \IF~\X{rt}~\X{in}_1^\ast~\ELSE~\X{in}_2^\ast~\END - \\ &&& (\Tid_1^? = \epsilon \vee \Tid_1^? = \Tlabel, \Tid_2^? = \epsilon \vee \Tid_2^? = \Tlabel) \\ + \\ &&&\qquad \Rightarrow\quad \IF~\X{rt}~\X{in}_1^\ast~\ELSE~\X{in}_2^\ast~\END + \qquad (\Tid_1^? = \epsilon \vee \Tid_1^? = \Tlabel, \Tid_2^? = \epsilon \vee \Tid_2^? = \Tlabel) \\ \end{array} +.. _text-nop: +.. _text-unreachable: +.. _text-br: +.. _text-br_if: +.. _text-br_table: +.. _text-return: +.. _text-call: +.. _text-call_indirect: + +All other control instruction are represented verbatim. + .. math:: \begin{array}{llclll} \production{plain instruction} & \Tplaininstr_I &::=& @@ -402,7 +414,10 @@ Numeric Instructions Folded Instructions ~~~~~~~~~~~~~~~~~~~ -As a further abbreviation, instructions can also be written in *folded* S-expression form. +As a special abbreviation, instructions can be grouped into *folded* S-expression form. +The set side of all instruction phrases enabled by the following abbreviations defines the auxiliary syntactic class |Tfoldedinstr|. + +.. MathJax doesn't handle LaTex multicolumns, this the spacing hack in the following formula. .. math:: \begin{array}{lllll} @@ -413,33 +428,15 @@ As a further abbreviation, instructions can also be written in *folded* S-expres &\equiv\quad \text{block}~~\Tlabel~~\Tresulttype~~\Tinstr^\ast~~\text{end} \\ & \text{(}~\text{loop}~~\Tresulttype~~\Tinstr^\ast~\text{)} &\equiv\quad \text{loop}~~\Tlabel~~\Tresulttype~~\Tinstr^\ast~~\text{end} \\ & - \text{(}~\text{if}~~\Tlabel~~\Tresulttype~~\Tfoldedinstr - &\hspace{-1ex} \text{(}~\text{then}~~\Tinstr_1^\ast~\text{)}~~\text{(}~\text{else}~~\Tinstr_2^\ast~\text{)}^?~~\text{)} + \text{(}~\text{if}~~\Tlabel~~\Tresulttype~~\Tfoldedinstr^\ast + &\hspace{-3ex} \text{(}~\text{then}~~\Tinstr_1^\ast~\text{)}~~\text{(}~\text{else}~~\Tinstr_2^\ast~\text{)}^?~~\text{)} \quad\equiv \\ &\qquad - \Tfoldedinstr~~\text{if}~~\Tresulttype \hspace{-2em}& - ~\Tinstr_1^\ast~~\text{else}~~(\Tinstr_2^\ast)^?~\text{end} \\ - \end{array} - -.. math (commented out) - \begin{array}{llclll} - \production{folded instruction} & \Tfoldedinstr_I &::=& - \text{(}~\X{in}{:}\Tplaininstr~~(\X{op}{:}\Tfoldedinstr_I)^\ast~\text{)} - &\Rightarrow& \X{op}^\ast~\X{in} \\ &&|& - \text{(}~\text{block}~~\X{rt}{:}\Tresulttype~~(\X{in}{:}\Tinstr_{I'})^\ast~\text{)} - &\Rightarrow& \BLOCK~\X{rt}~\X{in}^\ast~\END \\ &&|& - \text{(}~\text{loop}~~\X{rt}{:}\Tresulttype~~(\X{in}{:}\Tinstr_{I'})^\ast~\text{)} - &\Rightarrow& \LOOP~\X{rt}~\X{in}^\ast~\END \\ &&|& - \text{(}~\text{if}~~\X{rt}{:}\Tresulttype~~\X{in}_0^\ast{:}\Tfoldedinstr_I~~\text{(}~\text{then}~~(\X{in}{:}\Tinstr_{I'})^\ast~\text{)}~~\text{)} - &\Rightarrow& \X{in}_0^\ast~~\IF~\X{rt}~\X{in}^\ast~\ELSE~\epsilon~\END \\ &&|& - \text{(}~\text{if}~~\X{rt}{:}\Tresulttype~~\X{in}_0^\ast{:}\Tfoldedinstr_I~~\text{(}~\text{then}~~(\X{in}_1{:}\Tinstr_{I'})^\ast~\text{)}~~ - \text{(}~\text{else}~~(\X{in}_2{:}\Tinstr_{I'})^\ast~\text{)}~~\text{)} - &\Rightarrow& \X{in}_0^\ast~~\IF~\X{rt}~\X{in}_1^\ast~\ELSE~\X{in}_2^\ast~\END \\ + \Tfoldedinstr^\ast~~\text{if}~~\Tlabel~~\Tresulttype &\hspace{-1ex} \Tinstr_1^\ast~~\text{else}~~(\Tinstr_2^\ast)^?~\text{end} \\ \end{array} .. note:: Folded instructions are solely syntactic sugar, - no additional syntactic or type checking is implied. - In particular, the number of syntactic operands to an instruction can differ from the number of values that the instruction consumes from the :ref:`stack `, because an individual operand instruction may produce less or more than one value. + no additional syntactic or type-based checking is implied. .. _text-expr: diff --git a/document/text/modules.rst b/document/text/modules.rst index 1cc943a41b..62f007584d 100644 --- a/document/text/modules.rst +++ b/document/text/modules.rst @@ -23,32 +23,32 @@ Modules Indices ~~~~~~~ -All :ref:`indices ` can be given either in raw numeric or in symbolic form. -In the latter case, they are looked up in the suitable space of the :ref:`identifier context `. +All :ref:`indices ` can be given either in raw numeric form or as symbolic :ref:`identifiers ` when bound by a respective construct. +Identifiers are looked up in the suitable space of the :ref:`identifier context `. .. math:: - \begin{array}{llclll} + \begin{array}{llclllllll} \production{type index} & \Ttypeidx_I &::=& - x{:}\Tu32 &\Rightarrow& x \\ &&|& + x{:}\Tu32 &\Rightarrow& x &|& v{:}\Tid &\Rightarrow& x & (I.\TYPES[x] = v) \\ \production{function index} & \Tfuncidx_I &::=& - x{:}\Tu32 &\Rightarrow& x \\ &&|& + x{:}\Tu32 &\Rightarrow& x &|& v{:}\Tid &\Rightarrow& x & (I.\FUNCS[x] = v) \\ \production{table index} & \Ttableidx_I &::=& - x{:}\Tu32 &\Rightarrow& x \\ &&|& + x{:}\Tu32 &\Rightarrow& x &|& v{:}\Tid &\Rightarrow& x & (I.\TABLES[x] = v) \\ \production{memory index} & \Tmemidx_I &::=& - x{:}\Tu32 &\Rightarrow& x \\ &&|& + x{:}\Tu32 &\Rightarrow& x &|& v{:}\Tid &\Rightarrow& x & (I.\MEMS[x] = v) \\ \production{global index} & \Tglobalidx_I &::=& - x{:}\Tid &\Rightarrow& x \\ &&|& + x{:}\Tu32 &\Rightarrow& x &|& v{:}\Tid &\Rightarrow& x & (I.\GLOBALS[x] = v) \\ \production{local index} & \Tlocalidx_I &::=& - x{:}\Tu32 &\Rightarrow& x \\ &&|& + x{:}\Tu32 &\Rightarrow& x &|& v{:}\Tid &\Rightarrow& x & (I.\LOCALS[x] = v) \\ \production{label index} & \Tlabelidx_I &::=& - l{:}\Tu32 &\Rightarrow& l \\ &&|& - v{:}\Tid &\Rightarrow& x & (I.\LABELS[x] = v) \\ + l{:}\Tu32 &\Rightarrow& l &|& + v{:}\Tid &\Rightarrow& l & (I.\LABELS[l] = v) \\ \end{array} @@ -59,6 +59,8 @@ In the latter case, they are looked up in the suitable space of the :ref:`identi Types ~~~~~ +Type definitions can bind a symbolic :ref:`type identifier `. + .. math:: \begin{array}{llclll} \production{type definition} & \Ttype &::=& @@ -119,6 +121,8 @@ A |Ttypeuse| may also be replaced entirely by inline function :ref:`parameters < In that case, the :ref:`type index ` of the first matching :ref:`type definition ` is automatically inserted. If no matching definition exists +.. todo:: fix + .. math:: \begin{array}{llclll} \production{type use} & @@ -135,7 +139,7 @@ If no matching definition exists Imports ~~~~~~~ -.. todo:: inline imports +The descriptors in imports can bind a symbolic function, table, memory, or global :ref:`identifier `. .. math:: \begin{array}{llclll} @@ -161,17 +165,17 @@ Imports Functions ~~~~~~~~~ -.. todo:: inline type, inline import/export +.. todo:: inline type + +Function definitions can bind a symbolic :ref:`function identifier `. .. math:: \begin{array}{llclll} \production{function} & \Tfunc_I &::=& \text{(}~\text{func}~~\Tid^?~~x,I'{:}\Ttypeuse_I~~ (t{:}\Tlocal)^\ast~~(\X{in}{:}\Tinstr_{I''})^\ast~\text{)} - &\Rightarrow& \{ \TYPE~x, \LOCALS~t^\ast, \BODY~\X{in}^\ast~\END \} \\ &&& \qquad - (\begin{array}[n]{@{}l@{}} - I'' = I' \compose \{\LOCALS~\F{id}(\Tlocal)^\ast\} \idcwellformed) \\ - \end{array} \\ + &\Rightarrow& \{ \TYPE~x, \LOCALS~t^\ast, \BODY~\X{in}^\ast~\END \} \\ &&&&& \qquad + (I'' = I' \compose \{\LOCALS~\F{id}(\Tlocal)^\ast\} \idcwellformed) \\ \production{local} & \Tlocal &::=& \text{(}~\text{local}~~\Tid^?~~t{:}\Tvaltype~\text{)} &\Rightarrow& t \\ @@ -192,8 +196,6 @@ The definition of the local :ref:`identifier context ` :math:`I''` Abbreviations ............. -A number of abbreviations are defined for functions. - Multiple anonymous locals may be combined into a single declaration: .. math:: @@ -203,6 +205,20 @@ Multiple anonymous locals may be combined into a single declaration: (\text{(}~~\text{local}~~\Tvaltype~~\text{)})^\ast \\ \end{array} +Functions can be defined as :ref:`imports ` or :ref:`exports ` inline: + +.. math:: + \begin{array}{llclll} + \production{module field} & + \text{(}~\text{func}~~\Tid^?~~\text{(}~\text{import}~~\Tname_1~~\Tname_2~\text{)}~~\Ttypeuse~\text{)} &\equiv& + \text{(}~\text{import}~~\Tname_1~~\Tname_2~~\text{(}~\text{func}~~\Tid^?~~\Ttypeuse~\text{)}~\text{)} \\ & + \text{(}~\text{func}~~\Tid^?~~\text{(}~\text{export}~~\Tname~\text{)}~~\Ttypeuse~~\dots~\text{)} &\equiv& + \text{(}~\text{export}~~\Tname~~\text{(}~\text{func}~~\Tid'~\text{)}~\text{)}~~ + \text{(}~\text{func}~~\Tid'~~\Ttypeuse~~\dots~\text{)} + \\&&& \qquad + (\Tid' = \Tid^? \neq \epsilon \vee \Tid'~\mbox{fresh}) \\ + \end{array} + .. _text-table: .. index:: table, table type @@ -211,6 +227,8 @@ Multiple anonymous locals may be combined into a single declaration: Tables ~~~~~~ +Table definitions can bind a symbolic :ref:`table identifier `. + .. math:: \begin{array}{llclll} \production{table} & \Ttable_I &::=& @@ -219,6 +237,36 @@ Tables \end{array} +Abbreviations +............. + +Tables can be defined as :ref:`imports ` or :ref:`exports ` inline: + +.. math:: + \begin{array}{llclll} + \production{module field} & + \text{(}~\text{table}~~\Tid^?~~\text{(}~\text{import}~~\Tname_1~~\Tname_2~\text{)}~~\Ttabletype~\text{)} &\equiv& + \text{(}~\text{import}~~\Tname_1~~\Tname_2~~\text{(}~\text{table}~~\Tid^?~~\Ttabletype~\text{)}~\text{)} \\ & + \text{(}~\text{table}~~\Tid^?~~\text{(}~\text{export}~~\Tname~\text{)}~~\Ttabletype~\text{)} &\equiv& + \text{(}~\text{export}~~\Tname~~\text{(}~\text{table}~~\Tid'~\text{)}~\text{)}~~ + \text{(}~\text{table}~~\Tid'~~\Ttabletype~\text{)} + \\&&& \qquad + (\Tid' = \Tid^? \neq \epsilon \vee \Tid'~\mbox{fresh}) \\ + \end{array} + +Moreover, :ref:`elements ` can be given inline, in which case the limits of the table type are inferred from the length of the given element vector: + +.. math:: + \begin{array}{llclll} + \production{module field} & + \text{(}~\text{table}~~\Tid^?~~\text{(}~\text{export}~~\Tname~\text{)}^?~~\Telemtype~~\text{(}~\text{elem}~~\Tvec(\Tfuncidx)~\text{)}~~\text{)} &\equiv& + \text{(}~\text{table}~~\Tid'~~\text{(}~\text{export}~~\Tname~\text{)}^?~~n~~n~~\Telemtype~\text{)}~~ + \text{(}~\text{elem}~~\Tid'~~\text{(}~\text{i32.const}~~\text{0}~\text{)}~~\Tvec(\Tfuncidx)~\text{)} + \\&&& \qquad + (n = |\Tvec(\Tfuncidx)|, \Tid' = \Tid^? \neq \epsilon \vee \Tid'~\mbox{fresh}) \\ + \end{array} + + .. _text-mem: .. index:: memory, memory type pair: text format; memory @@ -226,6 +274,8 @@ Tables Memories ~~~~~~~~ +Memory definitions can bind a symbolic :ref:`memory identifier `. + .. math:: \begin{array}{llclll} \production{memory} & \Tmem_I &::=& @@ -234,6 +284,38 @@ Memories \end{array} +Abbreviations +............. + +Memories can be defined as :ref:`imports ` or :ref:`exports ` inline: + +.. math:: + \begin{array}{llclll} + \production{module field} & + \text{(}~\text{memory}~~\Tid^?~~\text{(}~\text{import}~~\Tname_1~~\Tname_2~\text{)}~~\Tmemtype~\text{)} &\equiv& + \text{(}~\text{import}~~\Tname_1~~\Tname_2~~\text{(}~\text{memory}~~\Tid^?~~\Tmemtype~\text{)}~\text{)} \\ & + \text{(}~\text{memory}~~\Tid^?~~\text{(}~\text{export}~~\Tname~\text{)}~~\Tmemtype~\text{)} &\equiv& + \text{(}~\text{export}~~\Tname~~\text{(}~\text{memory}~~\Tid'~\text{)}~\text{)}~~ + \text{(}~\text{memory}~~\Tid'~~\Tmemtype~\text{)} + \\&&& \qquad + (\Tid' = \Tid^? \neq \epsilon \vee \Tid'~\mbox{fresh}) \\ + \end{array} + +Moreover, :ref:`data ` can be given inline, in which case the limits of the table type are inferred from the length of the given string, rounded up to :ref:`page size `: + +.. math:: + \begin{array}{llclll} + \production{module field} & + \text{(}~\text{memory}~~\Tid^?~~\text{(}~\text{export}~~\Tname~\text{)}^?~~\text{(}~\text{data}~~\Tstring~\text{)}~~\text{)} &\equiv& + \text{(}~\text{memory}~~\Tid'~~\text{(}~\text{export}~~\Tname~\text{)}^?~~n~~n~\text{)}~~ + \text{(}~\text{data}~~\Tid'~~\text{(}~\text{i32.const}~~\text{0}~\text{)}~~\Tstring~\text{)} + \\&&& \qquad + (n = |\Tstring|, \Tid' = \Tid^? \neq \epsilon \vee \Tid'~\mbox{fresh}) \\ + \end{array} + +.. todo:: length of data + + .. _text-global: .. index:: global, global type, expression pair: text format; global @@ -241,6 +323,8 @@ Memories Globals ~~~~~~~ +Global definitions can bind a symbolic :ref:`global identifier `. + .. math:: \begin{array}{llclll} \production{global} & \Tglobal_I &::=& @@ -249,6 +333,24 @@ Globals \end{array} +Abbreviations +............. + +Globals can be defined as :ref:`imports ` or :ref:`exports ` inline: + +.. math:: + \begin{array}{llclll} + \production{module field} & + \text{(}~\text{global}~~\Tid^?~~\text{(}~\text{import}~~\Tname_1~~\Tname_2~\text{)}~~\Tglobaltype~\text{)} &\equiv& + \text{(}~\text{import}~~\Tname_1~~\Tname_2~~\text{(}~\text{global}~~\Tid^?~~\Tglobaltype~\text{)}~\text{)} \\ & + \text{(}~\text{global}~~\Tid^?~~\text{(}~\text{export}~~\Tname~\text{)}~~\Tglobaltype~\text{)} &\equiv& + \text{(}~\text{export}~~\Tname~~\text{(}~\text{global}~~\Tid'~\text{)}~\text{)}~~ + \text{(}~\text{global}~~\Tid'~~\Tglobaltype~\text{)} + \\&&& \qquad + (\Tid' = \Tid^? \neq \epsilon \vee \Tid'~\mbox{fresh}) \\ + \end{array} + + .. _text-export: .. index:: export, name, index, function index, table index, memory index, global index pair: text format; export @@ -297,13 +399,21 @@ Start Function Element Segments ~~~~~~~~~~~~~~~~ +Element segments allow for an optional :ref:`table index ` to identify the table to initialize. +When omitted, :math:`\T{0}` is assumed. + .. math:: \begin{array}{llclll} \production{element segment} & \Telem_I &::=& - \text{(}~\text{elem}~~x{:}\Ttableidx_I~~\text{(}~\text{offset}~~(\X{in}{:}\Tinstr_I)^\ast~\text{)}~~y^\ast{:}\Tvec(\Tfuncidx_I)~\text{)} - &\Rightarrow& \{ \TABLE~x, \OFFSET~\X{in}^\ast~\END, \INIT~y^\ast \} \\ + \text{(}~\text{elem}~~(x{:}\Ttableidx_I)^?~~\text{(}~\text{offset}~~(\X{in}{:}\Tinstr_I)^\ast~\text{)}~~y^\ast{:}\Tvec(\Tfuncidx_I)~\text{)} + &\Rightarrow& \{ \TABLE~x', \OFFSET~\X{in}^\ast~\END, \INIT~y^\ast \} \\ + &&&&& \qquad (x' = x^? \neq \epsilon \vee x' = 0) \\ \end{array} +.. note:: + In the current version of WebAssembly, the only valid table index is 0 + or a symbolic :ref:`table identifier ` resolving to the same value. + .. _text-data: .. index:: data, memory, memory index, expression, byte @@ -314,13 +424,21 @@ Element Segments Data Segments ~~~~~~~~~~~~~ +Data segments allow for an optional :ref:`memory index ` to identify the memory to initialize. +When omitted, :math:`\T{0}` is assumed. + .. math:: \begin{array}{llclll} \production{data segment} & \Tdata_I &::=& - \text{(}~\text{data}~~x{:}\Tmemidx_I~~\text{(}~\text{offset}~~(\X{in}{:}\Tinstr_I)^\ast~\text{)}~~b^\ast{:}\Tstring~\text{)} - &\Rightarrow& \{ \MEM~x, \OFFSET~\X{in}^\ast~\END, \INIT~b^\ast \} \\ + \text{(}~\text{data}~~(x{:}\Tmemidx_I)^?~~\text{(}~\text{offset}~~(\X{in}{:}\Tinstr_I)^\ast~\text{)}~~b^\ast{:}\Tstring~\text{)} + &\Rightarrow& \{ \MEM~x', \OFFSET~\X{in}^\ast~\END, \INIT~b^\ast \} \\ + &&&&& \qquad (x' = x^? \neq \epsilon \vee x' = 0) \\ \end{array} +.. note:: + In the current version of WebAssembly, the only valid memory index is 0 + or a symbolic :ref:`memory identifier ` resolving to the same value. + .. _text-module: .. _text-modulebody: @@ -338,21 +456,21 @@ Modules ::=& \text{(}~\text{module}~~(m{:}\Tmodulefield_I)^\ast~\text{)} &\Rightarrow& \bigcompose m^\ast - \\& (I = \bigcompose \F{idc}(\Tmodulefield)^\ast \idcwellformed) \\ + & (I = \bigcompose \F{idc}(\Tmodulefield)^\ast \idcwellformed) \\ \end{array} \\ \production{module field} & \Tmodulefield_I & \begin{array}[t]{@{}clll} ::=& - \functype{:}\Ttype &\Rightarrow& \{\TYPES~\functype\} \\ |& - \import{:}\Timport_I &\Rightarrow& \{\IMPORTS~\import\} \\ |& - \func{:}\Tfunc_I &\Rightarrow& \{\FUNCS~\func\} \\ |& - \table{:}\Ttable_I &\Rightarrow& \{\TABLES~\table\} \\ |& - \mem{:}\Tmem_I &\Rightarrow& \{\MEMS~\mem\} \\ |& - \global{:}\Tglobal_I &\Rightarrow& \{\GLOBALS~\global\} \\ |& - \export{:}\Texport_I &\Rightarrow& \{\EXPORTS~\export\} \\ |& - \start{:}\Tstart_I &\Rightarrow& \{\START~\start\} \\ |& - \elem{:}\Telem_I &\Rightarrow& \{\ELEM~\elem\} \\ |& - \data{:}\Tdata_I &\Rightarrow& \{\DATA~\data\} \\ + \X{ty}{:}\Ttype &\Rightarrow& \{\TYPES~\X{ty}\} \\ |& + \X{im}{:}\Timport_I &\Rightarrow& \{\IMPORTS~\X{im}\} \\ |& + \X{fn}{:}\Tfunc_I &\Rightarrow& \{\FUNCS~\X{fn}\} \\ |& + \X{ta}{:}\Ttable_I &\Rightarrow& \{\TABLES~\X{ta}\} \\ |& + \X{me}{:}\Tmem_I &\Rightarrow& \{\MEMS~\X{me}\} \\ |& + \X{gl}{:}\Tglobal_I &\Rightarrow& \{\GLOBALS~\X{gl}\} \\ |& + \X{ex}{:}\Texport_I &\Rightarrow& \{\EXPORTS~\X{ex}\} \\ |& + \X{st}{:}\Tstart_I &\Rightarrow& \{\START~\X{st}\} \\ |& + \X{el}{:}\Telem_I &\Rightarrow& \{\ELEM~\X{el}\} \\ |& + \X{da}{:}\Tdata_I &\Rightarrow& \{\DATA~\X{da}\} \\ \end{array} \end{array} @@ -423,8 +541,12 @@ Moreover, the following restrictions are imposed on the composition of :ref:`mod The second condition enforces that all :ref:`imports ` must occur before any regular definition of a :ref:`function `, :ref:`table `, :ref:`memory `, or :ref:`global `, thereby maintaining the ordering of the respective :ref:`index spaces `. + The :ref:`well-formedness ` condition on :math:`I` in the grammar for |Tmodule| ensures that no namespace contains duplicate identifiers. + The definition of the initial :ref:`identifier context ` :math:`I` uses the following auxiliary definition which maps each relevant definition to a singular context with one (possibly empty) identifier: +.. todo:: |TYPEDEFS| + .. math:: \begin{array}{@{}lcl@{\qquad\qquad}l} \F{idc}(\text{(}~\text{type}~\Tid^?~\dots~\text{)}) &=& @@ -473,5 +595,15 @@ The definition of the initial :ref:`identifier context ` :math:`I` \F{desc}(\text{(}~\text{import}~\dots~\Timportdesc~\text{)}) \quad=\quad \Timportdesc \end{array} -.. note:: - The :ref:`well-formedness ` condition on :math:`I` ensures that no namespace contains duplicate identifiers. + +Abbreviations +............. + +In a source file, the toplevel :math:`\T{(module}~\dots\T{)}` surrounding the module body may be omitted. + +.. math:: + \begin{array}{llcll} + \production{module} & + \Tmodulefield^\ast &\equiv& + \text{(}~\text{module}~~\Tmodulefield^\ast~\text{)} + \end{array} diff --git a/document/text/values.rst b/document/text/values.rst index 5298c30b2b..555460c526 100644 --- a/document/text/values.rst +++ b/document/text/values.rst @@ -50,8 +50,8 @@ All :ref:`integers ` can be written in either decimal or hexadecimal n{:}\Thexnum~~h{:}\Thexdigit &\Rightarrow& 16\cdot n + h \\ \end{array} -Integer literals are distinguished by size and signedness. -Their value must lie within the range of the respective type. +The allowed syntax for integer literals depends on size and signedness. +Moreover, their value must lie within the range of the respective type. .. math:: \begin{array}{llclll@{\qquad}l} @@ -85,7 +85,7 @@ Floating-Point :ref:`Floating point ` values can be represented in either decimal or hexadecimal notation. The value of a literal must not lie outside the representable range of the corresponding `IEEE 754 `_ type -(that is, it must not overflow to :math:`\pm`infinity), +(that is, a numeric value must not overflow to :math:`\pm` infinity), but it may be rounded to the nearest representable value. .. note:: @@ -155,7 +155,7 @@ Strings *Strings* denote sequences of bytes that can represent both textual and binary data. They are enclosed in quotation marks and may contain any character other than `ASCII `_ control characters, quotation marks (:math:`\text{"}`), or backslash (:math:`\text{\verb|\|}`), -except when expressed with an *escape sequence* started by a backslash. +except when expressed with an *escape sequence*. Each character in a string literal represents the byte sequence corresponding to its `Unicode `_ UTF-8 encoding, except for hexadecimal escape sequences :math:`\text{\verb|\|}hh`, which represent raw bytes of the respective value. @@ -192,7 +192,7 @@ Names ~~~~~ :ref:`Names ` are strings denoting a literal character sequence. -It must form a valid `UTF-8 `_ encoding that is interpreted as a string of Unicode code points. +A name string must form a valid `UTF-8 `_ encoding that is interpreted as a string of Unicode code points. .. math:: \begin{array}{llclll@{\qquad}l} @@ -212,7 +212,7 @@ Identifiers ~~~~~~~~~~~ :ref:`Indices ` can be given in both numeric and symbolic form. -Symbolic *identifiers* standing for indices start with :math:`\text{$}`, followed by any sequence of printable `ASCII `_ characters that does not contain a space, quotation mark, comma, semicolon, or bracket. +Symbolic *identifiers* that stand in lieu of indices start with :math:`\text{$}`, followed by any sequence of printable `ASCII `_ characters that does not contain a space, quotation mark, comma, semicolon, or bracket. .. math:: \begin{array}{llclll@{\qquad}l} From 7907caa2925fb93f7961462a0d7fc82654393eba Mon Sep 17 00:00:00 2001 From: rossberg-chromium Date: Thu, 11 May 2017 15:37:05 +0200 Subject: [PATCH 14/30] Complete --- document/binary/modules.rst | 1 + document/math.def | 2 + document/syntax/modules.rst | 1 + document/text/conventions.rst | 32 ++-- document/text/instructions.rst | 70 ++++++-- document/text/lexical.rst | 19 +- document/text/modules.rst | 307 +++++++++++++++----------------- document/text/values.rst | 19 +- document/validation/modules.rst | 1 + 9 files changed, 248 insertions(+), 204 deletions(-) diff --git a/document/binary/modules.rst b/document/binary/modules.rst index 766d0daaef..0b919ecabe 100644 --- a/document/binary/modules.rst +++ b/document/binary/modules.rst @@ -308,6 +308,7 @@ It decodes into a vector of :ref:`element segments ` that represent .. _binary-local: .. index:: ! code section, function, local, type index, function type pair: binary format; function + pair: binary format; local pair: section; code Code Section diff --git a/document/math.def b/document/math.def index cf7a2e769a..ac8500d3b8 100644 --- a/document/math.def +++ b/document/math.def @@ -378,6 +378,7 @@ .. |Tlocal| mathdef:: \xref{text/modules}{text-local}{\T{local}} .. |Tlocals| mathdef:: \xref{text/modules}{text-local}{\T{locals}} .. |Tdata| mathdef:: \xref{text/modules}{text-data}{\T{data}} +.. |Tdatastring| mathdef:: \xref{text/modules}{text-datastring}{\T{datastring}} .. |Tstart| mathdef:: \xref{text/modules}{text-start}{\T{start}} @@ -508,4 +509,5 @@ .. Contexts, meta functions +.. |idfresh| mathdef:: ~\xref{text/conventions}{text-id-fresh}{\mbox{fresh}} .. |idcwellformed| mathdef:: ~\xref{text/conventions}{text-context-wf}{\mbox{well-formed}} diff --git a/document/syntax/modules.rst b/document/syntax/modules.rst index 2b5036bdd6..162404c71a 100644 --- a/document/syntax/modules.rst +++ b/document/syntax/modules.rst @@ -106,6 +106,7 @@ They are referenced by :ref:`type indices `. .. _syntax-local: .. index:: ! function, ! local, function index, local index, type index, value type, expression, import pair: abstract syntax; function + pair: abstract syntax; local Functions ~~~~~~~~~ diff --git a/document/text/conventions.rst b/document/text/conventions.rst index dea4e05d02..adf4c5962a 100644 --- a/document/text/conventions.rst +++ b/document/text/conventions.rst @@ -14,7 +14,7 @@ Some productions also take a :ref:`context ` as an inherited attri that records bound :ref:`identifers `. Except for a few exceptions, the core of the text grammar closely mirrors the grammar of the abstract syntax. -However, it also defines a number of forms that are *syntactic sugar* over the core syntax. +However, it also defines a number of *abbreviations* that are *syntactic sugar* over the core syntax. The recommended extension for source files containing WebAssembly modules in text format is ":math:`\T{.wat}`". Files with this extension are assumed to be encoded in `Unicode UTF-8 `_. @@ -32,9 +32,9 @@ The following conventions are adopted in defining grammar rules for the text for They mirror the conventions used for :ref:`abstract syntax ` and for the :ref:`binary format `. In order to distinguish symbols of the textual syntax from symbols of the abstract syntax, typewriter font is adopted for the former. -* Terminal symbols are either literal strings of characters enclosed in quotes: :math:`\text{module}`, - or expressed as `Unicode `_ code points: :math:`\unicode{0A}. - (All characters written literally are contained in the `7-bit ASCII `_ subset of Unicode.) +* Terminal symbols are either literal strings of characters enclosed in quotes: :math:`\text{module}`; + or expressed as `Unicode `_ code points: :math:`\unicode{0A}`. + (All characters written literally are unambguously drawn from the `7-bit ASCII `_ subset of Unicode.) * Nonterminal symbols are written in typewriter font: :math:`\T{valtype}, \T{instr}`. @@ -45,6 +45,9 @@ In order to distinguish symbols of the textual syntax from symbols of the abstra * :math:`T^\ast` is a possibly empty sequence of iterations of :math:`T`. (This is a shorthand for :math:`T^n` used where :math:`n` is not relevant.) +* :math:`T^+` is a sequence of one or more iterations of :math:`T`. + (This is a shorthand for :math:`T^n` where :math:`n \geq 1`.) + * :math:`T^?` is an optional occurrence of :math:`T`. (This is a shorthand for :math:`T^n` where :math:`n \leq 1`.) @@ -79,17 +82,20 @@ In order to distinguish symbols of the textual syntax from symbols of the abstra The attribute of the complete production then is the abstract syntax for the limit, expressed in terms of the former values. -.. _text-notation: +.. _text-abbreviations: +.. index:: ! abbreviations -Auxiliary Notation -~~~~~~~~~~~~~~~~~~ +Abbreviations +~~~~~~~~~~~~~ -When dealing with source text the following notation is also used: +In addition to the core grammar, which corresponds directly to the :ref:`abstract syntax `, the textual syntax also defines a number of *abbreviations* that can be used to improve convenience and readability. -* :math:`\epsilon` denotes the empty byte sequence. +Abbreviations are defined by rewrite rules specifying their expansion into the core syntax: +.. math:: + \X{abbreviation~syntax} \quad\equiv\quad \X{expanded~syntax} -.. todo:: Explain abbreviations +These expansions are assumed to be applied, recursively and in order of appearance, before applying the core grammar rules to construct the abstract syntax. .. _text-context: @@ -101,8 +107,8 @@ Contexts The text format allows to use symbolic :ref:`identifiers ` in place of :ref:`indices `. To resolve these identifiers into concrete indices, -some grammar production are indexed by an *identifier context* that records the declared identifiers in each :ref:`index space `. -In addition, the context records the types defined in the module, so that parameter indices can be computed. +some grammar production are indexed by an *identifier context* :math:`I` as a synthesized attribute that records the declared identifiers in each :ref:`index space `. +In addition, the context records the types defined in the module, so that :ref:`parameter ` indices can be computed for :ref:`functions `. It is convenient to define identifier contexts as :ref:`records ` :math:`I` with abstract syntax: @@ -121,7 +127,7 @@ It is convenient to define identifier contexts as :ref:`records ` \end{array} \end{array} -For each index space, an identifier context contains the list of :ref:`identifiers ` assigned to the defined indices. +For each index space, such a context contains the list of :ref:`identifiers ` assigned to the defined indices. Unnamed indices are associated with empty (:math:`\epsilon`) entries in these lists. An identifier context is *well-formed* if no index space contains duplicate identifiers. diff --git a/document/text/instructions.rst b/document/text/instructions.rst index b6888727a4..390ff54559 100644 --- a/document/text/instructions.rst +++ b/document/text/instructions.rst @@ -13,24 +13,68 @@ Both can also be written in :ref:`folded ` form. \X{in}{:}\Tplaininstr_I &\Rightarrow& \X{in} \\ &&|& \X{in}{:}\Tblockinstr_I - &\Rightarrow& \X{in} \\ &&|& - \X{in}^\ast{:}\Tfoldedinstr_I - &\Rightarrow& \X{in}^\ast \\ + &\Rightarrow& \X{in} \\ \end{array} -:ref:`Folded instructions` are a syntactic abbreviation for grouping instructions. +In addition, as a syntactic abbreviation, instructions can be :ref:`folded` into S-expressions, as a means of grouping them visually. +.. _text-index: +.. _text-typeidx: +.. _text-funcidx: +.. _text-tableidx: +.. _text-memidx: +.. _text-globalidx: +.. _text-localidx: +.. _text-labelidx: .. _text-label: -.. index:: index, label index +.. index:: index, type index, function index, table index, memory index, global index, local index, label index + pair: text format; type index + pair: text format; function index + pair: text format; table index + pair: text format; memory index + pair: text format; global index + pair: text format; local index pair: text format; label index -Labels -~~~~~~ +Indices +~~~~~~~ + +:ref:`Indices ` can be given either in raw numeric form or as symbolic :ref:`identifiers ` when bound by a respective construct. +Such identifiers are looked up in the suitable space of the :ref:`identifier context `. + +.. math:: + \begin{array}{llclllllll} + \production{type index} & \Ttypeidx_I &::=& + x{:}\Tu32 &\Rightarrow& x &|& + v{:}\Tid &\Rightarrow& x & (I.\TYPES[x] = v) \\ + \production{function index} & \Tfuncidx_I &::=& + x{:}\Tu32 &\Rightarrow& x &|& + v{:}\Tid &\Rightarrow& x & (I.\FUNCS[x] = v) \\ + \production{table index} & \Ttableidx_I &::=& + x{:}\Tu32 &\Rightarrow& x &|& + v{:}\Tid &\Rightarrow& x & (I.\TABLES[x] = v) \\ + \production{memory index} & \Tmemidx_I &::=& + x{:}\Tu32 &\Rightarrow& x &|& + v{:}\Tid &\Rightarrow& x & (I.\MEMS[x] = v) \\ + \production{global index} & \Tglobalidx_I &::=& + x{:}\Tu32 &\Rightarrow& x &|& + v{:}\Tid &\Rightarrow& x & (I.\GLOBALS[x] = v) \\ + \production{local index} & \Tlocalidx_I &::=& + x{:}\Tu32 &\Rightarrow& x &|& + v{:}\Tid &\Rightarrow& x & (I.\LOCALS[x] = v) \\ + \production{label index} & \Tlabelidx_I &::=& + l{:}\Tu32 &\Rightarrow& l &|& + v{:}\Tid &\Rightarrow& l & (I.\LABELS[l] = v) \\ + \end{array} -:ref:`Structured control instructions ` can be annotated with an optional symbolic :ref:`label identifier ` that can be used in place of the corresponding numeric :ref:`label index ` in :ref:`branches `. -:ref:`Labels ` are the only symbolic indices that can be defined locally in an :ref:`instruction sequence `. +.. _text-label: +.. index:: index, label index + pair: text format; label index + +:ref:`Structured control instructions ` can be annotated with an optional symbolic :ref:`label identifier ` that can be used in place of the corresponding numeric :ref:`label index ` to reference the instruction. +:ref:`Labels ` are the only symbolic identifiers that can be defined locally in an :ref:`instruction sequence `. The following grammar handles the corresponding update to the :ref:`identifier context ` by producing a context with an additional label entry. .. math:: @@ -43,7 +87,7 @@ The following grammar handles the corresponding update to the :ref:`identifier c .. note:: The new label entry is inserted at the *beginning* of the label list in the identifier context. - This effectively shifts all existing labels by one, + This effectively shifts all existing labels up by one, mirroring the fact that control instructions are indexed relatively not absolutely. @@ -415,7 +459,8 @@ Folded Instructions ~~~~~~~~~~~~~~~~~~~ As a special abbreviation, instructions can be grouped into *folded* S-expression form. -The set side of all instruction phrases enabled by the following abbreviations defines the auxiliary syntactic class |Tfoldedinstr|. +The set of all phrases defined by the following abbreviations recursively forms the auxiliary syntactic class |Tfoldedinstr|. +Such a folded instruction can appear anywhere a regular instruction can. .. MathJax doesn't handle LaTex multicolumns, this the spacing hack in the following formula. @@ -447,6 +492,9 @@ The set side of all instruction phrases enabled by the following abbreviations d Expressions ~~~~~~~~~~~ +Expressions are written as instruction sequences. +No explicit :math:`\text{end}` keyword is included, since they only occur in bracketed positions. + .. math:: \begin{array}{llclll} \production{expression} & \Texpr &::=& diff --git a/document/text/lexical.rst b/document/text/lexical.rst index 0834a4cdb8..a862a50ea7 100644 --- a/document/text/lexical.rst +++ b/document/text/lexical.rst @@ -5,7 +5,7 @@ Lexical Format .. _text-char: -.. index:: ! character, Unicode, ASCII, code point +.. index:: ! character, Unicode, ASCII, code point, ! source text pair: text format; character Characters @@ -22,11 +22,11 @@ Characters are assumed to be represented as valid `Unicode `_, - but a source text may contain other characters in :ref:`comments ` or :ref:`string ` literals. + but a source text may contain other characters in :ref:`comments ` or :ref:`string ` literals. .. _text-stoken: -.. index:: ! token, character, white space, comment +.. index:: ! token, character, white space, comment, source text single: text format; token Tokens @@ -40,7 +40,7 @@ or implicitly, by the occurrence of terminal symbols in literal form in the non- Tokens are formed from the input character stream according to the *longest match* rule. That is, the next token always consists of the longest possible sequence of characters that is recognized as a token. -Tokens may explicitly be separated by space and formatting characters or :ref:`comments `, +Tokens may explicitly be separated by space, formatting characters or :ref:`comments `, collectively called :ref:`white space `. Except for :ref:`string ` literals, white space cannot appear inside a token. @@ -53,8 +53,7 @@ White Space ~~~~~~~~~~~ *White space* is any sequence of literal space characters, formatting characters, or :ref:`comments `. - -The allowed formatting characters correspond to a subset of the `ASCII `_ *format effectors*, namely, *horizontal tabulation* (:math:`\unicode{09}`), *line feed* (:math:`\unicode{0A}`), or *carriage return* (:math:`\unicode{0D}`). +The allowed formatting characters correspond to a subset of the `ASCII `_ *format effectors*, namely, *horizontal tabulation* (:math:`\unicode{09}`), *line feed* (:math:`\unicode{0A}`), and *carriage return* (:math:`\unicode{0D}`). .. math:: \begin{array}{llclll@{\qquad\qquad}l} @@ -64,9 +63,6 @@ The allowed formatting characters correspond to a subset of the `ASCII `. - .. text-comment: .. index:: ! comment, character @@ -75,7 +71,7 @@ The allowed formatting characters correspond to a subset of the `ASCII ` can be given either in raw numeric form or as symbolic :ref:`identifiers ` when bound by a respective construct. -Identifiers are looked up in the suitable space of the :ref:`identifier context `. - -.. math:: - \begin{array}{llclllllll} - \production{type index} & \Ttypeidx_I &::=& - x{:}\Tu32 &\Rightarrow& x &|& - v{:}\Tid &\Rightarrow& x & (I.\TYPES[x] = v) \\ - \production{function index} & \Tfuncidx_I &::=& - x{:}\Tu32 &\Rightarrow& x &|& - v{:}\Tid &\Rightarrow& x & (I.\FUNCS[x] = v) \\ - \production{table index} & \Ttableidx_I &::=& - x{:}\Tu32 &\Rightarrow& x &|& - v{:}\Tid &\Rightarrow& x & (I.\TABLES[x] = v) \\ - \production{memory index} & \Tmemidx_I &::=& - x{:}\Tu32 &\Rightarrow& x &|& - v{:}\Tid &\Rightarrow& x & (I.\MEMS[x] = v) \\ - \production{global index} & \Tglobalidx_I &::=& - x{:}\Tu32 &\Rightarrow& x &|& - v{:}\Tid &\Rightarrow& x & (I.\GLOBALS[x] = v) \\ - \production{local index} & \Tlocalidx_I &::=& - x{:}\Tu32 &\Rightarrow& x &|& - v{:}\Tid &\Rightarrow& x & (I.\LOCALS[x] = v) \\ - \production{label index} & \Tlabelidx_I &::=& - l{:}\Tu32 &\Rightarrow& l &|& - v{:}\Tid &\Rightarrow& l & (I.\LABELS[l] = v) \\ - \end{array} - - .. _text-type: -.. index:: type definition +.. index:: type definition, identifier pair: text format; type definition Types @@ -77,30 +27,30 @@ Type Uses ~~~~~~~~~ A *type use* is a reference to a :ref:`type definition `. -It may optionally be augmented by inline function :ref:`parameters ` and :ref:`result ` annotations. -That allows declaring symbolic :ref:`identifiers ` for the :ref:`local indices ` of parameters. -If any inline annotation is given, then it must be complete and match the referenced type. +It may optionally be augmented by explicit inlined :ref:`parameter ` and :ref:`result ` declarations. +That allows binding symbolic :ref:`identifiers ` to name the :ref:`local indices ` of parameters. +If inline declarations are given, then their types must match the referenced :ref:`function type `. .. math:: \begin{array}{llclll} \production{type use} & \Ttypeuse_I &::=& \text{(}~\text{type}~~x{:}\Ttypeidx_I~\text{)} - \quad\Rightarrow\quad x, I' \\ &&& \qquad + &\Rightarrow& x, I' & (\begin{array}[t]{@{}l@{}} I.\TYPEDEFS[x] = [t_1^n] \to [t_2^\ast] \wedge I' = \{\LOCALS~(\epsilon)^n\}) \\ \end{array} \\ &&|& \text{(}~\text{type}~~x{:}\Ttypeidx_I~\text{)} ~~(t_1{:}\Tparam)^\ast~~(t_2{:}\Tresult)^\ast - \quad\Rightarrow\quad x, I' \\ &&&\qquad + &\Rightarrow& x, I' & (\begin{array}[t]{@{}l@{}} I.\TYPEDEFS[x] = [t_1^\ast] \to [t_2^\ast] \wedge I' = \{\LOCALS~\F{id}(\Tparam)\}^\ast \idcwellformed) \\ \end{array} \\ \end{array} -The resulting attribute of a |Ttypeuse| is a pair consisting of both the referenced :ref:`type index ` and the updated :ref:`identifier context ` including the parameter identifiers. -The following auxiliary notation filters out optional identifiers from parameters: +The resulting attribute of a |Ttypeuse| is a pair consisting of both the used :ref:`type index ` and the updated :ref:`identifier context ` including possible parameter identifiers. +The following auxiliary notation extracts optional identifiers from parameters: .. math:: \begin{array}{lcl@{\qquad\qquad}l} @@ -114,23 +64,32 @@ The following auxiliary notation filters out optional identifiers from parameter The :ref:`well-formedness ` condition on :math:`I'` ensures that the parameters do not contain duplicate identifier. +.. _text-typeuse-abbrev: + Abbreviations ............. -A |Ttypeuse| may also be replaced entirely by inline function :ref:`parameters ` and :ref:`result ` annotations. -In that case, the :ref:`type index ` of the first matching :ref:`type definition ` is automatically inserted. -If no matching definition exists - -.. todo:: fix +A |Ttypeuse| may also be replaced entirely by inline :ref:`parameter ` and :ref:`result ` declarations. +In that case, a :ref:`type index ` is automatically inserted: .. math:: \begin{array}{llclll} \production{type use} & - \text{(}~\text{func}~~\Tid^?~~\Ttypeuse~~\Tparam^\ast~~\Tresult_I~~\dots~\text{)} &\equiv& - \text{(}~\text{func}~~\Tid^?~~\Ttypeuse~~\Tparam^\ast~~\Tresult_I~~\dots~\text{)} \\ & - \text{(}~\text{func}~~\Tid^?~~\Ttypeuse~~\Tparam^\ast~~\Tresult_I~~\dots~\text{)} &\equiv& + (t_1{:}\Tparam)^\ast~~(t_2{:}\Tresult)^\ast &\equiv& + \text{(}~\text{type}~~x~\text{)}~~\Tparam^\ast~~\Tresult^\ast \\ \end{array} +where :math:`x` is the smallest existing :ref:`type index ` whose definition in the current module is the :ref:`function type ` :math:`[t_1^\ast] \to [t_2^\ast]`. +If no such index exists, then a new :ref:`type definition ` of the form + +.. math:: + \text{(}~\text{type}~~\text{(}~\text{func}~~\Tparam^\ast~~\Tresult~\text{)}~\text{)} + +is first inserted at the end of the module. + +.. note:: + Abbreviations are expanded in the order they appear, such that previously inserted type definitions are reused by consecutive expansions. + .. _text-import: .. index:: import, name, function type, table type, memory type, global type @@ -158,16 +117,23 @@ The descriptors in imports can bind a symbolic function, table, memory, or globa \end{array} +Abbreviations +............. + +As an abbreviation, imports may also be specified inline with :ref:`function `, :ref:`table `, :ref:`memory `, or :ref:`global ` definitions; see the respective sections. + + + .. _text-func: -.. index:: function, type index, function type +.. _text-local: +.. index:: function, type index, function type, identifier, local pair: text format; function + pair: text format; local Functions ~~~~~~~~~ -.. todo:: inline type - -Function definitions can bind a symbolic :ref:`function identifier `. +Function definitions can bind a symbolic :ref:`function identifier `, and :ref:`local identifiers ` for its :ref:`parameters ` and locals. .. math:: \begin{array}{llclll} @@ -181,7 +147,7 @@ Function definitions can bind a symbolic :ref:`function identifier `. &\Rightarrow& t \\ \end{array} -The definition of the local :ref:`identifier context ` :math:`I''` uses the following auxiliary notation to filter out optional identifiers from locals: +The definition of the local :ref:`identifier context ` :math:`I''` uses the following auxiliary notation to extract optional identifiers from locals: .. math:: \begin{array}{lcl@{\qquad\qquad}l} @@ -190,9 +156,15 @@ The definition of the local :ref:`identifier context ` :math:`I''` .. note:: - The :ref:`well-formedness ` condition on :math:`I'` ensures that parameters and locals do not contain duplicate identifier. + The :ref:`well-formedness ` condition on :math:`I''` ensures that parameters and locals do not contain duplicate identifiers. +.. _text-func-abbrev: +.. index:: import, name + pair: text format; import +.. index:: export, name, index, function index + pair: text format; export + Abbreviations ............. @@ -212,16 +184,16 @@ Functions can be defined as :ref:`imports ` or :ref:`exports `. \end{array} +.. _text-table-abbrev: +.. index:: import, name + pair: text format; import +.. index:: export, name, index, table index + pair: text format; export +.. index:: element, table index, function index + pair: text format; element + single: table; element + single: element; segment + Abbreviations ............. @@ -247,28 +229,28 @@ Tables can be defined as :ref:`imports ` or :ref:`exports ` can be given inline, in which case the limits of the table type are inferred from the length of the given element vector: +Moreover, an :ref:`element segment ` can be given inline, in which case the :ref:`limits ` of the :ref:`table type `are inferred from the length of the given segment: .. math:: \begin{array}{llclll} \production{module field} & - \text{(}~\text{table}~~\Tid^?~~\text{(}~\text{export}~~\Tname~\text{)}^?~~\Telemtype~~\text{(}~\text{elem}~~\Tvec(\Tfuncidx)~\text{)}~~\text{)} &\equiv& + \text{(}~\text{table}~~\Tid^?~~\text{(}~\text{export}~~\Tname~\text{)}^?~~\Telemtype~~\text{(}~\text{elem}~~x^n{:}\Tvec(\Tfuncidx)~\text{)}~~\text{)} &\equiv& \text{(}~\text{table}~~\Tid'~~\text{(}~\text{export}~~\Tname~\text{)}^?~~n~~n~~\Telemtype~\text{)}~~ \text{(}~\text{elem}~~\Tid'~~\text{(}~\text{i32.const}~~\text{0}~\text{)}~~\Tvec(\Tfuncidx)~\text{)} \\&&& \qquad - (n = |\Tvec(\Tfuncidx)|, \Tid' = \Tid^? \neq \epsilon \vee \Tid'~\mbox{fresh}) \\ + (\Tid' = \Tid^? \neq \epsilon \vee \Tid' \idfresh) \\ \end{array} .. _text-mem: -.. index:: memory, memory type +.. index:: memory, memory type, identifier pair: text format; memory Memories @@ -284,6 +266,16 @@ Memory definitions can bind a symbolic :ref:`memory identifier `. \end{array} +.. _text-mem-abbrev: +.. index:: import, name + pair: text format; import +.. index:: export, name, index, memory index + pair: text format; export +.. index:: data, memory, memory index, expression, byte, page size + pair: text format; data + single: memory; data + single: data; segment + Abbreviations ............. @@ -294,30 +286,28 @@ Memories can be defined as :ref:`imports ` or :ref:`exports ` can be given inline, in which case the limits of the table type are inferred from the length of the given string, rounded up to :ref:`page size `: +Moreover, a :ref:`data segment ` can be given inline, in which case the :ref:`limits ` of the :ref:`memory type ` are inferred from the length of the data, rounded up to :ref:`page size `: .. math:: \begin{array}{llclll} \production{module field} & - \text{(}~\text{memory}~~\Tid^?~~\text{(}~\text{export}~~\Tname~\text{)}^?~~\text{(}~\text{data}~~\Tstring~\text{)}~~\text{)} &\equiv& - \text{(}~\text{memory}~~\Tid'~~\text{(}~\text{export}~~\Tname~\text{)}^?~~n~~n~\text{)}~~ - \text{(}~\text{data}~~\Tid'~~\text{(}~\text{i32.const}~~\text{0}~\text{)}~~\Tstring~\text{)} + \text{(}~\text{memory}~~\Tid^?~~\text{(}~\text{export}~~\Tname~\text{)}^?~~\text{(}~\text{data}~~b^n{:}\Tdatastring~\text{)}~~\text{)} &\equiv& + \text{(}~\text{memory}~~\Tid'~~\text{(}~\text{export}~~\Tname~\text{)}^?~~m~~m~\text{)}~~ + \text{(}~\text{data}~~\Tid'~~\text{(}~\text{i32.const}~~\text{0}~\text{)}~~\Tdatastring~\text{)} \\&&& \qquad - (n = |\Tstring|, \Tid' = \Tid^? \neq \epsilon \vee \Tid'~\mbox{fresh}) \\ + (\Tid' = \Tid^? \neq \epsilon \vee \Tid' \idfresh, m = \F{ceil}(n / 64\F{Ki})) \\ \end{array} -.. todo:: length of data - .. _text-global: -.. index:: global, global type, expression +.. index:: global, global type, identifier, expression pair: text format; global Globals @@ -328,11 +318,17 @@ Global definitions can bind a symbolic :ref:`global identifier `. .. math:: \begin{array}{llclll} \production{global} & \Tglobal_I &::=& - \text{(}~\text{global}~~\Tid^?~~\X{gt}{:}\Tglobaltype~~(\X{in}{:}\Tinstr_I)^\ast~\text{)} - &\Rightarrow& \{ \TYPE~\X{gt}, \INIT~\X{in}^\ast~\END \} \\ + \text{(}~\text{global}~~\Tid^?~~\X{gt}{:}\Tglobaltype~~e{:}\Texpr_I~\text{)} + &\Rightarrow& \{ \TYPE~\X{gt}, \INIT~e \} \\ \end{array} +.. _text-global-abbrev: +.. index:: import, name + pair: text format; import +.. index:: export, name, index, global index + pair: text format; export + Abbreviations ............. @@ -343,11 +339,11 @@ Globals can be defined as :ref:`imports ` or :ref:`exports ` or :ref:`exports ` directly. + .. math:: \begin{array}{llclll} \production{export} & \Texport_I &::=& @@ -375,6 +373,12 @@ Exports \end{array} +Abbreviations +............. + +As an abbreviation, exports may also be specified inline with :ref:`function `, :ref:`table `, :ref:`memory `, or :ref:`global ` definitions; see the respective sections. + + .. _text-start: .. index:: start function, function index pair: text format; start function @@ -382,6 +386,8 @@ Exports Start Function ~~~~~~~~~~~~~~ +A :ref:`start function ` is defined in terms of its index. + .. math:: \begin{array}{llclll} \production{start function} & \Tstart_I &::=& @@ -389,6 +395,11 @@ Start Function &\Rightarrow& \{ \FUNC~x \} \\ \end{array} +.. note:: + At most one start function may occur in a module, + which is ensured by a suitable side condition on the |Tmodule| grammar. + + .. _text-elem: .. index:: element, table index, expression, function index @@ -405,8 +416,8 @@ When omitted, :math:`\T{0}` is assumed. .. math:: \begin{array}{llclll} \production{element segment} & \Telem_I &::=& - \text{(}~\text{elem}~~(x{:}\Ttableidx_I)^?~~\text{(}~\text{offset}~~(\X{in}{:}\Tinstr_I)^\ast~\text{)}~~y^\ast{:}\Tvec(\Tfuncidx_I)~\text{)} - &\Rightarrow& \{ \TABLE~x', \OFFSET~\X{in}^\ast~\END, \INIT~y^\ast \} \\ + \text{(}~\text{elem}~~(x{:}\Ttableidx_I)^?~~\text{(}~\text{offset}~~e{:}\Texpr_I~\text{)}~~y^\ast{:}\Tvec(\Tfuncidx_I)~\text{)} + &\Rightarrow& \{ \TABLE~x', \OFFSET~e, \INIT~y^\ast \} \\ &&&&& \qquad (x' = x^? \neq \epsilon \vee x' = 0) \\ \end{array} @@ -415,7 +426,14 @@ When omitted, :math:`\T{0}` is assumed. or a symbolic :ref:`table identifier ` resolving to the same value. +Abbreviations +............. + +As an abbreviation, element segments may also be specified inline with :ref:`table ` definitions; see the respective section. + + .. _text-data: +.. _text-datastring: .. index:: data, memory, memory index, expression, byte pair: text format; data single: memory; data @@ -426,13 +444,16 @@ Data Segments Data segments allow for an optional :ref:`memory index ` to identify the memory to initialize. When omitted, :math:`\T{0}` is assumed. +The data is written as a :ref:`string `, which may be split up into a possibly empty sequence of individual string literals. .. math:: \begin{array}{llclll} \production{data segment} & \Tdata_I &::=& - \text{(}~\text{data}~~(x{:}\Tmemidx_I)^?~~\text{(}~\text{offset}~~(\X{in}{:}\Tinstr_I)^\ast~\text{)}~~b^\ast{:}\Tstring~\text{)} - &\Rightarrow& \{ \MEM~x', \OFFSET~\X{in}^\ast~\END, \INIT~b^\ast \} \\ + \text{(}~\text{data}~~(x{:}\Tmemidx_I)^?~~\text{(}~\text{offset}~~e{:}\Texpr_I~\text{)}~~b^\ast{:}\Tdatastring~\text{)} + &\Rightarrow& \{ \MEM~x', \OFFSET~e, \INIT~b^\ast \} \\ &&&&& \qquad (x' = x^? \neq \epsilon \vee x' = 0) \\ + \production{data string} & \Tdatastring &::=& + (b^\ast{:}\Tstring)^\ast &\Rightarrow& \concat((b^\ast)^\ast) \\ \end{array} .. note:: @@ -440,21 +461,37 @@ When omitted, :math:`\T{0}` is assumed. or a symbolic :ref:`memory identifier ` resolving to the same value. +Abbreviations +............. + +As an abbreviation, data segments may also be specified inline with :ref:`memory ` definitions; see the respective section. + + .. _text-module: .. _text-modulebody: .. _text-modulefield: -.. index:: module, type definition, function type, function, table, memory, global, element, data, start function, import, export, context, version +.. index:: module, type definition, function type, function, table, memory, global, element, data, start function, import, export, identifier context, identifier, name section pair: text format; module + single: section; name Modules ~~~~~~~ +A module consists of a sequence of fields that can occur in any order. +All definitions and their respective bound :ref:`identifiers ` scope over the entire module, including the text preceding them. + +A module may optionally bind an :ref:`identifier ` that names the module. +The name serves a documentary role only. + +.. note:: + Tools may include the module name in the :ref:`name section ` of the :ref:`binary format `. + .. math:: \begin{array}{lll} \production{module} & \Tmodule & \begin{array}[t]{@{}clll} ::=& - \text{(}~\text{module}~~(m{:}\Tmodulefield_I)^\ast~\text{)} + \text{(}~\text{module}~~\Tid^?~~(m{:}\Tmodulefield_I)^\ast~\text{)} &\Rightarrow& \bigcompose m^\ast & (I = \bigcompose \F{idc}(\Tmodulefield)^\ast \idcwellformed) \\ \end{array} \\ @@ -474,60 +511,6 @@ Modules \end{array} \end{array} -.. math (commented out) - \production{module} & \Tmodule &::=& - \text{(}~\text{module}~~m{:}\Tmodulebody_I~\text{)} - &\Rightarrow& m - \qquad (I = \F{idc}(\Tmodulebody)~\mbox{well-formed}) \\ &&|& - m{:}\Tmodulebody_I \phantom{\text{(}~\text{module}~~~\text{)}} - &\Rightarrow& m - \qquad (I = \F{idc}(\Tmodulebody)~\mbox{well-formed}) \\ - \production{module body} & \Tmodulebody_I &::=& - (m{:}\Tmodulefield_I)^\ast &\Rightarrow& \{\}~(\compose~m)^\ast \\ - - \begin{array}{llcllll} - \production{module} & \Tmodule &::=& - \text{(}~\text{module}~~m{:}\Tmodulebody~\text{)} - \quad\Rightarrow\quad m \\ &&|& - m{:}\Tmodulebody \phantom{\text{(}~\text{module}~~~\text{)}} - \quad\Rightarrow\quad m \\ - \production{module body} & \Tmodulebody &::=& - (\functype{:}\Ttype)^\ast \\ &&& - (\import{:}\Timport_I)^\ast \\ &&& - (\func{:}\Tfunc_I)^\ast \\ &&& - (\table{:}\Ttable_I)^\ast \\ &&& - (\mem{:}\Tmem_I)^\ast \\ &&& - (\global{:}\Tglobal_I)^\ast \\ &&& - (\export{:}\Texport_I)^\ast \\ &&& - (\start{:}\Tstart_I)^? \\ &&& - (\elem{:}\Telem_I)^\ast \\ &&& - (\data{:}\Tdata_I)^\ast - \quad\Rightarrow\quad \\ &&&\qquad \{~ - \begin{array}[t]{@{}l@{}} - \TYPES~\functype^\ast, \\ - \FUNCS~\func^\ast, \\ - \TABLES~\table^\ast, \\ - \MEMS~\mem^\ast, \\ - \GLOBALS~\global^\ast, \\ - \ELEM~\elem^\ast, \\ - \DATA~\data^\ast, \\ - \START~\start^?, \\ - \IMPORTS~\import^\ast, \\ - \EXPORTS~\export^\ast ~\} \\ - \end{array} \\ &&& - \qquad (I = \{~ - \begin{array}[t]{@{}l@{}} - \TYPES~(\F{id}(\Ttype))^\ast, \\ - \FUNCS~\F{funcids}(\Timport^\ast)~(\F{id}(\Tfunc))^\ast, \\ - \TABLES~\F{tableids}(\Timport^\ast)~(\F{id}(\Ttable))^\ast, \\ - \MEMS~\F{memids}(\Timport^\ast)~(\F{id}(\Tmem))^\ast, \\ - \GLOBALS~\F{globalids}(\Timport^\ast)~(\F{id}(\Tglobal))^\ast, \\ - \LOCALS~\epsilon, \\ - \LABELS~\epsilon, - \TYPEDEFS~\functype^\ast ~\}~\mbox{well-formed}) \\ - \end{array} - \end{array} - Here, the notation :math:`\bigcompose r^\ast` is shorthand for :ref:`composing ` a sequence of :ref:`module ` or :ref:`identifier context ` records, respectively; if the sequence is empty, then all fields of the resulting record are empty. Moreover, the following restrictions are imposed on the composition of :ref:`modules `: :math:`m_1 \compose m_2` is defined if and only if @@ -545,12 +528,10 @@ Moreover, the following restrictions are imposed on the composition of :ref:`mod The definition of the initial :ref:`identifier context ` :math:`I` uses the following auxiliary definition which maps each relevant definition to a singular context with one (possibly empty) identifier: -.. todo:: |TYPEDEFS| - .. math:: \begin{array}{@{}lcl@{\qquad\qquad}l} - \F{idc}(\text{(}~\text{type}~\Tid^?~\dots~\text{)}) &=& - \{\TYPES~(\Tid^?)\} \\ + \F{idc}(\text{(}~\text{type}~\Tid^?~\X{ft}{:}\Tfunctype~\text{)}) &=& + \{\TYPES~(\Tid^?), \TYPEDEFS~\X{ft}\} \\ \F{idc}(\text{(}~\text{func}~\Tid^?~\dots~\text{)}) &=& \{\FUNCS~(\Tid^?)\} \\ \F{idc}(\text{(}~\text{table}~\Tid^?~\dots~\text{)}) &=& diff --git a/document/text/values.rst b/document/text/values.rst index 555460c526..805d468624 100644 --- a/document/text/values.rst +++ b/document/text/values.rst @@ -85,7 +85,7 @@ Floating-Point :ref:`Floating point ` values can be represented in either decimal or hexadecimal notation. The value of a literal must not lie outside the representable range of the corresponding `IEEE 754 `_ type -(that is, a numeric value must not overflow to :math:`\pm` infinity), +(that is, a numeric value must not overflow to :math:`\pm\mbox{infinity}`), but it may be rounded to the nearest representable value. .. note:: @@ -121,7 +121,7 @@ Furthermore, arbitrary NaN values may be expressed by providing an explicit payl z{:}\Thexfloat &\Rightarrow& b^\ast & (\ieee_N(z) = b^\ast) \\ &&|& s{:}\Tsign~\text{inf} &\Rightarrow& b^\ast & (\ieeeinf_N(s) = b^\ast) \\ &&|& s{:}\Tsign~\text{nan} &\Rightarrow& b^\ast & (\ieeenan_N(s, 0) = b^\ast) \\ &&|& - s{:}\Tsign~\text{nan\!:}~\text{0x}~n{:}\Thexnum &\Rightarrow& b^\ast & (\ieeenan_N(s, n) = b^\ast) \\ + s{:}\Tsign~\text{nan\verb|:|}~\text{0x}~n{:}\Thexnum &\Rightarrow& b^\ast & (\ieeenan_N(s, n) = b^\ast) \\ \end{array} .. todo:: IEEE encoding @@ -201,7 +201,8 @@ A name string must form a valid `UTF-8 \end{array} .. note:: - Strings that do not contain any uses of hexadecimal byte escapes are always valid names. + Presuming the source text is itself encoded correctly, + strings that do not contain any uses of hexadecimal byte escapes are always valid names. .. _text-id: @@ -247,7 +248,11 @@ Symbolic *identifiers* that stand in lieu of indices start with :math:`\text{$}` \text{\verb|~|} \\ \end{array} -.. math (commented out) - b \Rightarrow b - && (\hex{21} \leq b \leq \hex{7E} \wedge - b \notin \{\text{,}, \text{;}, \text{(}, \text{)}, \text{[}, \text{]}, \text{\{}, \text{\}}\}) \\ + +.. _text-id-fresh: + +Conventions +........... + +The expansion rule of some abbreviations require insertion of a *fresh* identifier. +That may be any syntactically valid identifier that does not already occur in the given source text. diff --git a/document/validation/modules.rst b/document/validation/modules.rst index a1e26da4a5..14123c1d0d 100644 --- a/document/validation/modules.rst +++ b/document/validation/modules.rst @@ -29,6 +29,7 @@ Limits :math:`\{ \MIN~n, \MAX~m^? \}` .. _valid-func: +.. _valid-local: .. index:: function, local, function index, local index, type index, function type, value type, expression, import pair: abstract syntax; function single: abstract syntax; function From bb3033178adbec321be7db946a79e4d5248bdd24 Mon Sep 17 00:00:00 2001 From: rossberg-chromium Date: Thu, 11 May 2017 16:44:09 +0200 Subject: [PATCH 15/30] Fix various xref and TeX bugs --- document/binary/values.rst | 2 +- document/execution/instructions.rst | 4 ++-- document/execution/runtime.rst | 2 +- document/math.def | 18 +++++++++++++++++- document/syntax/instructions.rst | 19 ++++++++++++++----- document/syntax/values.rst | 6 +++--- document/text/conventions.rst | 2 +- document/text/instructions.rst | 9 ++++----- document/text/lexical.rst | 13 +++++++------ document/text/types.rst | 2 ++ document/text/values.rst | 6 ++++-- document/validation/conventions.rst | 2 +- 12 files changed, 57 insertions(+), 28 deletions(-) diff --git a/document/binary/values.rst b/document/binary/values.rst index 5e2f5d4260..82577ab08f 100644 --- a/document/binary/values.rst +++ b/document/binary/values.rst @@ -122,7 +122,7 @@ Vectors Names ~~~~~ -:ref:`Names ` are encoded like a :ref:`vector ` of bytes containing the `Unicode `_ UTF-8 encoding of the name's code point sequence. +:ref:`Names ` are encoded like a :ref:`vector ` of bytes containing the `Unicode `_ UTF-8 encoding of the name's code point sequence. .. math:: \begin{array}{llclll@{\qquad}l} diff --git a/document/execution/instructions.rst b/document/execution/instructions.rst index 50cfc4d3ab..3188ae077b 100644 --- a/document/execution/instructions.rst +++ b/document/execution/instructions.rst @@ -914,7 +914,7 @@ Entering :math:`\instr^\ast` with label :math:`L` 1. Push :math:`L` to the stack. -2. :ref:`Jump ` to the start of the instruction sequence :math:`\instr^\ast`. +2. Jump to the start of the instruction sequence :math:`\instr^\ast`. .. note:: No formal reduction rule is needed for entering an instruction sequence, @@ -964,7 +964,7 @@ Invocation of :ref:`function address ` :math:`a` 1. Assert: due to :ref:`validation `, :math:`S.\FUNCS[a]` exists. -2. Let :math:`f` be the :ref:`function instance `, :math:`S.\FUNCS[a]`. +2. Let :math:`f` be the :ref:`function instance `, :math:`S.\FUNCS[a]`. 3. Assert: due to :ref:`validation `, :math:`f.\MODULE.\TYPES[f.\CODE.\TYPE]` exists. diff --git a/document/execution/runtime.rst b/document/execution/runtime.rst index d6e751a9ee..9d622a2fa1 100644 --- a/document/execution/runtime.rst +++ b/document/execution/runtime.rst @@ -403,7 +403,7 @@ and a reference to the function's own :ref:`module instance ` \{ \LOCALS~\val^\ast, \MODULE~\moduleinst\} \\ \end{array} -The values of the locals are mutated by respective :ref:`variable instructions `. +The values of the locals are mutated by respective :ref:`variable instructions `. Conventions diff --git a/document/math.def b/document/math.def index c73354dcac..a21a861418 100644 --- a/document/math.def +++ b/document/math.def @@ -28,6 +28,17 @@ .. |bigcompose| mathdef:: \xref{syntax/conventions}{syntax-record}{\bigoplus} +.. Lexical grammar, terminals + +.. |textl| mathdef:: \mbox{‘} +.. |textr| mathdef:: \mbox{’} +.. |text#1| mathdef:: \textl\mathtt{#1}\textr + +.. |Tcommentl| mathdef:: \text{{(}{;}} +.. |Tcommentr| mathdef:: \text{{;}{)}} +.. |Tcommentd| mathdef:: \text{{;}{;}} + + .. Lexical grammar, non-terminals .. |Tchar| mathdef:: \xref{text/lexical}{text-char}{\T{char}} @@ -50,7 +61,6 @@ .. |hex#1| mathdef:: \mathtt{0x#1} .. |unicode#1| mathdef:: \mathrm{U{+}#1} -.. |text#1| mathdef:: \mbox{‘}\mathtt{#1}\mbox{’} .. Values, non-terminals @@ -578,3 +588,9 @@ .. |signed| mathdef:: \xref{execution/numerics}{aux-signed}{\F{signed}} .. |extend| mathdef:: \xref{execution/numerics}{aux-extend}{\F{extend}} .. |wrap| mathdef:: \xref{execution/numerics}{aux-wrap}{\F{wrap}} + +.. todo... + +.. |ieee| mathdef:: \F{ieee} +.. |ieeeinf| mathdef:: \F{ieeeinf} +.. |ieeenan| mathdef:: \F{ieeenan} diff --git a/document/syntax/instructions.rst b/document/syntax/instructions.rst index 07bf174d83..afd5f694f8 100644 --- a/document/syntax/instructions.rst +++ b/document/syntax/instructions.rst @@ -221,7 +221,7 @@ The |TEELOCAL| instruction is like |SETLOCAL| but also returns its argument. Memory Instructions ~~~~~~~~~~~~~~~~~~~ -Instructions in this group are concerned with :ref:`linear memory `. +Instructions in this group are concerned with :ref:`linear memory `. .. math:: \begin{array}{llll} @@ -264,11 +264,20 @@ Both instructions operate in units of :ref:`page size `. all memory instructions implicitly operate on :ref:`memory ` :ref:`index ` :math:`0`. This restriction may be lifted in future versions. -The precise semantics of memory instructions is :ref:`described ` in the :ref:`Instruction ` section. - .. _syntax-instr-control: -.. _syntax-isntr-seq: +.. _syntax-instr-seq: +.. _syntax-nop: +.. _syntax-unreachable: +.. _syntax-block: +.. _syntax-loop: +.. _syntax-if: +.. _syntax-br: +.. _syntax-br_if: +.. _syntax-br_table: +.. _syntax-return: +.. _syntax-call: +.. _syntax-call_indirect: .. _syntax-label: .. index:: ! control instruction, ! structured control, ! label, ! block, ! branch, ! unwinding, result type, label index, function index, type index, vector pair: abstract syntax; instruction @@ -333,7 +342,7 @@ However, forward branches that target a control instruction with a non-empty res The |CALL| instruction invokes another function, consuming the necessary arguments from the stack and returning the result values of the call. The |CALLINDIRECT| instruction calls a function indirectly through an operand indexing into a :ref:`table `. Since tables may contain function elements of heterogeneous type |ANYFUNC|, -the callee is dynamically checked against the :ref:`function type ` indexed by the instruction's immediate, and the call aborted with a :ref:`trap ` if it does not match. +the callee is dynamically checked against the :ref:`function type ` indexed by the instruction's immediate, and the call aborted with a :ref:`trap ` if it does not match. .. note:: In the current version of WebAssembly, diff --git a/document/syntax/values.rst b/document/syntax/values.rst index d5a0cb4b3f..89ecfe8d54 100644 --- a/document/syntax/values.rst +++ b/document/syntax/values.rst @@ -60,7 +60,7 @@ Different classes of *integers* with different value ranges are distinguished by The latter class defines *uninterpreted* integers, whose signedness interpretation can vary depending on context. In the abstract syntax, they are represented as unsigned. -However, some operations :ref:`convert ` them to signed based on a 2's complement interpretation. +However, some operations :ref:`convert ` them to signed based on a 2's complement interpretation. Conventions @@ -119,9 +119,9 @@ Names *Names* are sequences of *scalar* `Unicode `_ *code points*. .. math:: - \begin{array}{llll} + \begin{array}{llclll} \production{name} & \name &::=& - \codepoint^\ast & (|\utf(\codepoint^\ast)| < 2^{32}) \\ + \codepoint^\ast & (|\utf8(\codepoint^\ast)| < 2^{32}) \\ \production{code point} & \codepoint &::=& \unicode{0000} ~|~ \dots ~|~ \unicode{D7FF} ~|~ \unicode{E000} ~|~ \dots ~|~ \unicode{10FFFF} \\ diff --git a/document/text/conventions.rst b/document/text/conventions.rst index adf4c5962a..0e1dd9c574 100644 --- a/document/text/conventions.rst +++ b/document/text/conventions.rst @@ -38,7 +38,7 @@ In order to distinguish symbols of the textual syntax from symbols of the abstra * Nonterminal symbols are written in typewriter font: :math:`\T{valtype}, \T{instr}`. -* Arbitrary :ref:`white space ` is allowed in any place where the grammar contains spaces, except where noted otherwise, such as the :ref:`lexical syntax `. +* Arbitrary :ref:`white space ` is allowed in any place where the grammar contains spaces, except where noted otherwise, such as the :ref:`lexical syntax `. * :math:`T^n` is a sequence of :math:`n\geq 0` iterations of :math:`T`. diff --git a/document/text/instructions.rst b/document/text/instructions.rst index 390ff54559..0cd3ae9efa 100644 --- a/document/text/instructions.rst +++ b/document/text/instructions.rst @@ -16,7 +16,7 @@ Both can also be written in :ref:`folded ` form. &\Rightarrow& \X{in} \\ \end{array} -In addition, as a syntactic abbreviation, instructions can be :ref:`folded` into S-expressions, as a means of grouping them visually. +In addition, as a syntactic abbreviation, instructions can be :ref:`folded ` into S-expressions, as a means of grouping them visually. .. _text-index: @@ -27,7 +27,6 @@ In addition, as a syntactic abbreviation, instructions can be :ref:`folded` into .. _text-globalidx: .. _text-localidx: .. _text-labelidx: -.. _text-label: .. index:: index, type index, function index, table index, memory index, global index, local index, label index pair: text format; type index pair: text format; function index @@ -74,7 +73,7 @@ Such identifiers are looked up in the suitable space of the :ref:`identifier con pair: text format; label index :ref:`Structured control instructions ` can be annotated with an optional symbolic :ref:`label identifier ` that can be used in place of the corresponding numeric :ref:`label index ` to reference the instruction. -:ref:`Labels ` are the only symbolic identifiers that can be defined locally in an :ref:`instruction sequence `. +:ref:`Labels ` are the only symbolic identifiers that can be defined locally in an instruction sequence. The following grammar handles the corresponding update to the :ref:`identifier context ` by producing a context with an additional label entry. .. math:: @@ -102,7 +101,7 @@ Control Instructions .. _text-loop: .. _text-if: -:ref:`Structured control instructions ` can bind an optional symbolic :ref:`label identifier `. +:ref:`Structured control instructions ` can bind an optional symbolic :ref:`label identifier `. The same identifier may optionally be repeated after the corresponding :math:`\T{end}` and :math:`\T{else}` pseudo instructions. .. math:: @@ -452,9 +451,9 @@ Numeric Instructions \end{array} +.. _text-foldedinstr: .. index:: ! folded instruction, S-expression - Folded Instructions ~~~~~~~~~~~~~~~~~~~ diff --git a/document/text/lexical.rst b/document/text/lexical.rst index a862a50ea7..2c8908dce7 100644 --- a/document/text/lexical.rst +++ b/document/text/lexical.rst @@ -1,3 +1,4 @@ +.. _text-lexical: .. index:: lexical format Lexical Format @@ -25,7 +26,7 @@ Characters are assumed to be represented as valid `Unicode ` or :ref:`string ` literals. -.. _text-stoken: +.. _text-token: .. index:: ! token, character, white space, comment, source text single: text format; token @@ -64,15 +65,15 @@ The allowed formatting characters correspond to a subset of the `ASCII ` is allowed. +hence no :ref:`white space ` is allowed. .. _text-sign: @@ -121,7 +121,7 @@ Furthermore, arbitrary NaN values may be expressed by providing an explicit payl z{:}\Thexfloat &\Rightarrow& b^\ast & (\ieee_N(z) = b^\ast) \\ &&|& s{:}\Tsign~\text{inf} &\Rightarrow& b^\ast & (\ieeeinf_N(s) = b^\ast) \\ &&|& s{:}\Tsign~\text{nan} &\Rightarrow& b^\ast & (\ieeenan_N(s, 0) = b^\ast) \\ &&|& - s{:}\Tsign~\text{nan\verb|:|}~\text{0x}~n{:}\Thexnum &\Rightarrow& b^\ast & (\ieeenan_N(s, n) = b^\ast) \\ + s{:}\Tsign~\text{nan{:}}~\text{0x}~n{:}\Thexnum &\Rightarrow& b^\ast & (\ieeenan_N(s, n) = b^\ast) \\ \end{array} .. todo:: IEEE encoding @@ -160,6 +160,8 @@ except when expressed with an *escape sequence*. Each character in a string literal represents the byte sequence corresponding to its `Unicode `_ UTF-8 encoding, except for hexadecimal escape sequences :math:`\text{\verb|\|}hh`, which represent raw bytes of the respective value. +.. todo - find replacement for the use of \verb, which isn't actually allowed in math mode, nor can be put into an \mbox + .. math:: \begin{array}{llclll@{\qquad\qquad}l} \production{string} & \Tstring &::=& diff --git a/document/validation/conventions.rst b/document/validation/conventions.rst index d1f3633574..b4f1e04cad 100644 --- a/document/validation/conventions.rst +++ b/document/validation/conventions.rst @@ -41,7 +41,7 @@ which collects relevant information about the surrounding :ref:`module ` for each :ref:`index space `, +In other words, a context contains a sequence of suitable :ref:`types ` for each :ref:`index space `, describing each defined entry in that space. Locals, labels and return type are only used for validating :ref:`instructions ` in :ref:`function bodies `, and are left empty elsewhere. The label stack is the only part of the context that changes as validation of an instruction sequence proceeds. From b184b661692cdf6a2ce1e886e5dcc7e05c70668e Mon Sep 17 00:00:00 2001 From: Andreas Rossberg Date: Thu, 11 May 2017 20:03:40 +0200 Subject: [PATCH 16/30] C&P typo --- document/text/conventions.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/document/text/conventions.rst b/document/text/conventions.rst index 0e1dd9c574..b2bdf6cd2f 100644 --- a/document/text/conventions.rst +++ b/document/text/conventions.rst @@ -8,7 +8,7 @@ The textual format for WebAssembly :ref:`modules ` is a rendering of th Like the :ref:`binary format `, the text format is defined by an *attribute grammar*. A text string is a well-formed description of a module if and only if it is generated by the grammar. -Each production of this grammar has at most one synthesized attribute: the abstract syntax that the respective byte sequence encodes. +Each production of this grammar has at most one synthesized attribute: the abstract syntax that the respective character sequence expresses. Thus, the attribute grammar implicitly defines a *parsing* function. Some productions also take a :ref:`context ` as an inherited attribute that records bound :ref:`identifers `. From ef40721cdc6a6638a53b5f09b20a0584a0a42a5e Mon Sep 17 00:00:00 2001 From: Andreas Rossberg Date: Thu, 11 May 2017 20:45:00 +0200 Subject: [PATCH 17/30] Typos --- document/text/conventions.rst | 2 +- document/text/instructions.rst | 10 ++++++---- document/text/modules.rst | 2 +- document/text/values.rst | 2 +- 4 files changed, 9 insertions(+), 7 deletions(-) diff --git a/document/text/conventions.rst b/document/text/conventions.rst index b2bdf6cd2f..1aafa04c50 100644 --- a/document/text/conventions.rst +++ b/document/text/conventions.rst @@ -88,7 +88,7 @@ In order to distinguish symbols of the textual syntax from symbols of the abstra Abbreviations ~~~~~~~~~~~~~ -In addition to the core grammar, which corresponds directly to the :ref:`abstract syntax `, the textual syntax also defines a number of *abbreviations* that can be used to improve convenience and readability. +In addition to the core grammar, which corresponds directly to the :ref:`abstract syntax `, the textual syntax also defines a number of *abbreviations* that can be used for convenience and readability. Abbreviations are defined by rewrite rules specifying their expansion into the core syntax: diff --git a/document/text/instructions.rst b/document/text/instructions.rst index 0cd3ae9efa..5c585ae7cc 100644 --- a/document/text/instructions.rst +++ b/document/text/instructions.rst @@ -5,7 +5,6 @@ Instructions ------------ Instructions are syntactically distinguished into *plain* and *structured* instructions. -Both can also be written in :ref:`folded ` form. .. math:: \begin{array}{llclll} @@ -16,7 +15,7 @@ Both can also be written in :ref:`folded ` form. &\Rightarrow& \X{in} \\ \end{array} -In addition, as a syntactic abbreviation, instructions can be :ref:`folded ` into S-expressions, as a means of grouping them visually. +In addition, as a syntactic abbreviation, instructions can be written in :ref:`folded ` form as S-expressions, to group them visually. .. _text-index: @@ -72,8 +71,8 @@ Such identifiers are looked up in the suitable space of the :ref:`identifier con .. index:: index, label index pair: text format; label index -:ref:`Structured control instructions ` can be annotated with an optional symbolic :ref:`label identifier ` that can be used in place of the corresponding numeric :ref:`label index ` to reference the instruction. -:ref:`Labels ` are the only symbolic identifiers that can be defined locally in an instruction sequence. +:ref:`Structured control instructions ` can be annotated with a symbolic :ref:`label identifier `. +They are the only symbolic identifiers that can be bound locally in an instruction sequence. The following grammar handles the corresponding update to the :ref:`identifier context ` by producing a context with an additional label entry. .. math:: @@ -217,6 +216,9 @@ Memory Instructions .. _text-current_memory: .. _text-grow_memory: +The offset and alignment immediates to memory instructions are optional. +The offset defaults to :math:`\T{0}`, the alignment to the storage size of the respective memory access, which is its *natural alignment*. + .. math:: \begin{array}{llclll} \production{memory argument} & \Tmemarg_N &::=& diff --git a/document/text/modules.rst b/document/text/modules.rst index bceecd215d..e67470d8c5 100644 --- a/document/text/modules.rst +++ b/document/text/modules.rst @@ -236,7 +236,7 @@ Tables can be defined as :ref:`imports ` or :ref:`exports ` can be given inline, in which case the :ref:`limits ` of the :ref:`table type `are inferred from the length of the given segment: +Moreover, an :ref:`element segment ` can be given inline, in which case the :ref:`limits ` of the :ref:`table type ` are inferred from the length of the given segment: .. math:: \begin{array}{llclll} diff --git a/document/text/values.rst b/document/text/values.rst index 091f33f123..4e1bcf5c25 100644 --- a/document/text/values.rst +++ b/document/text/values.rst @@ -256,5 +256,5 @@ Symbolic *identifiers* that stand in lieu of indices start with :math:`\text{$}` Conventions ........... -The expansion rule of some abbreviations require insertion of a *fresh* identifier. +The expansion rules of some abbreviations require insertion of a *fresh* identifier. That may be any syntactically valid identifier that does not already occur in the given source text. From a90213076341c666dcd989d556ed25bef9940b5c Mon Sep 17 00:00:00 2001 From: Andreas Rossberg Date: Fri, 12 May 2017 08:42:49 +0200 Subject: [PATCH 18/30] binji's comments --- document/math.def | 2 +- document/text/lexical.rst | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/document/math.def b/document/math.def index a21a861418..e68ada0cc1 100644 --- a/document/math.def +++ b/document/math.def @@ -539,7 +539,7 @@ .. Contexts, meta functions -.. |idfresh| mathdef:: ~\xref{text/conventions}{text-id-fresh}{\mbox{fresh}} +.. |idfresh| mathdef:: ~\xref{text/values}{text-id-fresh}{\mbox{fresh}} .. |idcwellformed| mathdef:: ~\xref{text/conventions}{text-context-wf}{\mbox{well-formed}} diff --git a/document/text/lexical.rst b/document/text/lexical.rst index 2c8908dce7..71d4f5d5fd 100644 --- a/document/text/lexical.rst +++ b/document/text/lexical.rst @@ -18,7 +18,7 @@ Characters are assumed to be represented as valid `Unicode Date: Mon, 15 May 2017 12:55:29 +0200 Subject: [PATCH 19/30] Update paper --- papers/pldi2017.pdf | Bin 2486556 -> 2501487 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/papers/pldi2017.pdf b/papers/pldi2017.pdf index ee581fc6a38b4ebac01994062cbb90b1ddd3047d..05d59de972abb7165fb09d012818323a1c3205ca 100644 GIT binary patch delta 129406 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

Jf>@6w-t!;+Hv9?vxpy4(*ry!;(t}a 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�+7jX&5OlOW)5Q+E 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

we5N*llFN!bt z{7`!?dr;pKIZo7TldpX1>#cN`A zP=!Yxt)GK8J*LO z`k#~UHlkfrs>)XQG`%MWnGM(HPIxuz=BXeIobv5Uyyz6JgeXi^?NzuyxiZF>Qfgd3V-vli$4H6mm)ql=sG{v)5rd4kgCM~ zLsh=LKoM1=_AS2Jjba;la`)R0%dglG(F;R4Px`493-k94F(B9a>;nBu!4d)MJbV7rk%7K1!U3k&odV&H@J$oFs z^S9ig<0b$m3q*=$^SOp2|9~n|RX8Ric~UqV;j(EIvLCm^4H&0{o{kP}u^u%O95kE} zhUC_7W?dYkxK0)M4pi>k)}G7poNN}D5LREuf^EO1itU~#kRh*l$tPH*{GM>bU#A2H zHXI5^Pt!z!CSsN-EY>bdIe5nw5uabDuwW-&6+_@QEW>V(-g5B0>DED@XNO6b zRm8$Wk{Cl-+;ip*Hcc5XeIRGLj_Vzyuo-{G#1x_YwK-M>a(A*Du*xdnp6mnFR2-eu z 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ᱷ_A2jE?%ML zuv*aEH{hve(tjvvPu$x{N^!;p7bWcu{2y3@9=ZI|t$TR|zHzDx?c23imUmTt+N?ij z9~k&%F$94Fod!XOP_<^KK?X!5z&czdIp_?|o&p5J(NKT{ zh!D7Q6d(y;_Cy&qND-Gt0pcTuqHqlW4R?bA#DL480yxDeL3}s~3J?>nmjXnOlcWJr zGlL<227mnDlnFR6D}fpW!PQcN_;K|VAV%C0C5Vd(gZYOqLE|D<5*G~P_!UgTqZS$ zmI#Tv!vYw;P7UJ4ZBc=kaeOo&PTT@u@81OwTo4Vgfe>n7RVfY7)}m=Z$~a0|fSra0 zprL6&?6@cRt6*vn6!(}GU{1kbaHR)S;LRh3KylNwAak53EkM?x17zf}1Li3)0_Z%W z13-gga07GzXq*fHXv}!f%c8Hj*A(vA(0Uz!9+Me1P1@>ts*>!023f+j2Xm@drbqNjQ)EG$pYvt z#b2^z0Zc{VbZG&R9e665`R@WQ912)~yRny-EZZ;4%GkydLFgNCstCgFzgR7kY1PE4jHjv_f?mxtEb1Z22b6^8gL4DnYO@~<%DA77dNXMhU|3e4JJ#hXNlfKy3pTX@>IdIKgL zlZ^b6XaeZJ3ebPQVg6^4rm!ey0+%P%9~r_Bz%hUK1o?Aa0P#nX0P2rbe>CG7^+maH z)m(tPei?}J;pVwO7bxLSFa!!kL7_MaZV=ahzFy@9r4plIxK(ZtHwO%Z-vRz3;3`1% z=MOLpjlke|c|gKgGz10((E871;8*DoBnmM5I1RXu1YjYc!C=6?2xwpgp*$1@j)&nm z9|VpsMOXqN8cw(v4MyUfdz=pnh5|_ahX(wKfuc{+ASl44$NAup|E$IS1q6bG!U1m| zV}u|fu#*B|c&q=z2L)h30MHW9FfjOW#Q+}$g(BobV}fZXp;9g(ASm7lXkN33OQ~ypawvTFc#nt2#Syo4gsSG;|K-}FglJZ9vRGERDu2f4}QGW zC^Vt(&`=;h39N>r3H=E?gUG2m}z-|B?3xe*^*nJ`N$U7z05N3PeJY z$m8h=1|y*e0w06H2n70s(MaH#)CqYQFcw4T6C@O<7XPsj??e;=c49FK0XexA13y6n zvgt$|q0tz8#Ropvf8oc2bpkFlz(R-&3UQ(m0&BsTK`_82+fifBsEHGy)DjE)dU$#?KNv&Ic67<1`>(5KzMU0np$CDB$_f2<-6)28cij zIIb8^1Mokl7>eI9{qU@dTnokRu+MiU@|1*#DkC?O{lBMAx;o)1Hi?*I*QqRs;}6hW5Y z`Ot(XC7ytp@m{g+PuS&j>&<`h-8> zC=?vuQ5}mJBpOY4^g@sr*vZXd5J0;BJ%9cULKFZGK_Ed;VDyRTM*;0IAzDEBAnXkw zD4+}wW(f)k^j!ZKjs4S+K_O^39N$tO+X>JM!3c931H+sUh=D^1{SNd;Cz=f?7ziT* zc~GGL024+l6apN+1i=LbaQXkBAx_X>a14~dbx@!n5u6b~X@o)00MdW({|A162q!pt zf%XFiIUx`M^qquCfQ-Q31OFF6D3B3I0(U}@81#Rt?VtV+=%In?O1Kyelq7;^1w4la z|LeQIu7hHLuIVHVL+DNz-X#R6!oXMjDgh z$ND%j01e1RfQHBaANXN#ppp_qD?mFDn1G8>aDwOuXc)p&gdtET@*SX||C@?<{ZJTC z%LtkcfQAC5q7zsRwAutmG!%wHqX|zo7#fKH6Ydy|L=l#B7zTv}j%flVK$}ijtASPz z=md`Q0k;t+3lb1-0*j^KtAA~2&lW-x&hw+ z!~T3z7BH5DC<0N7yo6E&D_v4iP*B0BTtX@$6wyEvbP0}DR+bm||7S53ke8?O^0x5w X_V={0rNSG5g2BkCL`5%YsZjkt5A#38 From 27b2ad5a14612d815aeebef58079706bd22724bc Mon Sep 17 00:00:00 2001 From: rossberg-chromium Date: Tue, 16 May 2017 09:45:02 +0200 Subject: [PATCH 20/30] [spec] Execution: conventions, runtime, instructions (#467) --- document/binary/instructions.rst | 32 +- document/binary/modules.rst | 73 +- document/binary/types.rst | 18 +- document/binary/values.rst | 26 +- document/execution/conventions.rst | 131 ++++ document/execution/index.rst | 4 +- document/execution/instructions.rst | 1062 ++++++++++++++++++++++++++ document/execution/modules.rst | 5 + document/execution/numerics.rst | 54 ++ document/execution/runtime.rst | 539 +++++++++++++ document/index.rst | 2 - document/instantiation/index.rst | 8 - document/math.def | 161 ++-- document/syntax/conventions.rst | 37 +- document/syntax/instructions.rst | 188 +++-- document/syntax/modules.rst | 52 +- document/syntax/types.rst | 52 +- document/syntax/values.rst | 25 +- document/validation/conventions.rst | 48 +- document/validation/instructions.rst | 94 +-- document/validation/modules.rst | 26 +- 21 files changed, 2256 insertions(+), 381 deletions(-) create mode 100644 document/execution/conventions.rst create mode 100644 document/execution/instructions.rst create mode 100644 document/execution/modules.rst create mode 100644 document/execution/numerics.rst create mode 100644 document/execution/runtime.rst delete mode 100644 document/instantiation/index.rst diff --git a/document/binary/instructions.rst b/document/binary/instructions.rst index 945b391e8b..fb64b6634c 100644 --- a/document/binary/instructions.rst +++ b/document/binary/instructions.rst @@ -37,7 +37,7 @@ Control Instructions .. math:: \begin{array}{llclll} - \production{instructions} & \Binstr &::=& + \production{instruction} & \Binstr &::=& \hex{00} &\Rightarrow& \UNREACHABLE \\ &&|& \hex{01} &\Rightarrow& \NOP \\ &&|& \hex{02}~~\X{rt}{:}\Bblocktype~~(\X{in}{:}\Binstr)^\ast~~\hex{0B} @@ -77,7 +77,7 @@ Parametric Instructions .. math:: \begin{array}{llclll} - \production{instructions} & \Binstr &::=& \dots \\ &&|& + \production{instruction} & \Binstr &::=& \dots \\ &&|& \hex{1A} &\Rightarrow& \DROP \\ &&|& \hex{1B} &\Rightarrow& \SELECT \\ \end{array} @@ -101,7 +101,7 @@ Variable Instructions .. math:: \begin{array}{llclll} - \production{instructions} & \Binstr &::=& \dots \\ &&|& + \production{instruction} & \Binstr &::=& \dots \\ &&|& \hex{20}~~x{:}\Blocalidx &\Rightarrow& \GETLOCAL~x \\ &&|& \hex{21}~~x{:}\Blocalidx &\Rightarrow& \SETLOCAL~x \\ &&|& \hex{22}~~x{:}\Blocalidx &\Rightarrow& \TEELOCAL~x \\ &&|& @@ -131,9 +131,9 @@ Each variant of :ref:`memory instruction ` is encoded with .. math:: \begin{array}{llclll} - \production{memory arguments} & \Bmemarg &::=& + \production{memory argument} & \Bmemarg &::=& a{:}\Bu32~~o{:}\Bu32 &\Rightarrow& \{ \ALIGN~a,~\OFFSET~o \} \\ - \production{instructions} & \Binstr &::=& \dots \\ &&|& + \production{instruction} & \Binstr &::=& \dots \\ &&|& \hex{28}~~m{:}\Bmemarg &\Rightarrow& \I32.\LOAD~m \\ &&|& \hex{29}~~m{:}\Bmemarg &\Rightarrow& \I64.\LOAD~m \\ &&|& \hex{2A}~~m{:}\Bmemarg &\Rightarrow& \F32.\LOAD~m \\ &&|& @@ -181,7 +181,7 @@ The |CONST| instructions are followed by the respective literal. .. math:: \begin{array}{llclll} - \production{instructions} & \Binstr &::=& \dots \\&&|& + \production{instruction} & \Binstr &::=& \dots \\&&|& \hex{41}~~n{:}\Bi32 &\Rightarrow& \I32.\CONST~n \\ &&|& \hex{42}~~n{:}\Bi64 &\Rightarrow& \I64.\CONST~n \\ &&|& \hex{43}~~z{:}\Bf32 &\Rightarrow& \F32.\CONST~z \\ &&|& @@ -195,7 +195,7 @@ All other numeric instructions are plain opcodes without any immediates. .. math:: \begin{array}{llclll} - \production{instructions} & \Binstr &::=& \dots && \phantom{thisshouldbeenough} \\&&|& + \production{instruction} & \Binstr &::=& \dots && \phantom{thisshouldbeenough} \\&&|& \hex{45} &\Rightarrow& \I32.\EQZ \\ &&|& \hex{46} &\Rightarrow& \I32.\EQ \\ &&|& \hex{47} &\Rightarrow& \I32.\NE \\ &&|& @@ -211,7 +211,7 @@ All other numeric instructions are plain opcodes without any immediates. .. math:: \begin{array}{llclll} - \phantom{\production{instructions}} & \phantom{\Binstr} &\phantom{::=}& \phantom{\dots} && \phantom{thisshouldbeenough} \\[-2ex] &&|& + \phantom{\production{instruction}} & \phantom{\Binstr} &\phantom{::=}& \phantom{\dots} && \phantom{thisshouldbeenough} \\[-2ex] &&|& \hex{50} &\Rightarrow& \I64.\EQZ \\ &&|& \hex{51} &\Rightarrow& \I64.\EQ \\ &&|& \hex{52} &\Rightarrow& \I64.\NE \\ &&|& @@ -227,7 +227,7 @@ All other numeric instructions are plain opcodes without any immediates. .. math:: \begin{array}{llclll} - \phantom{\production{instructions}} & \phantom{\Binstr} &\phantom{::=}& \phantom{\dots} && \phantom{thisshouldbeenough} \\[-2ex] &&|& + \phantom{\production{instruction}} & \phantom{\Binstr} &\phantom{::=}& \phantom{\dots} && \phantom{thisshouldbeenough} \\[-2ex] &&|& \hex{5B} &\Rightarrow& \F32.\EQ \\ &&|& \hex{5C} &\Rightarrow& \F32.\NE \\ &&|& \hex{5D} &\Rightarrow& \F32.\LT \\ &&|& @@ -238,7 +238,7 @@ All other numeric instructions are plain opcodes without any immediates. .. math:: \begin{array}{llclll} - \phantom{\production{instructions}} & \phantom{\Binstr} &\phantom{::=}& \phantom{\dots} && \phantom{thisshouldbeenough} \\[-2ex] &&|& + \phantom{\production{instruction}} & \phantom{\Binstr} &\phantom{::=}& \phantom{\dots} && \phantom{thisshouldbeenough} \\[-2ex] &&|& \hex{61} &\Rightarrow& \F64.\EQ \\ &&|& \hex{62} &\Rightarrow& \F64.\NE \\ &&|& \hex{63} &\Rightarrow& \F64.\LT \\ &&|& @@ -252,7 +252,7 @@ All other numeric instructions are plain opcodes without any immediates. .. math:: \begin{array}{llclll} - \phantom{\production{instructions}} & \phantom{\Binstr} &\phantom{::=}& \phantom{\dots} && \phantom{thisshouldbeenough} \\[-2ex] &&|& + \phantom{\production{instruction}} & \phantom{\Binstr} &\phantom{::=}& \phantom{\dots} && \phantom{thisshouldbeenough} \\[-2ex] &&|& \hex{67} &\Rightarrow& \I32.\CLZ \\ &&|& \hex{68} &\Rightarrow& \I32.\CTZ \\ &&|& \hex{69} &\Rightarrow& \I32.\POPCNT \\ &&|& @@ -275,7 +275,7 @@ All other numeric instructions are plain opcodes without any immediates. .. math:: \begin{array}{llclll} - \phantom{\production{instructions}} & \phantom{\Binstr} &\phantom{::=}& \phantom{\dots} && \phantom{thisshouldbeenough} \\[-2ex] &&|& + \phantom{\production{instruction}} & \phantom{\Binstr} &\phantom{::=}& \phantom{\dots} && \phantom{thisshouldbeenough} \\[-2ex] &&|& \hex{79} &\Rightarrow& \I64.\CLZ \\ &&|& \hex{7A} &\Rightarrow& \I64.\CTZ \\ &&|& \hex{7B} &\Rightarrow& \I64.\POPCNT \\ &&|& @@ -298,7 +298,7 @@ All other numeric instructions are plain opcodes without any immediates. .. math:: \begin{array}{llclll} - \phantom{\production{instructions}} & \phantom{\Binstr} &\phantom{::=}& \phantom{\dots} && \phantom{thisshouldbeenough} \\[-2ex] &&|& + \phantom{\production{instruction}} & \phantom{\Binstr} &\phantom{::=}& \phantom{\dots} && \phantom{thisshouldbeenough} \\[-2ex] &&|& \hex{8B} &\Rightarrow& \F32.\ABS \\ &&|& \hex{8C} &\Rightarrow& \F32.\NEG \\ &&|& \hex{8D} &\Rightarrow& \F32.\CEIL \\ &&|& @@ -317,7 +317,7 @@ All other numeric instructions are plain opcodes without any immediates. .. math:: \begin{array}{llclll} - \phantom{\production{instructions}} & \phantom{\Binstr} &\phantom{::=}& \phantom{\dots} && \phantom{thisshouldbeenough} \\[-2ex] &&|& + \phantom{\production{instruction}} & \phantom{\Binstr} &\phantom{::=}& \phantom{\dots} && \phantom{thisshouldbeenough} \\[-2ex] &&|& \hex{99} &\Rightarrow& \F64.\ABS \\ &&|& \hex{9A} &\Rightarrow& \F64.\NEG \\ &&|& \hex{9B} &\Rightarrow& \F64.\CEIL \\ &&|& @@ -338,7 +338,7 @@ All other numeric instructions are plain opcodes without any immediates. .. math:: \begin{array}{llclll} - \phantom{\production{instructions}} & \phantom{\Binstr} &\phantom{::=}& \phantom{\dots} && \phantom{thisshouldbeenough} \\[-2ex] &&|& + \phantom{\production{instruction}} & \phantom{\Binstr} &\phantom{::=}& \phantom{\dots} && \phantom{thisshouldbeenough} \\[-2ex] &&|& \hex{A7} &\Rightarrow& \I32.\WRAP\K{/}\I64 \\ &&|& \hex{A8} &\Rightarrow& \I32.\TRUNC\K{\_s/}\F32 \\ &&|& \hex{A9} &\Rightarrow& \I32.\TRUNC\K{\_u/}\F32 \\ &&|& @@ -380,6 +380,6 @@ Expressions .. math:: \begin{array}{llclll} - \production{instructions} & \Bexpr &::=& + \production{expression} & \Bexpr &::=& (\X{in}{:}\Binstr)^\ast~~\hex{0B} &\Rightarrow& \X{in}^\ast~\END \\ \end{array} diff --git a/document/binary/modules.rst b/document/binary/modules.rst index 4431f17841..bd20c8be73 100644 --- a/document/binary/modules.rst +++ b/document/binary/modules.rst @@ -40,13 +40,13 @@ All :ref:`indices ` are encoded with their respective |U32| value. .. math:: \begin{array}{llclll} - \production{type indices} & \Btypeidx &::=& x{:}\Bu32 &\Rightarrow& x \\ - \production{function indices} & \Bfuncidx &::=& x{:}\Bu32 &\Rightarrow& x \\ - \production{table indices} & \Btableidx &::=& x{:}\Bu32 &\Rightarrow& x \\ - \production{memory indices} & \Bmemidx &::=& x{:}\Bu32 &\Rightarrow& x \\ - \production{global indices} & \Bglobalidx &::=& x{:}\Bu32 &\Rightarrow& x \\ - \production{local indices} & \Blocalidx &::=& x{:}\Bu32 &\Rightarrow& x \\ - \production{label indices} & \Blabelidx &::=& l{:}\Bu32 &\Rightarrow& l \\ + \production{type index} & \Btypeidx &::=& x{:}\Bu32 &\Rightarrow& x \\ + \production{function index} & \Bfuncidx &::=& x{:}\Bu32 &\Rightarrow& x \\ + \production{table index} & \Btableidx &::=& x{:}\Bu32 &\Rightarrow& x \\ + \production{memory index} & \Bmemidx &::=& x{:}\Bu32 &\Rightarrow& x \\ + \production{global index} & \Bglobalidx &::=& x{:}\Bu32 &\Rightarrow& x \\ + \production{local index} & \Blocalidx &::=& x{:}\Bu32 &\Rightarrow& x \\ + \production{label index} & \Blabelidx &::=& l{:}\Bu32 &\Rightarrow& l \\ \end{array} @@ -69,7 +69,7 @@ The following parameterized grammar rule defines the generic structure of a sect .. math:: \begin{array}{llclll@{\qquad}l} - \production{sections} & \Bsection_N(\B{B}) &::=& + \production{section} & \Bsection_N(\B{B}) &::=& N{:}\Bbyte~~\X{size}{:}\Bu32~~\X{cont}{:}\B{B} &\Rightarrow& \X{cont} & (\X{size} = ||\B{B}||) \\ &&|& \epsilon &\Rightarrow& \epsilon @@ -98,7 +98,7 @@ Their contents consist of a :ref:`name ` further identifying the cu .. math:: \begin{array}{llclll} - \production{custom sections} & \Bcustomsec &::=& + \production{custom section} & \Bcustomsec &::=& \Bsection_0(\Bcustom) \\ \production{custom data} & \Bcustom &::=& \Bname~~\Bbyte^\ast \\ @@ -123,7 +123,7 @@ It decodes into a vector of :ref:`function types ` that represe .. math:: \begin{array}{llclll} - \production{type sections} & \Btypesec &::=& + \production{type section} & \Btypesec &::=& \X{ft}^\ast{:\,}\Bsection_1(\Bvec(\Bfunctype)) &\Rightarrow& \X{ft}^\ast \\ \end{array} @@ -143,12 +143,12 @@ It decodes into a vector of :ref:`imports ` that represent the |I .. math:: \begin{array}{llclll} - \production{import sections} & \Bimportsec &::=& + \production{import section} & \Bimportsec &::=& \X{im}^\ast{:}\Bsection_2(\Bvec(\Bimport)) &\Rightarrow& \X{im}^\ast \\ - \production{imports} & \Bimport &::=& + \production{import} & \Bimport &::=& \X{mod}{:}\Bname~~\X{nm}{:}\Bname~~d{:}\Bimportdesc &\Rightarrow& \{ \MODULE~\X{mod}, \NAME~\X{nm}, \DESC~d \} \\ - \production{import descriptions} & \Bimportdesc &::=& + \production{import description} & \Bimportdesc &::=& \hex{00}~~x{:}\Btypeidx &\Rightarrow& \FUNC~x \\ &&|& \hex{01}~~\X{tt}{:}\Btabletype &\Rightarrow& \TABLE~\X{tt} \\ &&|& \hex{02}~~\X{mt}{:}\Bmemtype &\Rightarrow& \MEM~\X{mt} \\ &&|& @@ -172,7 +172,7 @@ The |LOCALS| and |BODY| fields of the respective functions are encoded separatel .. math:: \begin{array}{llclll} - \production{function sections} & \Bfuncsec &::=& + \production{function section} & \Bfuncsec &::=& x^\ast{:}\Bsection_3(\Bvec(\Btypeidx)) &\Rightarrow& x^\ast \\ \end{array} @@ -192,9 +192,9 @@ It decodes into a vector of :ref:`tables ` that represent the |TAB .. math:: \begin{array}{llclll} - \production{table sections} & \Btablesec &::=& + \production{table section} & \Btablesec &::=& \X{tab}^\ast{:}\Bsection_4(\Bvec(\Btable)) &\Rightarrow& \X{tab}^\ast \\ - \production{tables} & \Btable &::=& + \production{table} & \Btable &::=& \X{tt}{:}\Btabletype &\Rightarrow& \{ \TYPE~\X{tt} \} \\ \end{array} @@ -214,9 +214,9 @@ It decodes into a vector of :ref:`memories ` that represent the |MEM .. math:: \begin{array}{llclll} - \production{memory sections} & \Bmemsec &::=& + \production{memory section} & \Bmemsec &::=& \X{mem}^\ast{:}\Bsection_5(\Bvec(\Bmem)) &\Rightarrow& \X{mem}^\ast \\ - \production{memories} & \Bmem &::=& + \production{memory} & \Bmem &::=& \X{mt}{:}\Bmemtype &\Rightarrow& \{ \TYPE~\X{mt} \} \\ \end{array} @@ -236,9 +236,9 @@ It decodes into a vector of :ref:`globals ` that represent the |G .. math:: \begin{array}{llclll} - \production{global sections} & \Bglobalsec &::=& + \production{global section} & \Bglobalsec &::=& \X{glob}^\ast{:}\Bsection_6(\Bvec(\Bglobal)) &\Rightarrow& \X{glob}^\ast \\ - \production{globals} & \Bglobal &::=& + \production{global} & \Bglobal &::=& \X{gt}{:}\Bglobaltype~~e{:}\Bexpr &\Rightarrow& \{ \TYPE~\X{gt}, \INIT~e \} \\ \end{array} @@ -259,12 +259,12 @@ It decodes into a vector of :ref:`exports ` that represent the |E .. math:: \begin{array}{llclll} - \production{export sections} & \Bexportsec &::=& + \production{export section} & \Bexportsec &::=& \X{ex}^\ast{:}\Bsection_7(\Bvec(\Bexport)) &\Rightarrow& \X{ex}^\ast \\ - \production{exports} & \Bexport &::=& + \production{export} & \Bexport &::=& \X{nm}{:}\Bname~~d{:}\Bexportdesc &\Rightarrow& \{ \NAME~\X{nm}, \DESC~d \} \\ - \production{export descriptions} & \Bexportdesc &::=& + \production{export description} & \Bexportdesc &::=& \hex{00}~~x{:}\Bfuncidx &\Rightarrow& \FUNC~x \\ &&|& \hex{01}~~x{:}\Btableidx &\Rightarrow& \TABLE~x \\ &&|& \hex{02}~~x{:}\Bmemidx &\Rightarrow& \MEM~x \\ &&|& @@ -288,9 +288,9 @@ It decodes into an optional :ref:`start function ` that represents .. math:: \begin{array}{llclll} - \production{start sections} & \Bstartsec &::=& + \production{start section} & \Bstartsec &::=& \X{st}^?{:}\Bsection_8(\Bstart) &\Rightarrow& \X{st}^? \\ - \production{start functions} & \Bstart &::=& + \production{start function} & \Bstart &::=& x{:}\Bfuncidx &\Rightarrow& \{ \FUNC~x \} \\ \end{array} @@ -312,9 +312,9 @@ It decodes into a vector of :ref:`element segments ` that represent .. math:: \begin{array}{llclll} - \production{element sections} & \Belemsec &::=& + \production{element section} & \Belemsec &::=& \X{seg}^\ast{:}\Bsection_9(\Bvec(\Belem)) &\Rightarrow& \X{seg} \\ - \production{element segments} & \Belem &::=& + \production{element segment} & \Belem &::=& x{:}\Btableidx~~e{:}\Bexpr~~y^\ast{:}\Bvec(\Bfuncidx) &\Rightarrow& \{ \TABLE~x, \OFFSET~e, \INIT~y^\ast \} \\ \end{array} @@ -352,13 +352,13 @@ denoting *count* locals of the same value type. .. math:: \begin{array}{llclll@{\qquad}l} - \production{code sections} & \Bcodesec &::=& + \production{code section} & \Bcodesec &::=& \X{code}^\ast{:}\Bsection_{10}(\Bvec(\Bcode)) &\Rightarrow& \X{code}^\ast \\ \production{code} & \Bcode &::=& \X{size}{:}\Bu32~~\X{code}{:}\Bfunc &\Rightarrow& \X{code} & (\X{size} = ||\Bfunc||) \\ - \production{functions} & \Bfunc &::=& + \production{function} & \Bfunc &::=& (t^\ast)^\ast{:}\Bvec(\Blocals)~~e{:}\Bexpr &\Rightarrow& \F{concat}((t^\ast)^\ast), e^\ast & (|\F{concat}((t^\ast)^\ast)| < 2^{32}) \\ @@ -392,9 +392,9 @@ It decodes into a vector of :ref:`data segments ` that represent th .. math:: \begin{array}{llclll} - \production{data sections} & \Bdatasec &::=& + \production{data section} & \Bdatasec &::=& \X{seg}^\ast{:}\Bsection_{11}(\Bvec(\Bdata)) &\Rightarrow& \X{seg} \\ - \production{data segments} & \Bdata &::=& + \production{data segment} & \Bdata &::=& x{:}\Bmemidx~~e{:}\Bexpr~~b^\ast{:}\Bvec(\Bbyte) &\Rightarrow& \{ \MEM~x, \OFFSET~e, \INIT~b^\ast \} \\ \end{array} @@ -425,7 +425,7 @@ The lengths of vectors produced by the (possibly empty) :ref:`function ` occurring in the binary format .. math:: \begin{array}{llclll@{\qquad\qquad}l} - \production{result types} & \Bblocktype &::=& + \production{result type} & \Bblocktype &::=& \hex{40} &\Rightarrow& [] \\ &&|& t{:}\Bvaltype &\Rightarrow& [t] \\ \end{array} @@ -64,7 +64,7 @@ Function Types .. math:: \begin{array}{llclll@{\qquad\qquad}l} - \production{function types} & \Bfunctype &::=& + \production{function type} & \Bfunctype &::=& \hex{60}~~t_1^\ast{:\,}\Bvec(\Bvaltype)~~t_2^\ast{:\,}\Bvec(\Bvaltype) &\Rightarrow& [t_1^\ast] \to [t_2^\ast] \\ \end{array} @@ -100,7 +100,7 @@ Memory Types .. math:: \begin{array}{llclll@{\qquad\qquad}l} - \production{memory types} & \Bmemtype &::=& + \production{memory type} & \Bmemtype &::=& \X{lim}{:}\Blimits &\Rightarrow& \X{lim} \\ \end{array} @@ -120,9 +120,9 @@ Table Types .. math:: \begin{array}{llclll} - \production{table types} & \Btabletype &::=& + \production{table type} & \Btabletype &::=& \X{et}{:}\Belemtype~~\X{lim}{:}\Blimits &\Rightarrow& \X{lim}~\X{et} \\ - \production{element types} & \Belemtype &::=& + \production{element type} & \Belemtype &::=& \hex{70} &\Rightarrow& \ANYFUNC \\ \end{array} @@ -141,9 +141,9 @@ Global Types .. math:: \begin{array}{llclll} - \production{global types} & \Bglobaltype &::=& + \production{global type} & \Bglobaltype &::=& t{:}\Bvaltype~~m{:}\Bmut &\Rightarrow& m~t \\ \production{mutability} & \Bmut &::=& - \hex{00} &\Rightarrow& \CONST \\ &&|& - \hex{01} &\Rightarrow& \MUT \\ + \hex{00} &\Rightarrow& \MCONST \\ &&|& + \hex{01} &\Rightarrow& \MVAR \\ \end{array} diff --git a/document/binary/values.rst b/document/binary/values.rst index b2abed9ffa..8a4366501c 100644 --- a/document/binary/values.rst +++ b/document/binary/values.rst @@ -19,7 +19,7 @@ Bytes .. math:: \begin{array}{llcll@{\qquad}l} - \production{bytes} & \Bbyte &::=& + \production{byte} & \Bbyte &::=& \hex{00} &\Rightarrow& \hex{00} \\ &&|&& \dots \\ &&|& \hex{FF} &\Rightarrow& \hex{FF} \\ @@ -49,9 +49,9 @@ As an additional constraint, the total number of bytes encoding a value of type .. math:: \begin{array}{llclll@{\qquad}l} - \production{unsigned integers} & \BuX{N} &::=& + \production{unsigned integer} & \BuX{N} &::=& n{:}\Bbyte &\Rightarrow& n & (n < 2^7 \wedge n < 2^N) \\ &&|& - n{:}\Bbyte~~m{:}\BuX{N-7} &\Rightarrow& + n{:}\Bbyte~~m{:}\BuX{(N\B{-7})} &\Rightarrow& 2^7\cdot m + (n-2^7) & (n \geq 2^7 \wedge N > 7) \\ \end{array} @@ -60,19 +60,19 @@ As an additional constraint, the total number of bytes encoding a value of type .. math:: \begin{array}{llclll@{\qquad}l} - \production{signed integers} & \BsX{N} &::=& + \production{signed integer} & \BsX{N} &::=& n{:}\Bbyte &\Rightarrow& n & (n < 2^6 \wedge n < 2^{N-1}) \\ &&|& n{:}\Bbyte &\Rightarrow& n-2^7 & (2^6 \leq n < 2^7 \wedge n \geq 2^7-2^{N-1}) \\ &&|& - n{:}\Bbyte~~m{:}\BsX{N-7} &\Rightarrow& + n{:}\Bbyte~~m{:}\BsX{(N\B{-7})} &\Rightarrow& 2^7\cdot m + (n-2^7) & (n \geq 2^7 \wedge N > 7) \\ \end{array} -:ref:`Uninterpreted integers ` are always encoded as signed integers. +:ref:`Uninterpreted integers ` are encoded as signed integers. .. math:: \begin{array}{llclll@{\qquad\qquad}l} - \production{uninterpreted integers} & \BiX{N} &::=& - n{:}\BsX{N} &\Rightarrow& n + \production{uninterpreted integer} & \BiX{N} &::=& + n{:}\BsX{N} &\Rightarrow& i & (n = \signed_{\iX{N}}(i)) \end{array} .. note:: @@ -99,7 +99,7 @@ Floating-Point .. math:: \begin{array}{llclll@{\qquad\qquad}l} - \production{floating-point numbers} & \BfX{N} &::=& + \production{floating-point number} & \BfX{N} &::=& b^\ast{:\,}\Bbyte^{N/8} &\Rightarrow& \F{reverse}(b^\ast) \\ \end{array} @@ -118,7 +118,7 @@ Vectors .. math:: \begin{array}{llclll@{\qquad\qquad}l} - \production{vectors} & \Bvec(\B{B}) &::=& + \production{vector} & \Bvec(\B{B}) &::=& n{:}\Bu32~~(x{:}\B{B})^n &\Rightarrow& x^n \\ \end{array} @@ -135,13 +135,13 @@ Names .. math:: \begin{array}{llclll@{\qquad}l} - \production{names} & \Bname &::=& + \production{name} & \Bname &::=& n{:}\Bu32~~(\X{uc}{:}\Bcodepoint)^\ast &\Rightarrow& \X{uc}^\ast & (|\Bcodepoint^\ast| = n) \\ - \production{code points} & \Bcodepoint &::=& + \production{code point} & \Bcodepoint &::=& \X{uv}{:}\Bcodeval_N &\Rightarrow& \X{uv} & (\X{uv} \geq N \wedge (\X{uv} < \unicode{D800} \vee \unicode{E000} \leq \X{uv} < \unicode{110000})) \\ - \production{code values} & \Bcodeval_N &::=& + \production{code value} & \Bcodeval_N &::=& b_1{:}\Bbyte &\Rightarrow& b_1 & (b_1 < \hex{80} \wedge N = \unicode{00}) \\ &&|& diff --git a/document/execution/conventions.rst b/document/execution/conventions.rst new file mode 100644 index 0000000000..81d1c9f276 --- /dev/null +++ b/document/execution/conventions.rst @@ -0,0 +1,131 @@ +.. index:: ! execution, stack, store + +Conventions +----------- + +WebAssembly code is *executed* when :ref:`instantiating ` a module or :ref:`invoking ` an :ref:`exported ` function on the resulting module :ref:`instance `. + +Execution behavior is defined in terms of an *abstract machine* that models the *program state*. +It includes a *stack*, which records operand values and control constructs, and an abstract *store* containing global state. + +For each instruction, there is a rule that specifies the effect of its execution on the program state. +Furthermore, there are rules describing the instantiation of a module. +As with :ref:`validation `, all rules are given in two *equivalent* forms: + +1. In *prose*, describing the execution in intuitive form. +2. In *formal notation*, describing the rule in mathematical form. + +.. note:: + As with validation, the prose and formal rules are equivalent, + so that understanding of the formal notation is *not* required to read this specification. + The formalism offers a more concise description in notation that is used widely in programming languages semantics and is readily amenable to mathematical proof. + +:ref:`Store `, :ref:`stack `, and other *runtime structure*, such as :ref:`module instances `, are made precise in terms of additional auxiliary :ref:`syntax `. + + +.. _exec-notation-textual: + +Prose Notation +~~~~~~~~~~~~~~ + +Execution is specified by stylised, step-wise rules for each :ref:`instruction ` of the :ref:`abstract syntax `. +The following conventions are adopted in stating these rules. + +* The execution rules implicitly assume a given :ref:`store ` :math:`S`. + +* The execution rules also assume the presence of an implicit :ref:`stack ` + that is modified by *pushing* or *popping* + :ref:`values `, :ref:`labels `, and :ref:`frames `. + +* Certain rules require the stack to contain at least one frame, + which is referred to as the *current* frame. + +* Both the store and the current frame are mutated by *replacing* some of its components. + Such replacement is assumed to apply globally. + +* The execution of an instruction may *trap*, + in which case the entire computation is aborted and no further modifications to the store are performed by it. (Other computations can still be initiated afterwards.) + +* The execution of an instruction may also end in a *jump* to a designated target, + which defines the next instruction to execute. + +* Execution can *enter* and *exit* :ref:`instruction sequences ` in a block-like fashion. + +* :ref:`Instruction sequences ` are implicitly executed in order, unless a trap or jump occurs. + +* In various places the rules contain *assertions* expressing crucial invariants about the program state, with indications why these are known to hold. + + +.. _exec-notation: +.. index:: ! reduction rules, ! configuration + +Formal Notation +~~~~~~~~~~~~~~~ + +.. note:: + This section gives a brief explanation of the notation for specifying execution formally. + For the interested reader, a more thorough introduction can be found in respective text books. [#tapl]_ + +The formal execution rules use a standard approach for specifying operational semantics, rendering them into *reduction rules*. +Every rule has the following general form: + +.. math:: + \X{configuration} \quad\stepto\quad \X{configuration} + +A *configuration* is a syntactic description of a program state. +Each rule specifies one *step* of execution. +As long as there is at most one reduction rule applicable to a given configuration, reduction -- and thereby execution -- is *deterministic*. +WebAssembly has only very few exceptions to this, which are noted explicitly in this specification. + +For WebAssembly, a configuration is a tuple :math:`(S; F; \instr^\ast)` consisting of the current :ref:`store ` :math:`S`, the :ref:`call frame ` :math:`F` of the current function, and the sequence of :ref:`instructions ` that is to be executed. + +To avoid unnecessary clutter, the store :math:`S` and the frame :math:`F` are omitted from reduction rules that do not touch them. + +There is no separate representation of the :ref:`stack `. +Instead, it is conveniently represented as part of the configuration's instruction sequence. +In particular, :ref:`values ` are defined to coincide with |CONST| instructions, +and a sequence of |CONST| instructions can be interpreted as an operand "stack". + +.. note:: + For example, the :ref:`reduction rule ` for the :math:`\I32.\ADD` instruction could be given as follows: + + .. math:: + (\I32.\CONST~n_1)~(\I32.\CONST~n_2)~\I32.\ADD \quad\stepto\quad (\I32.\CONST~(n_1 + n_2) \mod 2^{32}) + + Per this rule, two |CONST| instructions and the |ADD| instruction itself are removed from the instruction stream and replaced with one new |CONST| instruction. + This can be interpreted as popping two value off the stack and pushing the result. + + When no result is produced, an instruction reduces to the empty sequence: + + .. math:: + \NOP \quad\stepto\quad \epsilon + +:ref:`Labels