From 35bbfa571f81eff3d3b247facf9ce41348f77ec9 Mon Sep 17 00:00:00 2001 From: rossberg-chromium Date: Wed, 26 Apr 2017 08:45:51 +0200 Subject: [PATCH 001/672] [document] Specify binary format (#455) --- document/Makefile | 2 +- document/binary/conventions.rst | 98 ++++++ document/binary/index.rst | 2 +- document/binary/instructions.rst | 385 ++++++++++++++++++++++++ document/binary/modules.rst | 492 +++++++++++++++++++++++++++++++ document/binary/types.rst | 149 ++++++++++ document/binary/values.rst | 166 +++++++++++ document/math.def | 122 +++++++- document/syntax/modules.rst | 13 +- document/syntax/types.rst | 1 + document/syntax/values.rst | 26 +- document/validation/modules.rst | 8 +- 12 files changed, 1438 insertions(+), 26 deletions(-) create mode 100644 document/binary/conventions.rst create mode 100644 document/binary/instructions.rst create mode 100644 document/binary/modules.rst create mode 100644 document/binary/types.rst create mode 100644 document/binary/values.rst diff --git a/document/Makefile b/document/Makefile index 5df0df13..ea7776e1 100644 --- a/document/Makefile +++ b/document/Makefile @@ -92,7 +92,7 @@ html: for file in `ls $(BUILDDIR)/html/*/*.html`; \ do \ sed s:BASEDIR:..:g <$$file >$$file.out; \ - sed 's;MathJax.Hub.Config({TeX: {MAXBUFFER: 10*1024}})MathJax.Hub.Config({TeX: {MAXBUFFER: 30*1024}})$$file; \ rm -f $$file.out; \ done diff --git a/document/binary/conventions.rst b/document/binary/conventions.rst new file mode 100644 index 00000000..c48bc848 --- /dev/null +++ b/document/binary/conventions.rst @@ -0,0 +1,98 @@ +.. index:: ! binary format + +Conventions +----------- + +The binary format for WebAssembly :ref:`modules ` is a dense linear *encoding* of their :ref:`abstract syntax `. +[#compression]_ + +The format is defined by an *attribute grammar* whose only terminal symbols are :ref:`bytes `. +A byte sequence is a well-formed encoding 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 *decoding* function. + +Except for a few exceptions, the binary grammar closely mirrors the grammar of the abstract syntax. + +.. note:: + Some phrases of abstract syntax have multiple possible encodings in the binary format. + For example, numbers may be encoded as if they had optional leading zeros. + Implementations of decoders must support all possible alternatives; + implementations of encoders can pick any one allowed encoding. + +.. [#compression] + Additional encoding layers -- for example, introducing compression -- may be defined on top of the basic representation defined here. + However, such layers are outside the scope of the current specification. + + +.. _binary-grammar: +.. index:: grammar notation, notation, byte + single: binary format; grammar + pair: binary format; notation + +Grammar +~~~~~~~ + +The following conventions are adopted in defining grammar rules for the binary format. +They mirror the conventions used for :ref:`abstract syntax `. +In order to distinguish symbols of the binary syntax from symbols of the abstract syntax, typewriter font is adopted for the former. + +* Terminal symbols are :ref:`bytes ` expressed in hexadecimal notation: :math:`\hex{0F}`. + +* Nonterminal symbols are written in typewriter font: :math:`\B{valtype}, \B{instr}`. + +* :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.) + +* :math:`B^?` is an optional occurrence of :math:`B`. + (This is a shorthand for :math:`A^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`. + +* Productions are written :math:`\B{name} ::= B \Rightarrow A`, where :math:`A` is the attribute that is synthesized for :math:`\B{name}`, usually from attribute variables bound in :math:`B`. + +* 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:`binary grammar ` for :ref:`value types ` is given as follows: + + .. math:: + \begin{array}{llcll@{\qquad\qquad}l} + \production{value types} & \Bvaltype &::=& + \hex{7F} &\Rightarrow& \I32 \\ &&|& + \hex{7E} &\Rightarrow& \I64 \\ &&|& + \hex{7D} &\Rightarrow& \F32 \\ &&|& + \hex{7C} &\Rightarrow& \F64 \\ + \end{array} + + Consequently, the byte :math:`\hex{7F}` encodes the type |I32|, + :math:`\hex{7E}` encodes the type |I64|, and so forth. + No other byte value is allowed as the encoding of a value type. + + The :ref:`binary grammar ` for :ref:`limits ` is defined as follows: + + .. math:: + \begin{array}{llclll} + \production{limits} & \Blimits &::=& + \hex{00}~~n{:}\Bu32 &\Rightarrow& \{ \MIN~n, \MAX~\epsilon \} \\ &&|& + \hex{01}~~n{:}\Bu32~~m{:}\Bu32 &\Rightarrow& \{ \MIN~n, \MAX~m \} \\ + \end{array} + + That is, a limits pair is encoded as either the byte :math:`\hex{00}` followed by the encoding of a |U32| value, + or the byte :math:`\hex{01}` followed by two such encodings. + The variables :math:`n` and :math:`m` name the attributes of the respective |Bu32| 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. + +* :math:`||B||` is the length of the byte sequence generated from the production :math:`B` in a derivation. diff --git a/document/binary/index.rst b/document/binary/index.rst index ce1879dd..89a61d9c 100644 --- a/document/binary/index.rst +++ b/document/binary/index.rst @@ -9,5 +9,5 @@ Binary Format conventions values types - modules instructions + modules diff --git a/document/binary/instructions.rst b/document/binary/instructions.rst new file mode 100644 index 00000000..945b391e --- /dev/null +++ b/document/binary/instructions.rst @@ -0,0 +1,385 @@ +.. _binary-instr: +.. index:: instruction, ! opcode + +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. + +.. note:: + Gaps in the byte code ranges encoding instructions are reserved for future extensions. + + +.. _binary-instr-control: +.. index:: control instructions, structured control, label, block, branch, result type, label index, function index, type index, vector, polymorphism + pair: binary 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|. + +.. _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: + +.. math:: + \begin{array}{llclll} + \production{instructions} & \Binstr &::=& + \hex{00} &\Rightarrow& \UNREACHABLE \\ &&|& + \hex{01} &\Rightarrow& \NOP \\ &&|& + \hex{02}~~\X{rt}{:}\Bblocktype~~(\X{in}{:}\Binstr)^\ast~~\hex{0B} + &\Rightarrow& \BLOCK~\X{rt}~\X{in}^\ast~\END \\ &&|& + \hex{03}~~\X{rt}{:}\Bblocktype~~(\X{in}{:}\Binstr)^\ast~~\hex{0B} + &\Rightarrow& \LOOP~\X{rt}~\X{in}^\ast~\END \\ &&|& + \hex{04}~~\X{rt}{:}\Bblocktype~~(\X{in}{:}\Binstr)^\ast~~\hex{0B} + &\Rightarrow& \IF~\X{rt}~\X{in}^\ast~\ELSE~\epsilon~\END \\ &&|& + \hex{04}~~\X{rt}{:}\Bblocktype~~(\X{in}_1{:}\Binstr)^\ast~~ + \hex{05}~~(\X{in}_2{:}\Binstr)^\ast~~\hex{0B} + &\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{0F} &\Rightarrow& \RETURN \\ &&|& + \hex{10}~~x{:}\Bfuncidx &\Rightarrow& \CALL~x \\ &&|& + \hex{11}~~x{:}\Btypeidx &\Rightarrow& \CALLINDIRECT~x \\ + \end{array} + +.. note:: + The |ELSE| opcode :math:`\hex{05}` in the encoding of an |IF| instruction can be omitted if the following instruction sequence is empty. + + +.. _binary-instr-parametric: +.. index:: value type, polymorphism + pair: binary format; instruction + single: abstract syntax; instruction + +Parametric Instructions +~~~~~~~~~~~~~~~~~~~~~~~ + +:ref:`Parametric instructions ` are represented by single byte codes. + +.. _binary-drop: +.. _binary-select: + +.. math:: + \begin{array}{llclll} + \production{instructions} & \Binstr &::=& \dots \\ &&|& + \hex{1A} &\Rightarrow& \DROP \\ &&|& + \hex{1B} &\Rightarrow& \SELECT \\ + \end{array} + + +.. _binary-instr-variable: +.. index:: variable instructions, local index, global index + pair: binary format; instruction + single: abstract syntax; instruction + +Variable Instructions +~~~~~~~~~~~~~~~~~~~~~ + +:ref:`Variable instructions ` are represented by byte codes followed by the encoding of the respective :ref:`index `. + +.. _binary-get_local: +.. _binary-set_local: +.. _binary-tee_local: +.. _binary-get_global: +.. _binary-set_global: + +.. math:: + \begin{array}{llclll} + \production{instructions} & \Binstr &::=& \dots \\ &&|& + \hex{20}~~x{:}\Blocalidx &\Rightarrow& \GETLOCAL~x \\ &&|& + \hex{21}~~x{:}\Blocalidx &\Rightarrow& \SETLOCAL~x \\ &&|& + \hex{22}~~x{:}\Blocalidx &\Rightarrow& \TEELOCAL~x \\ &&|& + \hex{23}~~x{:}\Bglobalidx &\Rightarrow& \GETGLOBAL~x \\ &&|& + \hex{24}~~x{:}\Bglobalidx &\Rightarrow& \SETGLOBAL~x \\ + \end{array} + + +.. _binary-instr-memory: +.. _binary-memarg: +.. index:: memory instruction, memory index + pair: validation; instruction + single: abstract syntax; instruction + +Memory Instructions +~~~~~~~~~~~~~~~~~~~ + +Each variant of :ref:`memory instruction ` is encoded with a different byte code. Loads and stores are followed by the encoding of their |memarg| immediate. + +.. _binary-memarg: +.. _binary-load: +.. _binary-loadn: +.. _binary-store: +.. _binary-storen: +.. _binary-current_memory: +.. _binary-grow_memory: + +.. math:: + \begin{array}{llclll} + \production{memory arguments} & \Bmemarg &::=& + a{:}\Bu32~~o{:}\Bu32 &\Rightarrow& \{ \ALIGN~a,~\OFFSET~o \} \\ + \production{instructions} & \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 \\ &&|& + \hex{2B}~~m{:}\Bmemarg &\Rightarrow& \F64.\LOAD~m \\ &&|& + \hex{2C}~~m{:}\Bmemarg &\Rightarrow& \I32.\LOAD\K{8\_s}~m \\ &&|& + \hex{2D}~~m{:}\Bmemarg &\Rightarrow& \I32.\LOAD\K{8\_u}~m \\ &&|& + \hex{2E}~~m{:}\Bmemarg &\Rightarrow& \I32.\LOAD\K{16\_s}~m \\ &&|& + \hex{2F}~~m{:}\Bmemarg &\Rightarrow& \I32.\LOAD\K{16\_u}~m \\ &&|& + \hex{30}~~m{:}\Bmemarg &\Rightarrow& \I64.\LOAD\K{8\_s}~m \\ &&|& + \hex{31}~~m{:}\Bmemarg &\Rightarrow& \I64.\LOAD\K{8\_u}~m \\ &&|& + \hex{32}~~m{:}\Bmemarg &\Rightarrow& \I64.\LOAD\K{16\_s}~m \\ &&|& + \hex{33}~~m{:}\Bmemarg &\Rightarrow& \I64.\LOAD\K{16\_u}~m \\ &&|& + \hex{34}~~m{:}\Bmemarg &\Rightarrow& \I64.\LOAD\K{32\_s}~m \\ &&|& + \hex{35}~~m{:}\Bmemarg &\Rightarrow& \I64.\LOAD\K{32\_u}~m \\ &&|& + \hex{36}~~m{:}\Bmemarg &\Rightarrow& \I32.\STORE~m \\ &&|& + \hex{37}~~m{:}\Bmemarg &\Rightarrow& \I64.\STORE~m \\ &&|& + \hex{38}~~m{:}\Bmemarg &\Rightarrow& \F32.\STORE~m \\ &&|& + \hex{39}~~m{:}\Bmemarg &\Rightarrow& \F64.\STORE~m \\ &&|& + \hex{3A}~~m{:}\Bmemarg &\Rightarrow& \I32.\STORE\K{8}~m \\ &&|& + \hex{3B}~~m{:}\Bmemarg &\Rightarrow& \I32.\STORE\K{16}~m \\ &&|& + \hex{3C}~~m{:}\Bmemarg &\Rightarrow& \I64.\STORE\K{8}~m \\ &&|& + \hex{3D}~~m{:}\Bmemarg &\Rightarrow& \I64.\STORE\K{16}~m \\ &&|& + \hex{3E}~~m{:}\Bmemarg &\Rightarrow& \I64.\STORE\K{32}~m \\ &&|& + \hex{3F}~~\hex{00} &\Rightarrow& \CURRENTMEMORY \\ &&|& + \hex{40}~~\hex{00} &\Rightarrow& \GROWMEMORY \\ + \end{array} + +.. note:: + In future versions of WebAssembly, the additional zero bytes occurring in the encoding of the |CURRENTMEMORY| and |GROWMEMORY| instructions may be used to index additional memories. + + +.. _binary-instr-numeric: +.. index:: numeric instruction + pair: binary format; instruction + single: abstract syntax; instruction + +Numeric Instructions +~~~~~~~~~~~~~~~~~~~~ + +All variants of :ref:`numeric instructions ` are represented by separate byte codes. + +The |CONST| instructions are followed by the respective literal. + +.. _binary-const: + +.. math:: + \begin{array}{llclll} + \production{instructions} & \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 \\ &&|& + \hex{44}~~z{:}\Bf64 &\Rightarrow& \F64.\CONST~z \\ + \end{array} + +All other numeric instructions are plain opcodes without any immediates. + +.. _binary-testop: +.. _binary-relop: + +.. math:: + \begin{array}{llclll} + \production{instructions} & \Binstr &::=& \dots && \phantom{thisshouldbeenough} \\&&|& + \hex{45} &\Rightarrow& \I32.\EQZ \\ &&|& + \hex{46} &\Rightarrow& \I32.\EQ \\ &&|& + \hex{47} &\Rightarrow& \I32.\NE \\ &&|& + \hex{48} &\Rightarrow& \I32.\LT\K{\_s} \\ &&|& + \hex{49} &\Rightarrow& \I32.\LT\K{\_u} \\ &&|& + \hex{4A} &\Rightarrow& \I32.\GT\K{\_s} \\ &&|& + \hex{4B} &\Rightarrow& \I32.\GT\K{\_u} \\ &&|& + \hex{4C} &\Rightarrow& \I32.\LE\K{\_s} \\ &&|& + \hex{4D} &\Rightarrow& \I32.\LE\K{\_u} \\ &&|& + \hex{4E} &\Rightarrow& \I32.\GE\K{\_s} \\ &&|& + \hex{4F} &\Rightarrow& \I32.\GE\K{\_u} \\ + \end{array} + +.. math:: + \begin{array}{llclll} + \phantom{\production{instructions}} & \phantom{\Binstr} &\phantom{::=}& \phantom{\dots} && \phantom{thisshouldbeenough} \\[-2ex] &&|& + \hex{50} &\Rightarrow& \I64.\EQZ \\ &&|& + \hex{51} &\Rightarrow& \I64.\EQ \\ &&|& + \hex{52} &\Rightarrow& \I64.\NE \\ &&|& + \hex{53} &\Rightarrow& \I64.\LT\K{\_s} \\ &&|& + \hex{54} &\Rightarrow& \I64.\LT\K{\_u} \\ &&|& + \hex{55} &\Rightarrow& \I64.\GT\K{\_s} \\ &&|& + \hex{56} &\Rightarrow& \I64.\GT\K{\_u} \\ &&|& + \hex{57} &\Rightarrow& \I64.\LE\K{\_s} \\ &&|& + \hex{58} &\Rightarrow& \I64.\LE\K{\_u} \\ &&|& + \hex{59} &\Rightarrow& \I64.\GE\K{\_s} \\ &&|& + \hex{5A} &\Rightarrow& \I64.\GE\K{\_u} \\ + \end{array} + +.. math:: + \begin{array}{llclll} + \phantom{\production{instructions}} & \phantom{\Binstr} &\phantom{::=}& \phantom{\dots} && \phantom{thisshouldbeenough} \\[-2ex] &&|& + \hex{5B} &\Rightarrow& \F32.\EQ \\ &&|& + \hex{5C} &\Rightarrow& \F32.\NE \\ &&|& + \hex{5D} &\Rightarrow& \F32.\LT \\ &&|& + \hex{5E} &\Rightarrow& \F32.\GT \\ &&|& + \hex{5F} &\Rightarrow& \F32.\LE \\ &&|& + \hex{60} &\Rightarrow& \F32.\GE \\ + \end{array} + +.. math:: + \begin{array}{llclll} + \phantom{\production{instructions}} & \phantom{\Binstr} &\phantom{::=}& \phantom{\dots} && \phantom{thisshouldbeenough} \\[-2ex] &&|& + \hex{61} &\Rightarrow& \F64.\EQ \\ &&|& + \hex{62} &\Rightarrow& \F64.\NE \\ &&|& + \hex{63} &\Rightarrow& \F64.\LT \\ &&|& + \hex{64} &\Rightarrow& \F64.\GT \\ &&|& + \hex{65} &\Rightarrow& \F64.\LE \\ &&|& + \hex{66} &\Rightarrow& \F64.\GE \\ + \end{array} + +.. _binary-unop: +.. _binary-binop: + +.. math:: + \begin{array}{llclll} + \phantom{\production{instructions}} & \phantom{\Binstr} &\phantom{::=}& \phantom{\dots} && \phantom{thisshouldbeenough} \\[-2ex] &&|& + \hex{67} &\Rightarrow& \I32.\CLZ \\ &&|& + \hex{68} &\Rightarrow& \I32.\CTZ \\ &&|& + \hex{69} &\Rightarrow& \I32.\POPCNT \\ &&|& + \hex{6A} &\Rightarrow& \I32.\ADD \\ &&|& + \hex{6B} &\Rightarrow& \I32.\SUB \\ &&|& + \hex{6C} &\Rightarrow& \I32.\MUL \\ &&|& + \hex{6D} &\Rightarrow& \I32.\DIV\K{\_s} \\ &&|& + \hex{6E} &\Rightarrow& \I32.\DIV\K{\_u} \\ &&|& + \hex{6F} &\Rightarrow& \I32.\REM\K{\_s} \\ &&|& + \hex{70} &\Rightarrow& \I32.\REM\K{\_u} \\ &&|& + \hex{71} &\Rightarrow& \I32.\AND \\ &&|& + \hex{72} &\Rightarrow& \I32.\OR \\ &&|& + \hex{73} &\Rightarrow& \I32.\XOR \\ &&|& + \hex{74} &\Rightarrow& \I32.\SHL \\ &&|& + \hex{75} &\Rightarrow& \I32.\SHR\K{\_s} \\ &&|& + \hex{76} &\Rightarrow& \I32.\SHR\K{\_u} \\ &&|& + \hex{77} &\Rightarrow& \I32.\ROTL \\ &&|& + \hex{78} &\Rightarrow& \I32.\ROTR \\ + \end{array} + +.. math:: + \begin{array}{llclll} + \phantom{\production{instructions}} & \phantom{\Binstr} &\phantom{::=}& \phantom{\dots} && \phantom{thisshouldbeenough} \\[-2ex] &&|& + \hex{79} &\Rightarrow& \I64.\CLZ \\ &&|& + \hex{7A} &\Rightarrow& \I64.\CTZ \\ &&|& + \hex{7B} &\Rightarrow& \I64.\POPCNT \\ &&|& + \hex{7C} &\Rightarrow& \I64.\ADD \\ &&|& + \hex{7D} &\Rightarrow& \I64.\SUB \\ &&|& + \hex{7E} &\Rightarrow& \I64.\MUL \\ &&|& + \hex{7F} &\Rightarrow& \I64.\DIV\K{\_s} \\ &&|& + \hex{80} &\Rightarrow& \I64.\DIV\K{\_u} \\ &&|& + \hex{81} &\Rightarrow& \I64.\REM\K{\_s} \\ &&|& + \hex{82} &\Rightarrow& \I64.\REM\K{\_u} \\ &&|& + \hex{83} &\Rightarrow& \I64.\AND \\ &&|& + \hex{84} &\Rightarrow& \I64.\OR \\ &&|& + \hex{85} &\Rightarrow& \I64.\XOR \\ &&|& + \hex{86} &\Rightarrow& \I64.\SHL \\ &&|& + \hex{87} &\Rightarrow& \I64.\SHR\K{\_s} \\ &&|& + \hex{88} &\Rightarrow& \I64.\SHR\K{\_u} \\ &&|& + \hex{89} &\Rightarrow& \I64.\ROTL \\ &&|& + \hex{8A} &\Rightarrow& \I64.\ROTR \\ + \end{array} + +.. math:: + \begin{array}{llclll} + \phantom{\production{instructions}} & \phantom{\Binstr} &\phantom{::=}& \phantom{\dots} && \phantom{thisshouldbeenough} \\[-2ex] &&|& + \hex{8B} &\Rightarrow& \F32.\ABS \\ &&|& + \hex{8C} &\Rightarrow& \F32.\NEG \\ &&|& + \hex{8D} &\Rightarrow& \F32.\CEIL \\ &&|& + \hex{8E} &\Rightarrow& \F32.\FLOOR \\ &&|& + \hex{8F} &\Rightarrow& \F32.\TRUNC \\ &&|& + \hex{90} &\Rightarrow& \F32.\NEAREST \\ &&|& + \hex{91} &\Rightarrow& \F32.\SQRT \\ &&|& + \hex{92} &\Rightarrow& \F32.\ADD \\ &&|& + \hex{93} &\Rightarrow& \F32.\SUB \\ &&|& + \hex{94} &\Rightarrow& \F32.\MUL \\ &&|& + \hex{95} &\Rightarrow& \F32.\DIV \\ &&|& + \hex{96} &\Rightarrow& \F32.\FMIN \\ &&|& + \hex{97} &\Rightarrow& \F32.\FMAX \\ &&|& + \hex{98} &\Rightarrow& \F32.\COPYSIGN \\ + \end{array} + +.. math:: + \begin{array}{llclll} + \phantom{\production{instructions}} & \phantom{\Binstr} &\phantom{::=}& \phantom{\dots} && \phantom{thisshouldbeenough} \\[-2ex] &&|& + \hex{99} &\Rightarrow& \F64.\ABS \\ &&|& + \hex{9A} &\Rightarrow& \F64.\NEG \\ &&|& + \hex{9B} &\Rightarrow& \F64.\CEIL \\ &&|& + \hex{9C} &\Rightarrow& \F64.\FLOOR \\ &&|& + \hex{9D} &\Rightarrow& \F64.\TRUNC \\ &&|& + \hex{9E} &\Rightarrow& \F64.\NEAREST \\ &&|& + \hex{9F} &\Rightarrow& \F64.\SQRT \\ &&|& + \hex{A0} &\Rightarrow& \F64.\ADD \\ &&|& + \hex{A1} &\Rightarrow& \F64.\SUB \\ &&|& + \hex{A2} &\Rightarrow& \F64.\MUL \\ &&|& + \hex{A3} &\Rightarrow& \F64.\DIV \\ &&|& + \hex{A4} &\Rightarrow& \F64.\FMIN \\ &&|& + \hex{A5} &\Rightarrow& \F64.\FMAX \\ &&|& + \hex{A6} &\Rightarrow& \F64.\COPYSIGN \\ + \end{array} + +.. _binary-cvtop: + +.. math:: + \begin{array}{llclll} + \phantom{\production{instructions}} & \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 \\ &&|& + \hex{AA} &\Rightarrow& \I32.\TRUNC\K{\_s/}\F64 \\ &&|& + \hex{AB} &\Rightarrow& \I32.\TRUNC\K{\_u/}\F64 \\ &&|& + \hex{AC} &\Rightarrow& \I64.\EXTEND\K{\_s/}\I32 \\ &&|& + \hex{AD} &\Rightarrow& \I64.\EXTEND\K{\_u/}\I32 \\ &&|& + \hex{AE} &\Rightarrow& \I64.\TRUNC\K{\_s/}\F32 \\ &&|& + \hex{AF} &\Rightarrow& \I64.\TRUNC\K{\_u/}\F32 \\ &&|& + \hex{B0} &\Rightarrow& \I64.\TRUNC\K{\_s/}\F64 \\ &&|& + \hex{B1} &\Rightarrow& \I64.\TRUNC\K{\_u/}\F64 \\ &&|& + \hex{B2} &\Rightarrow& \F32.\CONVERT\K{\_s/}\I32 \\ &&|& + \hex{B3} &\Rightarrow& \F32.\CONVERT\K{\_u/}\I32 \\ &&|& + \hex{B4} &\Rightarrow& \F32.\CONVERT\K{\_s/}\I64 \\ &&|& + \hex{B5} &\Rightarrow& \F32.\CONVERT\K{\_u/}\I64 \\ &&|& + \hex{B6} &\Rightarrow& \F32.\DEMOTE\K{/}\F64 \\ &&|& + \hex{B7} &\Rightarrow& \F64.\CONVERT\K{\_s/}\I32 \\ &&|& + \hex{B8} &\Rightarrow& \F64.\CONVERT\K{\_u/}\I32 \\ &&|& + \hex{B9} &\Rightarrow& \F64.\CONVERT\K{\_s/}\I64 \\ &&|& + \hex{BA} &\Rightarrow& \F64.\CONVERT\K{\_u/}\I64 \\ &&|& + \hex{BB} &\Rightarrow& \F64.\PROMOTE\K{/}\F32 \\ &&|& + \hex{BC} &\Rightarrow& \I32.\REINTERPRET\K{/}\F32 \\ &&|& + \hex{BD} &\Rightarrow& \I64.\REINTERPRET\K{/}\F64 \\ &&|& + \hex{BE} &\Rightarrow& \F32.\REINTERPRET\K{/}\I32 \\ &&|& + \hex{BF} &\Rightarrow& \F64.\REINTERPRET\K{/}\I64 \\ + \end{array} + + +.. _binary-expr: +.. index:: expression + pair: binary format; expression + single: abstract syntax; expression + single: expression; constant + +Expressions +~~~~~~~~~~~ + +:ref:`Expressions ` are encoded by their instruction sequence terminated with an explicit :math:`\hex{0B}` opcode for |END|. + +.. math:: + \begin{array}{llclll} + \production{instructions} & \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 new file mode 100644 index 00000000..f520e7b8 --- /dev/null +++ b/document/binary/modules.rst @@ -0,0 +1,492 @@ +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(\Bfunctype^\ast) &\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(\Bimport^\ast) &\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(\Btypeidx^\ast) &\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(\Btable^\ast) &\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(\Bmem^\ast) &\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(\Bglobal^\ast) &\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(\Bexport^\ast) &\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(\Belem^\ast) &\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}(\Bcode^\ast) + &\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} + +.. math (commented out) + \begin{array}{llclll} + \production{code sections} & \Bcodesec_{\typeidx^n} &::=& + \f^\ast{:}\Bsection_{10}(\Bcode_{\typeidx}^n) + &\Rightarrow& \f^\ast \\ + \production{code} & \Bcode_{\typeidx} &::=& + \X{size}{:}\Bu32~~f{:}\Bfunc_{\typeidx} + &\Rightarrow& f \qquad\qquad (\X{size} = |\Bfunc|) \\ + \production{functions} & \Bfunc_{\typeidx} &::=& + (t^\ast)^\ast{:}\Bvec(\Blocals)~~e{:}\Bexpr &\Rightarrow& + \{ \TYPE~\typeidx, \LOCALS~\F{concat}((t^\ast)^\ast), \BODY~e^\ast \} \\ + \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}(\Bdata^\ast) &\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/binary/types.rst b/document/binary/types.rst new file mode 100644 index 00000000..33e5188b --- /dev/null +++ b/document/binary/types.rst @@ -0,0 +1,149 @@ +.. _binary-type: +.. index:: type + pair: binary format; type + single: abstract syntax; type + +Types +----- + +.. _binary-valtype: +.. index:: value type + pair: binary format; value type + single: abstract syntax; value type + +Value Types +~~~~~~~~~~~ + +:ref:`Value types ` are encoded by a single byte. + +.. math:: + \begin{array}{llclll@{\qquad\qquad}l} + \production{value types} & \Bvaltype &::=& + \hex{7F} &\Rightarrow& \I32 \\ &&|& + \hex{7E} &\Rightarrow& \I64 \\ &&|& + \hex{7D} &\Rightarrow& \F32 \\ &&|& + \hex{7C} &\Rightarrow& \F64 \\ + \end{array} + +.. note:: + In future versions of WebAssembly, value types may include types denoted by :ref:`type indices `. + Thus, the binary format for types corresponds to the encodings of small negative :math:`\xref{binary/values}{binary-sint}{\sX{}}` values, so that they can coexist with (positive) type indices. + + +.. _binary-resulttype: +.. _binary-blocktype: +.. index:: result type, value type + pair: binary format; result type + single: abstract syntax; result type + +Result Types +~~~~~~~~~~~~ + +The only :ref:`result types ` occurring in the binary format are the types of blocks. These are encoded in special compressed form, by either the byte :math:`\hex{40}` indicating the empty type or as a single :ref:`value type `. + +.. math:: + \begin{array}{llclll@{\qquad\qquad}l} + \production{result types} & \Bblocktype &::=& + \hex{40} &\Rightarrow& [] \\ &&|& + t{:}\Bvaltype &\Rightarrow& [t] \\ + \end{array} + +.. note:: + In future versions of WebAssembly, this scheme may be extended to support multiple results or more general block types. + + +.. _binary-functype: +.. index:: function type, value type, result type + pair: binary format; function type + single: abstract syntax; function type + +Function Types +~~~~~~~~~~~~~~ + +:ref:`Function types ` are encoded by the byte :math:`\hex{60}` followed by the respective :ref:`vectors ` of parameter and result types. + +.. math:: + \begin{array}{llclll@{\qquad\qquad}l} + \production{function types} & \Bfunctype &::=& + \hex{60}~~t_1^\ast{:\,}\Bvec(\Bvaltype)~~t_2^\ast{:\,}\Bvec(\Bvaltype) + &\Rightarrow& [t_1^\ast] \to [t_2^\ast] \\ + \end{array} + + +.. _binary-limits: +.. index:: limits + pair: binary format; limits + single: abstract syntax; limits + +Limits +~~~~~~ + +:ref:`Limits ` are encoded with a preceding flag indicating whether a maximum is present. + +.. math:: + \begin{array}{llclll} + \production{limits} & \Blimits &::=& + \hex{00}~~n{:}\Bu32 &\Rightarrow& \{ \MIN~n, \MAX~\epsilon \} \\ &&|& + \hex{01}~~n{:}\Bu32~~m{:}\Bu32 &\Rightarrow& \{ \MIN~n, \MAX~m \} \\ + \end{array} + + +.. _binary-memtype: +.. index:: memory type, limits, page size + single: binary format; memory type + pair: abstract syntax; memory type + +Memory Types +~~~~~~~~~~~~ + +:ref:`Memory types ` are encoded with their :ref:`limits `. + +.. math:: + \begin{array}{llclll@{\qquad\qquad}l} + \production{memory types} & \Bmemtype &::=& + \X{lim}{:}\Blimits &\Rightarrow& \X{lim} \\ + \end{array} + + +.. _syntax-tabletype: +.. _syntax-elemtype: +.. 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 +~~~~~~~~~~~ + +:ref:`Table types ` are encoded with their :ref:`limits ` and a constant byte indicating their :ref:`element type `. + +.. math:: + \begin{array}{llclll} + \production{table types} & \Btabletype &::=& + \X{et}{:}\Belemtype~~\X{lim}{:}\Blimits &\Rightarrow& \X{lim}~\X{et} \\ + \production{element types} & \Belemtype &::=& + \hex{70} &\Rightarrow& \ANYFUNC \\ + \end{array} + + +.. _binary-globaltype: +.. 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 +~~~~~~~~~~~~ + +:ref:`Global types ` are encoded by their :ref:`value type ` and a flag for their :ref:`mutability `. + +.. math:: + \begin{array}{llclll} + \production{global types} & \Bglobaltype &::=& + t{:}\Bvaltype~~m{:}\Bmut &\Rightarrow& m~t \\ + \production{mutability} & \Bmut &::=& + \hex{00} &\Rightarrow& \CONST \\ &&|& + \hex{01} &\Rightarrow& \MUT \\ + \end{array} diff --git a/document/binary/values.rst b/document/binary/values.rst new file mode 100644 index 00000000..b2abed9f --- /dev/null +++ b/document/binary/values.rst @@ -0,0 +1,166 @@ +.. _binary-value: +.. index:: value + binary: binary format; value + single: abstract syntax; value + +Values +------ + + +.. _binary-byte: +.. index:: byte + pair: binary encoding; byte + single: abstract syntax; byte + +Bytes +~~~~~ + +: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} + + +.. _binary-int: +.. _binary-sint: +.. _binary-uint: +.. index:: integer, unsigned integer, signed integer, uninterpreted integer + pair: binary format; integer + 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 +~~~~~~~~ + +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. diff --git a/document/math.def b/document/math.def index d8e23dba..d79f1fea 100644 --- a/document/math.def +++ b/document/math.def @@ -9,10 +9,12 @@ .. X - (multi-letter) variables / non-terminals .. F - functions .. K - keywords / terminals +.. B - binary grammar non-terminals .. |X| mathdef:: \mathit .. |F| mathdef:: \mathrm .. |K| mathdef:: \mathsf +.. |B| mathdef:: \mathtt .. Auxiliary definitions for grammars @@ -20,16 +22,15 @@ .. |production| mathdef:: \void -.. Values, terminals and auxiliary +.. Values, terminals -.. |hex#1| mathdef:: \F{0x#1} -.. |byte| mathdef:: \F{byte} -.. |bytes| mathdef:: \F{bytes} +.. |hex#1| mathdef:: \mathtt{0x#1} +.. |unicode#1| mathdef:: \mathrm{U{+}#1} .. Values, non-terminals -.. |by| mathdef:: \xref{syntax/values}{syntax-byte}{\X{byte}} +.. |byte| mathdef:: \xref{syntax/values}{syntax-byte}{\X{byte}} .. |uX#1| mathdef:: {\X{uint}_{#1}} .. |sX#1| mathdef:: {\X{sint}_{#1}} @@ -44,6 +45,8 @@ .. |u64| mathdef:: \xref{syntax/values}{syntax-int}{\uX{64}} .. |sN| mathdef:: \xref{syntax/values}{syntax-int}{\sX{N}} +.. |s8| mathdef:: \xref{syntax/values}{syntax-int}{\sX{8}} +.. |s16| mathdef:: \xref{syntax/values}{syntax-int}{\sX{16}} .. |s32| mathdef:: \xref{syntax/values}{syntax-int}{\sX{32}} .. |s64| mathdef:: \xref{syntax/values}{syntax-int}{\sX{64}} @@ -57,6 +60,42 @@ .. |vec| mathdef:: \xref{syntax/values}{syntax-vec}{\X{vec}} .. |name| mathdef:: \xref{syntax/values}{syntax-name}{\X{name}} +.. |codepoint| mathdef:: \xref{syntax/values}{syntax-name}{\X{codepoint}} + + +.. Values, binary non-terminals + +.. |Bbyte| mathdef:: \xref{binary/values}{binary-byte}{\B{byte}} + +.. |BuX#1| mathdef:: {\B{uint}_{#1}} +.. |BsX#1| mathdef:: {\B{sint}_{#1}} +.. |BiX#1| mathdef:: {\B{int}_{#1}} +.. |BfX#1| mathdef:: {\B{float}_{#1}} + +.. |BuN| mathdef:: \xref{binary/values}{binary-int}{\BuX{N}} +.. |Bu1| mathdef:: \xref{binary/values}{binary-int}{\BuX{1}} +.. |Bu8| mathdef:: \xref{binary/values}{binary-int}{\BuX{8}} +.. |Bu16| mathdef:: \xref{binary/values}{binary-int}{\BuX{16}} +.. |Bu32| mathdef:: \xref{binary/values}{binary-int}{\BuX{32}} +.. |Bu64| mathdef:: \xref{binary/values}{binary-int}{\BuX{64}} + +.. |BsN| mathdef:: \xref{binary/values}{binary-int}{\BsX{N}} +.. |Bs32| mathdef:: \xref{binary/values}{binary-int}{\BsX{32}} +.. |Bs64| mathdef:: \xref{binary/values}{binary-int}{\BsX{64}} + +.. |BiN| mathdef:: \xref{binary/values}{binary-int}{\BiX{N}} +.. |Bi32| mathdef:: \xref{binary/values}{binary-int}{\BiX{32}} +.. |Bi64| mathdef:: \xref{binary/values}{binary-int}{\BiX{64}} + +.. |BfN| mathdef:: \xref{binary/values}{binary-float}{\BfX{N}} +.. |Bf32| mathdef:: \xref{binary/values}{binary-float}{\BfX{32}} +.. |Bf64| mathdef:: \xref{binary/values}{binary-float}{\BfX{64}} + +.. |Bvec| mathdef:: \xref{binary/values}{binary-vec}{\B{vec}} +.. |Bname| mathdef:: \xref{binary/values}{binary-name}{\B{name}} +.. |Bcodepoint| mathdef:: \xref{binary/values}{binary-name}{\B{codepoint}} +.. |Bcodeval| mathdef:: \xref{binary/values}{binary-name}{\B{codeval}} +.. |Bcodecont| mathdef:: \xref{binary/values}{binary-name}{\B{cont}} .. Types, terminals @@ -87,6 +126,21 @@ .. |mut| mathdef:: \xref{syntax/types}{syntax-mut}{\X{mut}} +.. Types, binary non-terminals + +.. |Bvaltype| mathdef:: \xref{binary/types}{binary-valtype}{\B{valtype}} +.. |Bresulttype| mathdef:: \xref{binary/types}{binary-resulttype}{\B{resulttype}} +.. |Bblocktype| mathdef:: \xref{binary/types}{binary-blocktype}{\B{blocktype}} +.. |Bfunctype| mathdef:: \xref{binary/types}{binary-functype}{\B{functype}} +.. |Bglobaltype| mathdef:: \xref{binary/types}{binary-globaltype}{\B{globaltype}} +.. |Btabletype| mathdef:: \xref{binary/types}{binary-tabletype}{\B{tabletype}} +.. |Belemtype| mathdef:: \xref{binary/types}{binary-elemtype}{\B{elemtype}} +.. |Bmemtype| mathdef:: \xref{binary/types}{binary-memtype}{\B{memtype}} +.. |Bexterntype| mathdef:: \xref{binary/types}{binary-externtype}{\B{externtype}} +.. |Blimits| mathdef:: \xref{binary/types}{binary-limits}{\B{limits}} +.. |Bmut| mathdef:: \xref{binary/types}{binary-mut}{\B{mut}} + + .. Indices .. |typeidx| mathdef:: \xref{syntax/modules}{syntax-typeidx}{\X{typeidx}} @@ -97,6 +151,14 @@ .. |localidx| mathdef:: \xref{syntax/modules}{syntax-localidx}{\X{localidx}} .. |labelidx| mathdef:: \xref{syntax/modules}{syntax-labelidx}{\X{labelidx}} +.. |Btypeidx| mathdef:: \xref{binary/modules}{binary-typeidx}{\B{typeidx}} +.. |Bfuncidx| mathdef:: \xref{binary/modules}{binary-funcidx}{\B{funcidx}} +.. |Btableidx| mathdef:: \xref{binary/modules}{binary-tableidx}{\B{tableidx}} +.. |Bmemidx| mathdef:: \xref{binary/modules}{binary-memidx}{\B{memidx}} +.. |Bglobalidx| mathdef:: \xref{binary/modules}{binary-globalidx}{\B{globalidx}} +.. |Blocalidx| mathdef:: \xref{binary/modules}{binary-localidx}{\B{localidx}} +.. |Blabelidx| mathdef:: \xref{binary/modules}{binary-labelidx}{\B{labelidx}} + .. Modules, terminals @@ -146,9 +208,45 @@ .. |export| mathdef:: \xref{syntax/modules}{syntax-export}{\X{export}} .. |importdesc| mathdef:: \xref{syntax/modules}{syntax-importdesc}{\X{importdesc}} .. |exportdesc| mathdef:: \xref{syntax/modules}{syntax-exportdesc}{\X{exportdesc}} -.. |elem| mathdef:: \xref{syntax/modules}{syntax-elemseg}{\X{elem}} -.. |data| mathdef:: \xref{syntax/modules}{syntax-dataseg}{\X{data}} -.. |start| mathdef:: \xref{syntax/modules}{syntax-dataseg}{\X{start}} +.. |elem| mathdef:: \xref{syntax/modules}{syntax-elem}{\X{elem}} +.. |data| mathdef:: \xref{syntax/modules}{syntax-data}{\X{data}} +.. |start| mathdef:: \xref{syntax/modules}{syntax-start}{\X{start}} + + +.. Modules, binary non-terminals + +.. |Bmagic| mathdef:: \xref{binary/modules}{binary-magic}{\B{magic}} +.. |Bversion| mathdef:: \xref{binary/modules}{binary-version}{\B{version}} +.. |Bmodule| mathdef:: \xref{binary/modules}{binary-module}{\B{module}} +.. |Bsection| mathdef:: \xref{binary/modules}{binary-module}{\B{section}} +.. |Bcustomsec| mathdef:: \xref{binary/modules}{binary-customsec}{\B{customsec}} +.. |Btypesec| mathdef:: \xref{binary/modules}{binary-typesec}{\B{typesec}} +.. |Bfuncsec| mathdef:: \xref{binary/modules}{binary-funcsec}{\B{funcsec}} +.. |Bcodesec| mathdef:: \xref{binary/modules}{binary-codesec}{\B{codesec}} +.. |Btablesec| mathdef:: \xref{binary/modules}{binary-tablesec}{\B{tablesec}} +.. |Bmemsec| mathdef:: \xref{binary/modules}{binary-memsec}{\B{memsec}} +.. |Bglobalsec| mathdef:: \xref{binary/modules}{binary-globalsec}{\B{globalsec}} +.. |Bimportsec| mathdef:: \xref{binary/modules}{binary-importsec}{\B{importsec}} +.. |Bexportsec| mathdef:: \xref{binary/modules}{binary-exportsec}{\B{exportsec}} +.. |Belemsec| mathdef:: \xref{binary/modules}{binary-elemsec}{\B{elemsec}} +.. |Bdatasec| mathdef:: \xref{binary/modules}{binary-datasec}{\B{datasec}} +.. |Bstartsec| mathdef:: \xref{binary/modules}{binary-startseg}{\B{startsec}} +.. |Bcustom| mathdef:: \xref{binary/modules}{binary-customsec}{\B{custom}} +.. |Btype| mathdef:: \xref{binary/modules}{binary-type}{\B{type}} +.. |Bfunc| mathdef:: \xref{binary/modules}{binary-func}{\B{func}} +.. |Btable| mathdef:: \xref{binary/modules}{binary-table}{\B{table}} +.. |Bmem| mathdef:: \xref{binary/modules}{binary-mem}{\B{mem}} +.. |Bglobal| mathdef:: \xref{binary/modules}{binary-global}{\B{global}} +.. |Bimport| mathdef:: \xref{binary/modules}{binary-import}{\B{import}} +.. |Bexport| mathdef:: \xref{binary/modules}{binary-export}{\B{export}} +.. |Bimportdesc| mathdef:: \xref{binary/modules}{binary-importdesc}{\B{importdesc}} +.. |Bexportdesc| mathdef:: \xref{binary/modules}{binary-exportdesc}{\B{exportdesc}} +.. |Belem| mathdef:: \xref{binary/modules}{binary-elem}{\B{elem}} +.. |Bcode| mathdef:: \xref{binary/modules}{binary-code}{\B{code}} +.. |Blocal| mathdef:: \xref{binary/modules}{binary-local}{\B{local}} +.. |Blocals| mathdef:: \xref{binary/modules}{binary-local}{\B{locals}} +.. |Bdata| mathdef:: \xref{binary/modules}{binary-data}{\B{data}} +.. |Bstart| mathdef:: \xref{binary/modules}{binary-start}{\B{start}} .. Modules, meta functions @@ -247,3 +345,11 @@ .. |instr| mathdef:: \xref{syntax/instructions}{syntax-instr}{\X{instr}} .. |expr| mathdef:: \xref{syntax/instructions}{syntax-expr}{\X{expr}} + + +.. Instructions, binary non-terminals + +.. |Bmemarg| mathdef:: \xref{binary/instructions}{binary-memarg}{\B{memarg}} + +.. |Binstr| mathdef:: \xref{binary/instructions}{binary-instr}{\B{instr}} +.. |Bexpr| mathdef:: \xref{binary/instructions}{binary-expr}{\B{expr}} diff --git a/document/syntax/modules.rst b/document/syntax/modules.rst index 743c4d43..2b5036bd 100644 --- a/document/syntax/modules.rst +++ b/document/syntax/modules.rst @@ -1,5 +1,5 @@ .. _syntax-module: -.. index:: ! modules, type definition, function type, function, table, memory, global, element, data, start function, import, export +.. index:: ! module, type definition, function type, function, table, memory, global, element, data, start function, import, export pair: abstract syntax; module Modules @@ -89,7 +89,6 @@ Conventions .. _syntax-type: .. index:: ! type definition, type index pair: abstract syntax; type definition - single: type; definition Types ~~~~~ @@ -250,13 +249,13 @@ The |OFFSET| is given by a :ref:`constant ` :ref:`expression ` are zero bytes. +The initial contents of a :ref:`memory ` are zero bytes. The |DATA| component of a module defines a vector of *data segments* that initialize a range of memory at a given offset with a static vector of bytes. .. math:: \begin{array}{llll} \production{data segments} & \data &::=& - \{ \MEM~\memidx, \OFFSET~\expr, \INIT~\vec(\by) \} \\ + \{ \MEM~\memidx, \OFFSET~\expr, \INIT~\vec(\byte) \} \\ \end{array} The |OFFSET| is given by a :ref:`constant ` :ref:`expression `. @@ -273,11 +272,11 @@ The |OFFSET| is given by a :ref:`constant ` :ref:`expression ` of a *start function* that is automatically invoked when the module is :ref:`instantiated `, after tables and memories have been initialized. +The |START| component of a module optionally declares the :ref:`function index ` of a *start function* that is automatically invoked when the module is :ref:`instantiated `, after tables and memories have been initialized. .. math:: \begin{array}{llll} - \production{start function} & \start &::=& + \production{start functions} & \start &::=& \{ \FUNC~\funcidx \} \\ \end{array} @@ -342,7 +341,7 @@ Each import is identified by a two-level :ref:`name ` space, consis Importable definitions are :ref:`functions `, :ref:`tables `, :ref:`memories `, and :ref:`globals `. Each import is specified by a descriptor with a respective type that a definition provided during instantiation is required to match. -Every import defines an index in the respective :ref:`index space `. +Every import defines an index in the respective :ref:`index space `. In each index space, the indices of imports go before the first index of any definition contained in the module itself. .. note:: diff --git a/document/syntax/types.rst b/document/syntax/types.rst index a35fb4c9..262da63e 100644 --- a/document/syntax/types.rst +++ b/document/syntax/types.rst @@ -156,6 +156,7 @@ A table of that type thus contains references to functions of heterogeneous type .. _syntax-globaltype: +.. _syntax-mut: .. index:: ! global type, ! mutability, value type pair: abstract syntax; global type pair: abstract syntax; mutability diff --git a/document/syntax/values.rst b/document/syntax/values.rst index 1dc03f8b..60930433 100644 --- a/document/syntax/values.rst +++ b/document/syntax/values.rst @@ -18,7 +18,7 @@ In the abstract syntax they are represented as hexadecimal literals. .. math:: \begin{array}{llll} - \production{bytes} & \by &::=& + \production{bytes} & \byte &::=& \hex{00} ~|~ \dots ~|~ \hex{FF} \\ \end{array} @@ -28,7 +28,7 @@ Conventions * The meta variable :math:`b` range over bytes. -* The meta function :math:`\byte(n)` denotes the byte representing the natural number :math:`n < 256`. +* Bytes are sometimes interpreted as natural numbers :math:`n < 256`. .. _syntax-int: @@ -69,7 +69,7 @@ and when interpreted as signed, positive values :math:`n \geq 2^{N-1}` convert t Conventions ........... -* The meta variables :math:`m, n` range over unsigned integers. +* The meta variables :math:`m, n, i` range over integers. * Numbers may be denoted by simple arithmetics, as in the grammar above. @@ -86,7 +86,7 @@ Floating-Point .. math:: \begin{array}{llll} \production{floating-point numbers} & \fN &::=& - \by^{N/8} \\ + \byte^{N/8} \\ \end{array} The two possible sizes :math:`N` are 32 and 64. @@ -118,13 +118,25 @@ A vector can have at most :math:`2^{32}-1` elements. Names ~~~~~ -*Names* are vectors of bytes interpreted as character strings. +*Names* are sequences of *scalar* `Unicode `_ *code points*. .. math:: \begin{array}{llll} \production{names} & \name &::=& - \vec(\by) \\ + \codepoint^\ast \\ + \production{code points} & \codepoint &::=& + \unicode{0000} ~|~ \dots ~|~ \unicode{D7FF} ~|~ + \unicode{E000} ~|~ \dots ~|~ \unicode{10FFFF} \\ \end{array} .. todo:: - Unicode? + 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? + + +Convention +.......... + +* Code points are sometimes used interchangeably with natural numbers :math:`n < 1114112`. diff --git a/document/validation/modules.rst b/document/validation/modules.rst index faad5cd4..a1e26da4 100644 --- a/document/validation/modules.rst +++ b/document/validation/modules.rst @@ -9,6 +9,9 @@ Auxiliary Rules ~~~~~~~~~~~~~~~ .. _valid-limits: +.. index:: limits + pair: validation; limits + single: abstract syntax; limits Limits :math:`\{ \MIN~n, \MAX~m^? \}` ..................................... @@ -28,6 +31,7 @@ Limits :math:`\{ \MIN~n, \MAX~m^? \}` .. _valid-func: .. index:: function, local, function index, local index, type index, function type, value type, expression, import pair: abstract syntax; function + single: abstract syntax; function Functions ~~~~~~~~~ @@ -262,7 +266,7 @@ Start function declarations :math:`\start` are not classified by any type. .. _valid-export: .. index:: export, name, index, function index, table index, memory index, global index - validation: abstract syntax; export + pair: validation; export single: abstract syntax; export Exports @@ -444,7 +448,7 @@ Imports :math:`\import` and import descriptions :math:`\importdesc` are classifi .. _valid-module: -.. index:: modules, type definition, function type, function, table, memory, global, element, data, start function, import, export, context +.. index:: module, type definition, function type, function, table, memory, global, element, data, start function, import, export, context pair: validation; module single: abstract syntax; module From 5bf1ca2aadd6e5419f6ef350f1e7473fac4f2c00 Mon Sep 17 00:00:00 2001 From: rossberg-chromium Date: Thu, 27 Apr 2017 11:15:27 +0200 Subject: [PATCH 002/672] [spec] Fix binary section grammar --- document/binary/modules.rst | 35 ++++++++++------------------------- 1 file changed, 10 insertions(+), 25 deletions(-) diff --git a/document/binary/modules.rst b/document/binary/modules.rst index f520e7b8..4431f178 100644 --- a/document/binary/modules.rst +++ b/document/binary/modules.rst @@ -124,7 +124,7 @@ It decodes into a vector of :ref:`function types ` that represe .. math:: \begin{array}{llclll} \production{type sections} & \Btypesec &::=& - \X{ft}^\ast{:\,}\Bsection_1(\Bfunctype^\ast) &\Rightarrow& \X{ft}^\ast \\ + \X{ft}^\ast{:\,}\Bsection_1(\Bvec(\Bfunctype)) &\Rightarrow& \X{ft}^\ast \\ \end{array} @@ -144,7 +144,7 @@ It decodes into a vector of :ref:`imports ` that represent the |I .. math:: \begin{array}{llclll} \production{import sections} & \Bimportsec &::=& - \X{im}^\ast{:}\Bsection_2(\Bimport^\ast) &\Rightarrow& \X{im}^\ast \\ + \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 \} \\ @@ -173,7 +173,7 @@ The |LOCALS| and |BODY| fields of the respective functions are encoded separatel .. math:: \begin{array}{llclll} \production{function sections} & \Bfuncsec &::=& - x^\ast{:}\Bsection_3(\Btypeidx^\ast) &\Rightarrow& x^\ast \\ + x^\ast{:}\Bsection_3(\Bvec(\Btypeidx)) &\Rightarrow& x^\ast \\ \end{array} @@ -193,7 +193,7 @@ It decodes into a vector of :ref:`tables ` that represent the |TAB .. math:: \begin{array}{llclll} \production{table sections} & \Btablesec &::=& - \X{tab}^\ast{:}\Bsection_4(\Btable^\ast) &\Rightarrow& \X{tab}^\ast \\ + \X{tab}^\ast{:}\Bsection_4(\Bvec(\Btable)) &\Rightarrow& \X{tab}^\ast \\ \production{tables} & \Btable &::=& \X{tt}{:}\Btabletype &\Rightarrow& \{ \TYPE~\X{tt} \} \\ \end{array} @@ -215,7 +215,7 @@ It decodes into a vector of :ref:`memories ` that represent the |MEM .. math:: \begin{array}{llclll} \production{memory sections} & \Bmemsec &::=& - \X{mem}^\ast{:}\Bsection_5(\Bmem^\ast) &\Rightarrow& \X{mem}^\ast \\ + \X{mem}^\ast{:}\Bsection_5(\Bvec(\Bmem)) &\Rightarrow& \X{mem}^\ast \\ \production{memories} & \Bmem &::=& \X{mt}{:}\Bmemtype &\Rightarrow& \{ \TYPE~\X{mt} \} \\ \end{array} @@ -237,7 +237,7 @@ It decodes into a vector of :ref:`globals ` that represent the |G .. math:: \begin{array}{llclll} \production{global sections} & \Bglobalsec &::=& - \X{glob}^\ast{:}\Bsection_6(\Bglobal^\ast) &\Rightarrow& \X{glob}^\ast \\ + \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 \} \\ @@ -260,7 +260,7 @@ It decodes into a vector of :ref:`exports ` that represent the |E .. math:: \begin{array}{llclll} \production{export sections} & \Bexportsec &::=& - \X{ex}^\ast{:}\Bsection_7(\Bexport^\ast) &\Rightarrow& \X{ex}^\ast \\ + \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 \} \\ @@ -313,7 +313,7 @@ It decodes into a vector of :ref:`element segments ` that represent .. math:: \begin{array}{llclll} \production{element sections} & \Belemsec &::=& - \X{seg}^\ast{:}\Bsection_9(\Belem^\ast) &\Rightarrow& \X{seg} \\ + \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 \} \\ @@ -353,7 +353,7 @@ denoting *count* locals of the same value type. .. math:: \begin{array}{llclll@{\qquad}l} \production{code sections} & \Bcodesec &::=& - \X{code}^\ast{:}\Bsection_{10}(\Bcode^\ast) + \X{code}^\ast{:}\Bsection_{10}(\Bvec(\Bcode)) &\Rightarrow& \X{code}^\ast \\ \production{code} & \Bcode &::=& \X{size}{:}\Bu32~~\X{code}{:}\Bfunc @@ -366,21 +366,6 @@ denoting *count* locals of the same value type. n{:}\Bu32~~t{:}\Bvaltype &\Rightarrow& t^n \\ \end{array} -.. math (commented out) - \begin{array}{llclll} - \production{code sections} & \Bcodesec_{\typeidx^n} &::=& - \f^\ast{:}\Bsection_{10}(\Bcode_{\typeidx}^n) - &\Rightarrow& \f^\ast \\ - \production{code} & \Bcode_{\typeidx} &::=& - \X{size}{:}\Bu32~~f{:}\Bfunc_{\typeidx} - &\Rightarrow& f \qquad\qquad (\X{size} = |\Bfunc|) \\ - \production{functions} & \Bfunc_{\typeidx} &::=& - (t^\ast)^\ast{:}\Bvec(\Blocals)~~e{:}\Bexpr &\Rightarrow& - \{ \TYPE~\typeidx, \LOCALS~\F{concat}((t^\ast)^\ast), \BODY~e^\ast \} \\ - \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. @@ -408,7 +393,7 @@ It decodes into a vector of :ref:`data segments ` that represent th .. math:: \begin{array}{llclll} \production{data sections} & \Bdatasec &::=& - \X{seg}^\ast{:}\Bsection_{11}(\Bdata^\ast) &\Rightarrow& \X{seg} \\ + \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 \} \\ From 2fa62739e6dc81797bbbac3eb9028b368b55bf42 Mon Sep 17 00:00:00 2001 From: rossberg-chromium Date: Fri, 5 May 2017 15:03:24 +0200 Subject: [PATCH 003/672] Represent all names in UTF-8 (#454) --- interpreter/host/import.ml | 5 +-- interpreter/host/import.mli | 4 +-- interpreter/host/import/env.ml | 2 +- interpreter/host/import/spectest.ml | 2 +- interpreter/host/js.ml | 23 +++++++------ interpreter/host/main.ml | 4 +-- interpreter/host/run.ml | 22 +++++++----- interpreter/spec/ast.ml | 7 ++-- interpreter/spec/decode.ml | 13 +++++--- interpreter/spec/encode.ml | 7 ++-- interpreter/spec/instance.ml | 2 +- interpreter/spec/utf8.ml | 42 +++++++++++++++++++++++ interpreter/spec/utf8.mli | 4 +++ interpreter/spec/valid.ml | 2 +- interpreter/text/arrange.ml | 15 +++++---- interpreter/text/parser.mly | 20 +++++++---- interpreter/text/script.ml | 6 ++-- interpreter/util/lib.ml | 52 +++++++++++++++++------------ interpreter/util/lib.mli | 2 ++ interpreter/winmake.bat | 6 ++-- 20 files changed, 162 insertions(+), 78 deletions(-) create mode 100644 interpreter/spec/utf8.ml create mode 100644 interpreter/spec/utf8.mli diff --git a/interpreter/host/import.ml b/interpreter/host/import.ml index 31595b67..0e658dc0 100644 --- a/interpreter/host/import.ml +++ b/interpreter/host/import.ml @@ -4,7 +4,7 @@ open Ast module Unknown = Error.Make () exception Unknown = Unknown.Error (* indicates unknown import name *) -module Registry = Map.Make(String) +module Registry = Instance.ExportMap let registry = ref Registry.empty let register name lookup = registry := Registry.add name lookup !registry @@ -14,6 +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 \"" ^ module_name ^ "." ^ item_name ^ "\"") + ("unknown import \"" ^ String.escaped (Utf8.encode module_name) ^ + "\".\"" ^ String.escaped (Utf8.encode item_name) ^ "\"") let link m = List.map (lookup m) m.it.imports diff --git a/interpreter/host/import.mli b/interpreter/host/import.mli index 9310553d..7d29b592 100644 --- a/interpreter/host/import.mli +++ b/interpreter/host/import.mli @@ -3,6 +3,6 @@ exception Unknown of Source.region * string val link : Ast.module_ -> Instance.extern list (* raises Unknown *) val register : - string -> - (string -> Types.external_type -> Instance.extern (* raise Not_found *)) -> + Ast.name -> + (Ast.name -> Types.external_type -> Instance.extern (* raise Not_found *)) -> unit diff --git a/interpreter/host/import/env.ml b/interpreter/host/import/env.ml index 9414fd17..07dab62f 100644 --- a/interpreter/host/import/env.ml +++ b/interpreter/host/import/env.ml @@ -40,7 +40,7 @@ let exit vs = let lookup name t = - match name, t with + match Utf8.encode name, t with | "abort", ExternalFuncType t -> ExternalFunc (HostFunc (t, abort)) | "exit", ExternalFuncType t -> ExternalFunc (HostFunc (t, exit)) | _ -> raise Not_found diff --git a/interpreter/host/import/spectest.ml b/interpreter/host/import/spectest.ml index de953751..a5e07625 100644 --- a/interpreter/host/import/spectest.ml +++ b/interpreter/host/import/spectest.ml @@ -28,7 +28,7 @@ let print (FuncType (_, out)) vs = let lookup name t = - match name, t with + match Utf8.encode name, t with | "print", ExternalFuncType t -> ExternalFunc (HostFunc (t, print t)) | "print", _ -> let t = FuncType ([], []) in ExternalFunc (HostFunc (t, print t)) diff --git a/interpreter/host/js.ml b/interpreter/host/js.ml index fff314c2..1d66dc18 100644 --- a/interpreter/host/js.ml +++ b/interpreter/host/js.ml @@ -139,14 +139,15 @@ let harness = (* Context *) module Map = Map.Make(String) +module ExportMap = Instance.ExportMap -type exports = external_type Map.t +type exports = external_type ExportMap.t type modules = {mutable env : exports Map.t; mutable current : int} let exports m : exports = List.fold_left - (fun map exp -> Map.add exp.it.name (export_type m exp) map) - Map.empty m.it.exports + (fun map exp -> ExportMap.add exp.it.name (export_type m exp) map) + ExportMap.empty m.it.exports let modules () : modules = {env = Map.empty; current = 0} @@ -167,8 +168,9 @@ let lookup (mods : modules) x_opt name at = raise (Eval.Crash (at, if x_opt = None then "no module defined within script" else "unknown module " ^ of_var_opt mods x_opt ^ " within script")) - in try Map.find name exports with Not_found -> - raise (Eval.Crash (at, "unknown export \"" ^ name ^ "\" within module")) + in try ExportMap.find name exports with Not_found -> + raise (Eval.Crash (at, "unknown export \"" ^ + String.escaped (Utf8.encode name) ^ "\" within module")) (* Wrappers *) @@ -245,7 +247,7 @@ let wrap module_name item_name wrap_action wrap_assertion at = let types = FuncType ([], []) :: itypes in let imports = [{module_name; item_name; idesc} @@ at] in let edesc = FuncExport item @@ at in - let exports = [{name = "run"; edesc} @@ at] in + let exports = [{name = Utf8.decode "run"; edesc} @@ at] in let body = [ Block ([], action @ assertion @ [Return @@ at]) @@ at; Unreachable @@ at ] @@ -286,6 +288,7 @@ let of_string_with add_char s = let of_bytes = of_string_with add_hex_char let of_string = of_string_with add_char +let of_name n = of_string (Utf8.encode n) let of_float z = match string_of_float z with @@ -311,14 +314,14 @@ let of_definition def = let of_wrapper mods x_opt name wrap_action wrap_assertion at = let x = of_var_opt mods x_opt in - let bs = wrap x name wrap_action wrap_assertion at in + let bs = wrap (Utf8.decode x) name wrap_action wrap_assertion at in "call(instance(" ^ of_bytes bs ^ ", " ^ "exports(" ^ of_string x ^ ", " ^ x ^ ")), " ^ " \"run\", [])" let of_action mods act = match act.it with | Invoke (x_opt, name, lits) -> - "call(" ^ of_var_opt mods x_opt ^ ", " ^ of_string name ^ ", " ^ + "call(" ^ of_var_opt mods x_opt ^ ", " ^ of_name name ^ ", " ^ "[" ^ String.concat ", " (List.map of_literal lits) ^ "])", (match lookup mods x_opt name act.at with | ExternalFuncType ft when not (is_js_func_type ft) -> @@ -327,7 +330,7 @@ let of_action mods act = | _ -> None ) | Get (x_opt, name) -> - "get(" ^ of_var_opt mods x_opt ^ ", " ^ of_string name ^ ")", + "get(" ^ of_var_opt mods x_opt ^ ", " ^ of_name name ^ ")", (match lookup mods x_opt name act.at with | ExternalGlobalType gt when not (is_js_global_type gt) -> let GlobalType (t, _) = gt in @@ -383,7 +386,7 @@ let of_command mods cmd = (if x_opt = None then "" else "let " ^ of_var_opt mods x_opt ^ " = " ^ current_var mods ^ ";\n") | Register (name, x_opt) -> - "register(" ^ of_string name ^ ", " ^ of_var_opt mods x_opt ^ ")\n" + "register(" ^ of_name name ^ ", " ^ of_var_opt mods x_opt ^ ")\n" | Action act -> of_assertion' mods act "run" [] None ^ "\n" | Assertion ass -> diff --git a/interpreter/host/main.ml b/interpreter/host/main.ml index 5e62cab1..ab09cbd2 100644 --- a/interpreter/host/main.ml +++ b/interpreter/host/main.ml @@ -2,8 +2,8 @@ let name = "wasm" let version = "0.7" let configure () = - Import.register "spectest" Spectest.lookup; - Import.register "env" Env.lookup + Import.register (Utf8.decode "spectest") Spectest.lookup; + Import.register (Utf8.decode "env") Env.lookup let banner () = print_endline diff --git a/interpreter/host/run.ml b/interpreter/host/run.ml index 3e041c9a..1f7a9c22 100644 --- a/interpreter/host/run.ml +++ b/interpreter/host/run.ml @@ -188,6 +188,8 @@ 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 = @@ -198,7 +200,8 @@ let print_import m im = | ExternalGlobalType t -> "global", string_of_global_type t in Printf.printf " import %s %S %S : %s\n" - category im.it.Ast.module_name im.it.Ast.item_name annotation + category (string_of_name im.it.Ast.module_name) + (string_of_name im.it.Ast.item_name) annotation let print_export m ex = let open Types in @@ -210,7 +213,7 @@ let print_export m ex = | ExternalGlobalType t -> "global", string_of_global_type t in Printf.printf " export %s %S : %s\n" - category (String.escaped ex.it.Ast.name) annotation + category (string_of_name ex.it.Ast.name) annotation let print_module x_opt m = Printf.printf "module%s :\n" @@ -272,7 +275,7 @@ let run_definition def = let run_action act = match act.it with | Invoke (x_opt, name, vs) -> - trace ("Invoking function \"" ^ name ^ "\"..."); + trace ("Invoking function \"" ^ string_of_name name ^ "\"..."); let inst = lookup_instance x_opt act.at in (match Instance.export inst name with | Some (Instance.ExternalFunc f) -> @@ -282,7 +285,7 @@ let run_action act = ) | Get (x_opt, name) -> - trace ("Getting global \"" ^ name ^ "\"..."); + trace ("Getting global \"" ^ string_of_name name ^ "\"..."); let inst = lookup_instance x_opt act.at in (match Instance.export inst name with | Some (Instance.ExternalGlobal v) -> [v] @@ -298,7 +301,10 @@ let assert_result at correct got print_expect expect = end let assert_message at name msg re = - if String.sub msg 0 (String.length re) <> re then begin + if + String.length msg < String.length re || + String.sub msg 0 (String.length re) <> re + then begin print_endline ("Result: \"" ^ msg ^ "\""); print_endline ("Expect: \"" ^ re ^ "\""); Assert.error at ("wrong " ^ name ^ " error") @@ -419,10 +425,10 @@ let rec run_command cmd = | Register (name, x_opt) -> quote := cmd :: !quote; if not !Flags.dry then begin - trace ("Registering module \"" ^ name ^ "\"..."); + trace ("Registering module \"" ^ string_of_name name ^ "\"..."); let inst = lookup_instance x_opt cmd.at in - registry := Map.add name inst !registry; - Import.register name (lookup_registry name) + registry := Map.add (Utf8.encode name) inst !registry; + Import.register name (lookup_registry (Utf8.encode name)) end | Action act -> diff --git a/interpreter/spec/ast.ml b/interpreter/spec/ast.ml index 94822eb7..3604bbc1 100644 --- a/interpreter/spec/ast.ml +++ b/interpreter/spec/ast.ml @@ -65,6 +65,7 @@ type storeop = Memory.mem_size memop type var = int32 Source.phrase type literal = Values.value Source.phrase +type name = int list type instr = instr' Source.phrase and instr' = @@ -156,7 +157,7 @@ and export_desc' = type export = export' Source.phrase and export' = { - name : string; + name : name; edesc : export_desc; } @@ -170,8 +171,8 @@ and import_desc' = type import = import' Source.phrase and import' = { - module_name : string; - item_name : string; + module_name : name; + item_name : name; idesc : import_desc; } diff --git a/interpreter/spec/decode.ml b/interpreter/spec/decode.ml index 2cca1245..3c4dfd49 100644 --- a/interpreter/spec/decode.ml +++ b/interpreter/spec/decode.ml @@ -114,6 +114,11 @@ let rec list f n s = if n = 0 then [] else let x = f s in x :: list f (n - 1) s let opt f b s = if b then Some (f s) else None let vec f s = let n = len32 s in list f n s +let name s = + let pos = pos s in + try Utf8.decode (string s) with Utf8.Utf8 -> + error s pos "invalid UTF-8 encoding" + let sized f s = let size = len32 s in let start = pos s in @@ -491,8 +496,8 @@ let import_desc s = | _ -> error s (pos s - 1) "invalid import kind" let import s = - let module_name = string s in - let item_name = string s in + let module_name = name s in + let item_name = name s in let idesc = at import_desc s in {module_name; item_name; idesc} @@ -548,7 +553,7 @@ let export_desc s = | _ -> error s (pos s - 1) "invalid export kind" let export s = - let name = string s in + let name = name s in let edesc = at export_desc s in {name; edesc} @@ -607,7 +612,7 @@ let data_section s = let custom size s = let start = pos s in - let _id = string s in + let _id = name s in skip (size - (pos s - start)) s; true diff --git a/interpreter/spec/encode.ml b/interpreter/spec/encode.ml index c93e71ed..ca706b18 100644 --- a/interpreter/spec/encode.ml +++ b/interpreter/spec/encode.ml @@ -71,6 +71,7 @@ let encode m = let bool b = vu1 (if b then 1 else 0) let string bs = len (String.length bs); put_string s bs + let name n = string (Utf8.encode n) let list f xs = List.iter f xs let opt f xo = Lib.Option.app f xo let vec f xs = len (List.length xs); list f xs @@ -390,7 +391,7 @@ let encode m = let import im = let {module_name; item_name; idesc} = im.it in - string module_name; string item_name; import_desc idesc + name module_name; name item_name; import_desc idesc let import_section ims = section 2 (vec import) ims (ims <> []) @@ -434,8 +435,8 @@ let encode m = | GlobalExport x -> u8 3; var x let export ex = - let {name; edesc} = ex.it in - string name; export_desc edesc + let {name = n; edesc} = ex.it in + name n; export_desc edesc let export_section exs = section 7 (vec export) exs (exs <> []) diff --git a/interpreter/spec/instance.ml b/interpreter/spec/instance.ml index 8c468bc9..bcc01953 100644 --- a/interpreter/spec/instance.ml +++ b/interpreter/spec/instance.ml @@ -1,6 +1,6 @@ open Values -module ExportMap = Map.Make(String) +module ExportMap = Map.Make(struct type t = Ast.name let compare = compare end) type global = value ref diff --git a/interpreter/spec/utf8.ml b/interpreter/spec/utf8.ml new file mode 100644 index 00000000..5cf17997 --- /dev/null +++ b/interpreter/spec/utf8.ml @@ -0,0 +1,42 @@ +exception Utf8 + +let con n = 0x80 lor (n land 0x3f) + +let rec encode ns = Lib.String.implode (List.map Char.chr (encode' ns)) +and encode' = function + | [] -> [] + | n::ns when n < 0 -> + raise Utf8 + | n::ns when n < 0x80 -> + n :: encode' ns + | n::ns when n < 0x800 -> + 0xc0 lor (n lsr 6) :: con n :: encode' ns + | n::ns when n < 0x10000 -> + 0xe0 lor (n lsr 12) :: con (n lsr 6) :: con n :: encode' ns + | n::ns when n < 0x110000 -> + 0xf0 lor (n lsr 18) :: con (n lsr 12) :: con (n lsr 6) :: con n + :: encode' ns + | _ -> + raise Utf8 + +let con b = if b land 0xc0 = 0x80 then b land 0x3f else raise Utf8 +let code min n = + if n < min || (0xd800 <= n && n < 0xe000) || n >= 0x110000 then raise Utf8 + else n + +let rec decode s = decode' (List.map Char.code (Lib.String.explode s)) +and decode' = function + | [] -> [] + | b1::bs when b1 < 0x80 -> + code 0x0 b1 :: decode' bs + | b1::bs when b1 < 0xc0 -> + raise Utf8 + | b1::b2::bs when b1 < 0xe0 -> + code 0x80 ((b1 land 0x1f) lsl 6 + con b2) :: decode' bs + | b1::b2::b3::bs when b1 < 0xf0 -> + code 0x800 ((b1 land 0x0f) lsl 12 + con b2 lsl 6 + con b3) :: decode' bs + | b1::b2::b3::b4::bs when b1 < 0xf8 -> + code 0x10000 ((b1 land 0x07) lsl 18 + con b2 lsl 12 + con b3 lsl 6 + con b4) + :: decode' bs + | _ -> + raise Utf8 diff --git a/interpreter/spec/utf8.mli b/interpreter/spec/utf8.mli new file mode 100644 index 00000000..589d87ec --- /dev/null +++ b/interpreter/spec/utf8.mli @@ -0,0 +1,4 @@ +exception Utf8 + +val decode : string -> int list (* raise UTf8 *) +val encode : int list -> string (* raise Utf8 *) diff --git a/interpreter/spec/valid.ml b/interpreter/spec/valid.ml index 77ce2c01..e596c92e 100644 --- a/interpreter/spec/valid.ml +++ b/interpreter/spec/valid.ml @@ -409,7 +409,7 @@ let check_import (im : import) (c : context) : context = "mutable globals cannot be imported (yet)"; {c with globals = t :: c.globals} -module NameSet = Set.Make(String) +module NameSet = Set.Make(struct type t = Ast.name let compare = compare end) let check_export (c : context) (set : NameSet.t) (ex : export) : NameSet.t = let {name; edesc} = ex.it in diff --git a/interpreter/text/arrange.ml b/interpreter/text/arrange.ml index 18bc51f4..3eb2a066 100644 --- a/interpreter/text/arrange.ml +++ b/interpreter/text/arrange.ml @@ -29,6 +29,7 @@ let string_with add_char s = let bytes = string_with add_hex_char let string = string_with add_char +let name n = string (Utf8.encode n) let list_of_opt = function None -> [] | Some x -> [x] @@ -307,7 +308,7 @@ let import_desc i d = let import i im = let {module_name; item_name; idesc} = im.it in Node ("import", - [atom string module_name; atom string item_name; import_desc i idesc] + [atom name module_name; atom name item_name; import_desc i idesc] ) let export_desc d = @@ -318,8 +319,8 @@ let export_desc d = | GlobalExport x -> Node ("global", [atom var x]) let export ex = - let {name; edesc} = ex.it in - Node ("export", [atom string name; export_desc edesc]) + let {name = n; edesc} = ex.it in + Node ("export", [atom name n; export_desc edesc]) let global off i g = let {gtype; value} = g.it in @@ -392,8 +393,8 @@ let definition mode x_opt def = | Encoded (_, bs) -> bs in binary_module_with_var_opt x_opt bs -let access x_opt name = - String.concat " " [var_opt x_opt; string name] +let access x_opt n = + String.concat " " [var_opt x_opt; name n] let action act = match act.it with @@ -426,8 +427,8 @@ let assertion mode ass = let command mode cmd = match cmd.it with | Module (x_opt, def) -> definition mode x_opt def - | Register (name, x_opt) -> - Node ("register " ^ string name ^ var_opt x_opt, []) + | Register (n, x_opt) -> + Node ("register " ^ name n ^ var_opt x_opt, []) | Action act -> action act | Assertion ass -> assertion mode ass | Meta _ -> assert false diff --git a/interpreter/text/parser.mly b/interpreter/text/parser.mly index e784a59c..31db274e 100644 --- a/interpreter/text/parser.mly +++ b/interpreter/text/parser.mly @@ -48,6 +48,9 @@ let nat s at = let nat32 s at = try I32.of_string_u s with Failure _ -> error at "i32 constant out of range" +let name s at = + try Utf8.decode s with Utf8.Utf8 -> error at "invalid UTF-8 encoding" + (* Symbolic variables *) @@ -196,6 +199,9 @@ let inline_type (c : context) ty at = /* Auxiliaries */ +name : + | TEXT { name $1 (at ()) } + text_list : | /* empty */ { "" } | text_list TEXT { $1 ^ $2 } @@ -537,7 +543,7 @@ import_desc : { fun c -> ignore ($3 c anon_global bind_global); GlobalImport $4 } import : - | LPAR IMPORT TEXT TEXT import_desc RPAR + | LPAR IMPORT name name import_desc RPAR { let at = at () and at5 = ati 5 in fun c -> {module_name = $3; item_name = $4; idesc = $5 c @@ at5} @@ at } | LPAR FUNC bind_var_opt inline_import type_use RPAR /* Sugar */ @@ -567,7 +573,7 @@ import : idesc = GlobalImport $5 @@ at } @@ at } inline_import : - | LPAR IMPORT TEXT TEXT RPAR { $3, $4 } + | LPAR IMPORT name name RPAR { $3, $4 } export_desc : | LPAR FUNC var RPAR { fun c -> FuncExport ($3 c func) } @@ -576,7 +582,7 @@ export_desc : | LPAR GLOBAL var RPAR { fun c -> GlobalExport ($3 c global) } export : - | LPAR EXPORT TEXT export_desc RPAR + | LPAR EXPORT name export_desc RPAR { let at = at () and at4 = ati 4 in fun c -> {name = $3; edesc = $4 c @@ at4} @@ at } @@ -585,7 +591,7 @@ inline_export_opt : | inline_export { $1 } inline_export : - | LPAR EXPORT TEXT RPAR + | LPAR EXPORT name RPAR { let at = at () in fun d c -> [{name = $3; edesc = d @@ at} @@ at] } @@ -658,9 +664,9 @@ script_var_opt : | VAR { Some ($1 @@ at ()) } /* Sugar */ action : - | LPAR INVOKE script_var_opt TEXT const_list RPAR + | LPAR INVOKE script_var_opt name const_list RPAR { Invoke ($3, $4, $5) @@ at () } - | LPAR GET script_var_opt TEXT RPAR + | LPAR GET script_var_opt name RPAR { Get ($3, $4) @@ at() } assertion : @@ -682,7 +688,7 @@ cmd : | action { Action $1 @@ at () } | assertion { Assertion $1 @@ at () } | module_ { Module (fst $1, snd $1) @@ at () } - | LPAR REGISTER TEXT script_var_opt RPAR { Register ($3, $4) @@ at () } + | LPAR REGISTER name script_var_opt RPAR { Register ($3, $4) @@ at () } | meta { Meta $1 @@ at () } cmd_list : diff --git a/interpreter/text/script.ml b/interpreter/text/script.ml index faa87e76..11032f1f 100644 --- a/interpreter/text/script.ml +++ b/interpreter/text/script.ml @@ -7,8 +7,8 @@ and definition' = type action = action' Source.phrase and action' = - | Invoke of var option * string * Ast.literal list - | Get of var option * string + | Invoke of var option * Ast.name * Ast.literal list + | Get of var option * Ast.name type assertion = assertion' Source.phrase and assertion' = @@ -25,7 +25,7 @@ and assertion' = type command = command' Source.phrase and command' = | Module of var option * definition - | Register of string * var option + | Register of Ast.name * var option | Action of action | Assertion of assertion | Meta of meta diff --git a/interpreter/util/lib.ml b/interpreter/util/lib.ml index 284329ec..51407749 100644 --- a/interpreter/util/lib.ml +++ b/interpreter/util/lib.ml @@ -4,6 +4,37 @@ struct if n = 0 then () else (f x; repeat (n - 1) f x) end +module Int = +struct + let log2 n = + if n <= 0 then failwith "log2"; + let rec loop acc n = if n = 1 then acc else loop (acc + 1) (n lsr 1) in + loop 0 n + + let is_power_of_two n = + if n < 0 then failwith "is_power_of_two"; + n <> 0 && n land (n - 1) = 0 +end + +module String = +struct + let implode cs = + let buf = Buffer.create (List.length cs) in + List.iter (Buffer.add_char buf) cs; + Buffer.contents buf + + let explode s = + let cs = ref [] in + for i = String.length s - 1 downto 0 do cs := s.[i] :: !cs done; + !cs + + let breakup s n = + let rec loop i = + let len = min n (String.length s - i) in + if len = 0 then [] else String.sub s i len :: loop (i + len) + in loop 0 +end + module List = struct let rec make n x = @@ -128,24 +159,3 @@ struct | Some x -> f x | None -> () end - -module Int = -struct - let log2 n = - if n <= 0 then failwith "log2"; - let rec loop acc n = if n = 1 then acc else loop (acc + 1) (n lsr 1) in - loop 0 n - - let is_power_of_two n = - if n < 0 then failwith "is_power_of_two"; - n <> 0 && n land (n - 1) = 0 -end - -module String = -struct - let breakup s n = - let rec loop i = - let len = min n (String.length s - i) in - if len = 0 then [] else String.sub s i len :: loop (i + len) - in loop 0 -end diff --git a/interpreter/util/lib.mli b/interpreter/util/lib.mli index 293070c0..5704e067 100644 --- a/interpreter/util/lib.mli +++ b/interpreter/util/lib.mli @@ -64,5 +64,7 @@ end module String : sig + val implode : char list -> string + val explode : string -> char list val breakup : string -> int -> string list end diff --git a/interpreter/winmake.bat b/interpreter/winmake.bat index e86d1198..40489fd4 100644 --- a/interpreter/winmake.bat +++ b/interpreter/winmake.bat @@ -17,6 +17,7 @@ ocamlc.opt -c -w +a-4-27-42-44-45 -warn-error +a -bin-annot -I spec -I util -I h ocamlc.opt -c -w +a-4-27-42-44-45 -warn-error +a -bin-annot -I spec -I util -I host -I text -I host/import -o spec/table.cmi spec/table.mli ocamlc.opt -c -w +a-4-27-42-44-45 -warn-error +a -bin-annot -I spec -I util -I host -I text -I host/import -o spec/instance.cmo spec/instance.ml ocamlc.opt -c -w +a-4-27-42-44-45 -warn-error +a -bin-annot -I spec -I util -I host -I text -I host/import -o spec/eval.cmi spec/eval.mli +ocamlc.opt -c -w +a-4-27-42-44-45 -warn-error +a -bin-annot -I spec -I util -I host -I text -I host/import -o spec/utf8.cmi spec/utf8.mli ocamlc.opt -c -w +a-4-27-42-44-45 -warn-error +a -bin-annot -I spec -I util -I host -I text -I host/import -o spec/encode.cmi spec/encode.mli ocamlc.opt -c -w +a-4-27-42-44-45 -warn-error +a -bin-annot -I host/import -I util -I spec -I host -I text -o host/import/env.cmo host/import/env.ml ocamlc.opt -c -w +a-4-27-42-44-45 -warn-error +a -bin-annot -I host -I util -I spec -I text -I host/import -o host/flags.cmo host/flags.ml @@ -38,16 +39,17 @@ ocamlc.opt -c -w +a-4-27-42-44-45 -warn-error +a -g -bin-annot -I host -I util - ocamlc.opt -c -w +a-4-27-42-44-45 -warn-error +a -g -bin-annot -I host -I util -I spec -I text -I host/import -o host/import.d.cmo host/import.ml ocamlc.opt -c -w +a-4-27-42-44-45 -warn-error +a -g -bin-annot -I host -I util -I spec -I text -I host/import -o host/run.d.cmo host/run.ml ocamlc.opt -c -w +a-4-27-42-44-45 -warn-error +a -g -bin-annot -I host/import -I util -I spec -I host -I text -o host/import/spectest.d.cmo host/import/spectest.ml +ocamlc.opt -c -w +a-4-27-42-44-45 -warn-error +a -g -bin-annot -I spec -I util -I host -I text -I host/import -o spec/utf8.d.cmo spec/utf8.ml ocamlc.opt -c -w +a-4-27-42-44-45 -warn-error +a -g -bin-annot -I spec -I util -I host -I text -I host/import -o spec/ast.d.cmo spec/ast.ml ocamlc.opt -c -w +a-4-27-42-44-45 -warn-error +a -g -bin-annot -I util -I spec -I host -I text -I host/import -o util/error.d.cmo util/error.ml ocamlc.opt -c -w +a-4-27-42-44-45 -warn-error +a -g -bin-annot -I spec -I util -I host -I text -I host/import -o spec/f32.d.cmo spec/f32.ml ocamlc.opt -c -w +a-4-27-42-44-45 -warn-error +a -g -bin-annot -I spec -I util -I host -I text -I host/import -o spec/f64.d.cmo spec/f64.ml -ocamlc.opt -c -w +a-4-27-42-44-45 -warn-error +a -g -bin-annot -I spec -I util -I host -I text -I host/import -o spec/i32.d.cmo spec/i32.ml ocamlc.opt -c -w +a-4-27-42-44-45 -warn-error +a -g -bin-annot -I util -I spec -I host -I text -I host/import -o util/lib.d.cmo util/lib.ml ocamlc.opt -c -w +a-4-27-42-44-45 -warn-error +a -g -bin-annot -I spec -I util -I host -I text -I host/import -o spec/memory.d.cmo spec/memory.ml ocamlc.opt -c -w +a-4-27-42-44-45 -warn-error +a -g -bin-annot -I util -I spec -I host -I text -I host/import -o util/source.d.cmo util/source.ml ocamlc.opt -c -w +a-4-27-42-44-45 -warn-error +a -g -bin-annot -I spec -I util -I host -I text -I host/import -o spec/types.d.cmo spec/types.ml ocamlc.opt -c -w +a-4-27-42-44-45 -warn-error +a -g -bin-annot -I spec -I util -I host -I text -I host/import -o spec/values.d.cmo spec/values.ml +ocamlc.opt -c -w +a-4-27-42-44-45 -warn-error +a -g -bin-annot -I spec -I util -I host -I text -I host/import -o spec/i32.d.cmo spec/i32.ml ocamlc.opt -c -w +a-4-27-42-44-45 -warn-error +a -g -bin-annot -I spec -I util -I host -I text -I host/import -o spec/i64.d.cmo spec/i64.ml ocamlc.opt -c -w +a-4-27-42-44-45 -warn-error +a -g -bin-annot -I spec -I util -I host -I text -I host/import -o spec/float.d.cmo spec/float.ml ocamlc.opt -c -w +a-4-27-42-44-45 -warn-error +a -g -bin-annot -I spec -I util -I host -I text -I host/import -o spec/int.d.cmo spec/int.ml @@ -83,4 +85,4 @@ ocamlc.opt -c -w +a-4-27-42-44-45 -warn-error +a -g -bin-annot -I text -I util - ocamlc.opt -c -w +a-4-27-42-44-45 -warn-error +a -g -bin-annot -I text -I util -I spec -I host -I host/import -o text/parser.d.cmo text/parser.ml ocamlc.opt -c -w +a-4-27-42-44-45 -warn-error +a -g -bin-annot -I text -I util -I spec -I host -I host/import -o text/arrange.d.cmo text/arrange.ml ocamlc.opt -c -w +a-4-27-42-44-45 -warn-error +a -g -bin-annot -I util -I spec -I host -I text -I host/import -o util/sexpr.d.cmo util/sexpr.ml -ocamlc.opt str.cma bigarray.cma -g host/flags.d.cmo spec/float.d.cmo spec/f32.d.cmo spec/f64.d.cmo spec/numeric_error.d.cmo spec/int.d.cmo spec/i32.d.cmo spec/i64.d.cmo spec/types.d.cmo spec/values.d.cmo util/lib.d.cmo spec/memory.d.cmo util/source.d.cmo spec/ast.d.cmo spec/table.d.cmo spec/instance.d.cmo util/error.d.cmo host/import.d.cmo spec/i32_convert.d.cmo spec/f32_convert.d.cmo spec/i64_convert.d.cmo spec/f64_convert.d.cmo spec/eval_numeric.d.cmo spec/eval.d.cmo host/import/env.d.cmo host/import/spectest.d.cmo spec/encode.d.cmo spec/operators.d.cmo spec/decode.d.cmo text/script.d.cmo host/js.d.cmo spec/valid.d.cmo text/parser.d.cmo text/lexer.d.cmo text/parse.d.cmo util/sexpr.d.cmo text/arrange.d.cmo text/print.d.cmo host/run.d.cmo host/main.d.cmo -o %NAME%.exe +ocamlc.opt bigarray.cma -g host/flags.d.cmo spec/float.d.cmo spec/f32.d.cmo spec/f64.d.cmo spec/numeric_error.d.cmo spec/int.d.cmo spec/i32.d.cmo spec/i64.d.cmo spec/types.d.cmo spec/values.d.cmo util/lib.d.cmo spec/memory.d.cmo util/source.d.cmo spec/ast.d.cmo spec/table.d.cmo spec/instance.d.cmo spec/utf8.d.cmo util/error.d.cmo host/import.d.cmo spec/i32_convert.d.cmo spec/f32_convert.d.cmo spec/i64_convert.d.cmo spec/f64_convert.d.cmo spec/eval_numeric.d.cmo spec/eval.d.cmo host/import/env.d.cmo host/import/spectest.d.cmo spec/encode.d.cmo spec/operators.d.cmo spec/decode.d.cmo text/script.d.cmo host/js.d.cmo spec/valid.d.cmo text/parser.d.cmo text/lexer.d.cmo text/parse.d.cmo util/sexpr.d.cmo text/arrange.d.cmo text/print.d.cmo host/run.d.cmo host/main.d.cmo -o %NAME%.exe From 232f5a6c8ab50fdaa5703db3cc814d68fc69d55a Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Fri, 5 May 2017 09:25:48 -0700 Subject: [PATCH 004/672] Utf8 tests (#469) * Test UTF-8 identifier validation. * Fix custom section lengths. Fix an error in the custom section lengths, so that the modules are valid except for the particular aspect being tested. * Avoid invalid UTF-8 byte sequences in comments. --- test/core/names.wast | 4 + test/core/utf8-custom-section-id.wast | 1792 +++++++++++++++++ test/core/utf8-import-field.wast | 2672 +++++++++++++++++++++++++ test/core/utf8-import-module.wast | 2672 +++++++++++++++++++++++++ 4 files changed, 7140 insertions(+) create mode 100644 test/core/utf8-custom-section-id.wast create mode 100644 test/core/utf8-import-field.wast create mode 100644 test/core/utf8-import-module.wast diff --git a/test/core/names.wast b/test/core/names.wast index 07b4deb5..907d82fb 100644 --- a/test/core/names.wast +++ b/test/core/names.wast @@ -46,6 +46,9 @@ ;; Test that we can use some libc hidden names without conflict. (func (export "_malloc") (result f32) (f32.const 0x1.93p+2)) (func (export "__malloc") (result f32) (f32.const 0x1.94p+2)) + + ;; Test that UTF-8 BOM characters can appear in identifiers. + (func (export "") (result f32) (f32.const 0x2.04p+2)) ) (assert_return (invoke "") (f32.const 0x1.91p+2)) @@ -60,6 +63,7 @@ (assert_return (invoke "NaN") (f32.const 0x2.01p+2)) (assert_return (invoke "Infinity") (f32.const 0x2.02p+2)) (assert_return (invoke "if") (f32.const 0x2.03p+2)) +(assert_return (invoke "") (f32.const 0x2.04p+2)) (module ;; Test that we can use indices instead of names to reference imports, diff --git a/test/core/utf8-custom-section-id.wast b/test/core/utf8-custom-section-id.wast new file mode 100644 index 00000000..040c3ea3 --- /dev/null +++ b/test/core/utf8-custom-section-id.wast @@ -0,0 +1,1792 @@ +;;;;;; Invalid UTF-8 custom section names + +;;;; Continuation bytes not preceded by prefixes + +;; encoding starts with (first) continuation byte +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\00\02" ;; custom section + "\01\80" ;; "\80" + ) + "invalid UTF-8 encoding" +) + +;; encoding starts with (0x8f) continuation byte +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\00\02" ;; custom section + "\01\8f" ;; "\8f" + ) + "invalid UTF-8 encoding" +) + +;; encoding starts with (0x90) continuation byte +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\00\02" ;; custom section + "\01\90" ;; "\90" + ) + "invalid UTF-8 encoding" +) + +;; encoding starts with (0x9f) continuation byte +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\00\02" ;; custom section + "\01\9f" ;; "\9f" + ) + "invalid UTF-8 encoding" +) + +;; encoding starts with (0xa0) continuation byte +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\00\02" ;; custom section + "\01\a0" ;; "\a0" + ) + "invalid UTF-8 encoding" +) + +;; encoding starts with (last) continuation byte +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\00\02" ;; custom section + "\01\bf" ;; "\bf" + ) + "invalid UTF-8 encoding" +) + +;;;; 2-byte sequences + +;; 2-byte sequence contains 3 bytes +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\00\04" ;; custom section + "\03\c2\80\80" ;; "\c2\80\80" + ) + "invalid UTF-8 encoding" +) + +;; 2-byte sequence contains 1 byte at end of string +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\00\02" ;; custom section + "\01\c2" ;; "\c2" + ) + "invalid UTF-8 encoding" +) + +;; 2-byte sequence contains 1 byte +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\00\03" ;; custom section + "\02\c2\2e" ;; "\c2." + ) + "invalid UTF-8 encoding" +) + +;;;; 2-byte sequence contents + +;; overlong encoding after 0xc0 prefix +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\00\03" ;; custom section + "\02\c0\80" ;; "\c0\80" + ) + "invalid UTF-8 encoding" +) + +;; overlong encoding after 0xc0 prefix +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\00\03" ;; custom section + "\02\c0\bf" ;; "\c0\bf" + ) + "invalid UTF-8 encoding" +) + +;; overlong encoding after 0xc1 prefix +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\00\03" ;; custom section + "\02\c1\80" ;; "\c1\80" + ) + "invalid UTF-8 encoding" +) + +;; overlong encoding after 0xc1 prefix +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\00\03" ;; custom section + "\02\c1\bf" ;; "\c1\bf" + ) + "invalid UTF-8 encoding" +) + +;; byte after (first) 2-byte prefix not a contination byte +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\00\03" ;; custom section + "\02\c2\00" ;; "\c2\00" + ) + "invalid UTF-8 encoding" +) + +;; byte after (first) 2-byte prefix not a continuation byte +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\00\03" ;; custom section + "\02\c2\7f" ;; "\c2\7f" + ) + "invalid UTF-8 encoding" +) + +;; byte after (first) 2-byte prefix not a continuation byte +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\00\03" ;; custom section + "\02\c2\c0" ;; "\c2\c0" + ) + "invalid UTF-8 encoding" +) + +;; byte after (first) 2-byte prefix not a continuation byte +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\00\03" ;; custom section + "\02\c2\fd" ;; "\c2\fd" + ) + "invalid UTF-8 encoding" +) + +;; byte after (last) 2-byte prefix not a continuation byte +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\00\03" ;; custom section + "\02\df\00" ;; "\df\00" + ) + "invalid UTF-8 encoding" +) + +;; byte after (last) 2-byte prefix not a continuation byte +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\00\03" ;; custom section + "\02\df\7f" ;; "\df\7f" + ) + "invalid UTF-8 encoding" +) + +;; byte after (last) 2-byte prefix not a continuation byte +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\00\03" ;; custom section + "\02\df\c0" ;; "\df\c0" + ) + "invalid UTF-8 encoding" +) + +;; byte after (last) 2-byte prefix not a continuation byte +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\00\03" ;; custom section + "\02\df\fd" ;; "\df\fd" + ) + "invalid UTF-8 encoding" +) + +;;;; 3-byte sequences + +;; 3-byte sequence contains 4 bytes +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\00\05" ;; custom section + "\04\e1\80\80\80" ;; "\e1\80\80\80" + ) + "invalid UTF-8 encoding" +) + +;; 3-byte sequence contains 2 bytes at end of string +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\00\03" ;; custom section + "\02\e1\80" ;; "\e1\80" + ) + "invalid UTF-8 encoding" +) + +;; 3-byte sequence contains 2 bytes +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\00\04" ;; custom section + "\03\e1\80\2e" ;; "\e1\80." + ) + "invalid UTF-8 encoding" +) + +;; 3-byte sequence contains 1 byte at end of string +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\00\02" ;; custom section + "\01\e1" ;; "\e1" + ) + "invalid UTF-8 encoding" +) + +;; 3-byte sequence contains 1 byte +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\00\03" ;; custom section + "\02\e1\2e" ;; "\e1." + ) + "invalid UTF-8 encoding" +) + +;;;; 3-byte sequence contents + +;; first byte after (0xe0) 3-byte prefix not a continuation byte +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\00\04" ;; custom section + "\03\e0\00\a0" ;; "\e0\00\a0" + ) + "invalid UTF-8 encoding" +) + +;; first byte after (0xe0) 3-byte prefix not a continuation byte +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\00\04" ;; custom section + "\03\e0\7f\a0" ;; "\e0\7f\a0" + ) + "invalid UTF-8 encoding" +) + +;; overlong encoding after 0xe0 prefix +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\00\04" ;; custom section + "\03\e0\80\80" ;; "\e0\80\80" + ) + "invalid UTF-8 encoding" +) + +;; overlong encoding after 0xe0 prefix +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\00\04" ;; custom section + "\03\e0\80\a0" ;; "\e0\80\a0" + ) + "invalid UTF-8 encoding" +) + +;; overlong encoding after 0xe0 prefix +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\00\04" ;; custom section + "\03\e0\9f\a0" ;; "\e0\9f\a0" + ) + "invalid UTF-8 encoding" +) + +;; overlong encoding after 0xe0 prefix +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\00\04" ;; custom section + "\03\e0\9f\bf" ;; "\e0\9f\bf" + ) + "invalid UTF-8 encoding" +) + +;; first byte after (0xe0) 3-byte prefix not a continuation byte +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\00\04" ;; custom section + "\03\e0\c0\a0" ;; "\e0\c0\a0" + ) + "invalid UTF-8 encoding" +) + +;; first byte after (0xe0) 3-byte prefix not a continuation byte +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\00\04" ;; custom section + "\03\e0\fd\a0" ;; "\e0\fd\a0" + ) + "invalid UTF-8 encoding" +) + +;; first byte after (first normal) 3-byte prefix not a continuation byte +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\00\04" ;; custom section + "\03\e1\00\80" ;; "\e1\00\80" + ) + "invalid UTF-8 encoding" +) + +;; first byte after (first normal) 3-byte prefix not a continuation byte +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\00\04" ;; custom section + "\03\e1\7f\80" ;; "\e1\7f\80" + ) + "invalid UTF-8 encoding" +) + +;; first byte after (first normal) 3-byte prefix not a continuation byte +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\00\04" ;; custom section + "\03\e1\c0\80" ;; "\e1\c0\80" + ) + "invalid UTF-8 encoding" +) + +;; first byte after (first normal) 3-byte prefix not a continuation byte +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\00\04" ;; custom section + "\03\e1\fd\80" ;; "\e1\fd\80" + ) + "invalid UTF-8 encoding" +) + +;; first byte after (normal) 3-byte prefix not a continuation byte +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\00\04" ;; custom section + "\03\ec\00\80" ;; "\ec\00\80" + ) + "invalid UTF-8 encoding" +) + +;; first byte after (normal) 3-byte prefix not a continuation byte +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\00\04" ;; custom section + "\03\ec\7f\80" ;; "\ec\7f\80" + ) + "invalid UTF-8 encoding" +) + +;; first byte after (normal) 3-byte prefix not a continuation byte +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\00\04" ;; custom section + "\03\ec\c0\80" ;; "\ec\c0\80" + ) + "invalid UTF-8 encoding" +) + +;; first byte after (normal) 3-byte prefix not a continuation byte +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\00\04" ;; custom section + "\03\ec\fd\80" ;; "\ec\fd\80" + ) + "invalid UTF-8 encoding" +) + +;; first byte after (0xed) 3-byte prefix not a continuation byte +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\00\04" ;; custom section + "\03\ed\00\80" ;; "\ed\00\80" + ) + "invalid UTF-8 encoding" +) + +;; first byte after (0xed) 3-byte prefix not a continuation byte +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\00\04" ;; custom section + "\03\ed\7f\80" ;; "\ed\7f\80" + ) + "invalid UTF-8 encoding" +) + +;; byte sequence reserved for UTF-16 surrogate half +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\00\04" ;; custom section + "\03\ed\a0\80" ;; "\ed\a0\80" + ) + "invalid UTF-8 encoding" +) + +;; byte sequence reserved for UTF-16 surrogate half +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\00\04" ;; custom section + "\03\ed\a0\bf" ;; "\ed\a0\bf" + ) + "invalid UTF-8 encoding" +) + +;; byte sequence reserved for UTF-16 surrogate half +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\00\04" ;; custom section + "\03\ed\bf\80" ;; "\ed\bf\80" + ) + "invalid UTF-8 encoding" +) + +;; byte sequence reserved for UTF-16 surrogate half +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\00\04" ;; custom section + "\03\ed\bf\bf" ;; "\ed\bf\bf" + ) + "invalid UTF-8 encoding" +) + +;; first byte after (0xed) 3-byte prefix not a continuation byte +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\00\04" ;; custom section + "\03\ed\c0\80" ;; "\ed\c0\80" + ) + "invalid UTF-8 encoding" +) + +;; first byte after (0xed) 3-byte prefix not a continuation byte +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\00\04" ;; custom section + "\03\ed\fd\80" ;; "\ed\fd\80" + ) + "invalid UTF-8 encoding" +) + +;; first byte after (normal) 3-byte prefix not a continuation byte +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\00\04" ;; custom section + "\03\ee\00\80" ;; "\ee\00\80" + ) + "invalid UTF-8 encoding" +) + +;; first byte after (normal) 3-byte prefix not a continuation byte +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\00\04" ;; custom section + "\03\ee\7f\80" ;; "\ee\7f\80" + ) + "invalid UTF-8 encoding" +) + +;; first byte after (normal) 3-byte prefix not a continuation byte +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\00\04" ;; custom section + "\03\ee\c0\80" ;; "\ee\c0\80" + ) + "invalid UTF-8 encoding" +) + +;; first byte after (normal) 3-byte prefix not a continuation byte +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\00\04" ;; custom section + "\03\ee\fd\80" ;; "\ee\fd\80" + ) + "invalid UTF-8 encoding" +) + +;; first byte after (last normal) 3-byte prefix not a continuation byte +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\00\04" ;; custom section + "\03\ef\00\80" ;; "\ef\00\80" + ) + "invalid UTF-8 encoding" +) + +;; first byte after (last normal) 3-byte prefix not a continuation byte +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\00\04" ;; custom section + "\03\ef\7f\80" ;; "\ef\7f\80" + ) + "invalid UTF-8 encoding" +) + +;; first byte after (last normal) 3-byte prefix not a continuation byte +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\00\04" ;; custom section + "\03\ef\c0\80" ;; "\ef\c0\80" + ) + "invalid UTF-8 encoding" +) + +;; first byte after (last normal) 3-byte prefix not a continuation byte +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\00\04" ;; custom section + "\03\ef\fd\80" ;; "\ef\fd\80" + ) + "invalid UTF-8 encoding" +) + +;;;; 3-byte sequence contents (third byte) + +;; second byte after (0xe0) 3-byte prefix not a continuation byte +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\00\04" ;; custom section + "\03\e0\a0\00" ;; "\e0\a0\00" + ) + "invalid UTF-8 encoding" +) + +;; second byte after (0xe0) 3-byte prefix not a continuation byte +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\00\04" ;; custom section + "\03\e0\a0\7f" ;; "\e0\a0\7f" + ) + "invalid UTF-8 encoding" +) + +;; second byte after (0xe0) 3-byte prefix not a continuation byte +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\00\04" ;; custom section + "\03\e0\a0\c0" ;; "\e0\a0\c0" + ) + "invalid UTF-8 encoding" +) + +;; second byte after (0xe0) 3-byte prefix not a continuation byte +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\00\04" ;; custom section + "\03\e0\a0\fd" ;; "\e0\a0\fd" + ) + "invalid UTF-8 encoding" +) + +;; second byte after (first normal) 3-byte prefix not a continuation byte +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\00\04" ;; custom section + "\03\e1\80\00" ;; "\e1\80\00" + ) + "invalid UTF-8 encoding" +) + +;; second byte after (first normal) 3-byte prefix not a continuation byte +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\00\04" ;; custom section + "\03\e1\80\7f" ;; "\e1\80\7f" + ) + "invalid UTF-8 encoding" +) + +;; second byte after (first normal) 3-byte prefix not a continuation byte +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\00\04" ;; custom section + "\03\e1\80\c0" ;; "\e1\80\c0" + ) + "invalid UTF-8 encoding" +) + +;; second byte after (first normal) 3-byte prefix not a continuation byte +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\00\04" ;; custom section + "\03\e1\80\fd" ;; "\e1\80\fd" + ) + "invalid UTF-8 encoding" +) + +;; second byte after (normal) 3-byte prefix not a continuation byte +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\00\04" ;; custom section + "\03\ec\80\00" ;; "\ec\80\00" + ) + "invalid UTF-8 encoding" +) + +;; second byte after (normal) 3-byte prefix not a continuation byte +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\00\04" ;; custom section + "\03\ec\80\7f" ;; "\ec\80\7f" + ) + "invalid UTF-8 encoding" +) + +;; second byte after (normal) 3-byte prefix not a continuation byte +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\00\04" ;; custom section + "\03\ec\80\c0" ;; "\ec\80\c0" + ) + "invalid UTF-8 encoding" +) + +;; second byte after (normal) 3-byte prefix not a continuation byte +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\00\04" ;; custom section + "\03\ec\80\fd" ;; "\ec\80\fd" + ) + "invalid UTF-8 encoding" +) + +;; second byte after (0xed) 3-byte prefix not a continuation byte +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\00\04" ;; custom section + "\03\ed\80\00" ;; "\ed\80\00" + ) + "invalid UTF-8 encoding" +) + +;; second byte after (0xed) 3-byte prefix not a continuation byte +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\00\04" ;; custom section + "\03\ed\80\7f" ;; "\ed\80\7f" + ) + "invalid UTF-8 encoding" +) + +;; second byte after (0xed) 3-byte prefix not a continuation byte +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\00\04" ;; custom section + "\03\ed\80\c0" ;; "\ed\80\c0" + ) + "invalid UTF-8 encoding" +) + +;; second byte after (0xed) 3-byte prefix not a continuation byte +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\00\04" ;; custom section + "\03\ed\80\fd" ;; "\ed\80\fd" + ) + "invalid UTF-8 encoding" +) + +;; second byte after (normal) 3-byte prefix not a continuation byte +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\00\04" ;; custom section + "\03\ee\80\00" ;; "\ee\80\00" + ) + "invalid UTF-8 encoding" +) + +;; second byte after (normal) 3-byte prefix not a continuation byte +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\00\04" ;; custom section + "\03\ee\80\7f" ;; "\ee\80\7f" + ) + "invalid UTF-8 encoding" +) + +;; second byte after (normal) 3-byte prefix not a continuation byte +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\00\04" ;; custom section + "\03\ee\80\c0" ;; "\ee\80\c0" + ) + "invalid UTF-8 encoding" +) + +;; second byte after (normal) 3-byte prefix not a continuation byte +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\00\04" ;; custom section + "\03\ee\80\fd" ;; "\ee\80\fd" + ) + "invalid UTF-8 encoding" +) + +;; second byte after (last normal) 3-byte prefix not a continuation byte +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\00\04" ;; custom section + "\03\ef\80\00" ;; "\ef\80\00" + ) + "invalid UTF-8 encoding" +) + +;; second byte after (last normal) 3-byte prefix not a continuation byte +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\00\04" ;; custom section + "\03\ef\80\7f" ;; "\ef\80\7f" + ) + "invalid UTF-8 encoding" +) + +;; second byte after (last normal) 3-byte prefix not a continuation byte +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\00\04" ;; custom section + "\03\ef\80\c0" ;; "\ef\80\c0" + ) + "invalid UTF-8 encoding" +) + +;; second byte after (last normal) 3-byte prefix not a continuation byte +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\00\04" ;; custom section + "\03\ef\80\fd" ;; "\ef\80\fd" + ) + "invalid UTF-8 encoding" +) + +;;;; 4-byte sequences + +;; 4-byte sequence contains 5 bytes +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\00\06" ;; custom section + "\05\f1\80\80\80\80" ;; "\f1\80\80\80\80" + ) + "invalid UTF-8 encoding" +) + +;; 4-byte sequence contains 3 bytes at end of string +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\00\04" ;; custom section + "\03\f1\80\80" ;; "\f1\80\80" + ) + "invalid UTF-8 encoding" +) + +;; 4-byte sequence contains 3 bytes +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\00\05" ;; custom section + "\04\f1\80\80\23" ;; "\f1\80\80#" + ) + "invalid UTF-8 encoding" +) + +;; 4-byte sequence contains 2 bytes at end of string +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\00\03" ;; custom section + "\02\f1\80" ;; "\f1\80" + ) + "invalid UTF-8 encoding" +) + +;; 4-byte sequence contains 2 bytes +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\00\04" ;; custom section + "\03\f1\80\23" ;; "\f1\80#" + ) + "invalid UTF-8 encoding" +) + +;; 4-byte sequence contains 1 byte at end of string +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\00\02" ;; custom section + "\01\f1" ;; "\f1" + ) + "invalid UTF-8 encoding" +) + +;; 4-byte sequence contains 1 byte +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\00\03" ;; custom section + "\02\f1\23" ;; "\f1#" + ) + "invalid UTF-8 encoding" +) + +;;;; 4-byte sequence contents + +;; first byte after (0xf0) 4-byte prefix not a continuation byte +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\00\05" ;; custom section + "\04\f0\00\90\90" ;; "\f0\00\90\90" + ) + "invalid UTF-8 encoding" +) + +;; first byte after (0xf0) 4-byte prefix not a continuation byte +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\00\05" ;; custom section + "\04\f0\7f\90\90" ;; "\f0\7f\90\90" + ) + "invalid UTF-8 encoding" +) + +;; overlong encoding after 0xf0 prefix +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\00\05" ;; custom section + "\04\f0\80\80\80" ;; "\f0\80\80\80" + ) + "invalid UTF-8 encoding" +) + +;; overlong encoding after 0xf0 prefix +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\00\05" ;; custom section + "\04\f0\80\90\90" ;; "\f0\80\90\90" + ) + "invalid UTF-8 encoding" +) + +;; overlong encoding after 0xf0 prefix +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\00\05" ;; custom section + "\04\f0\8f\90\90" ;; "\f0\8f\90\90" + ) + "invalid UTF-8 encoding" +) + +;; overlong encoding after 0xf0 prefix +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\00\05" ;; custom section + "\04\f0\8f\bf\bf" ;; "\f0\8f\bf\bf" + ) + "invalid UTF-8 encoding" +) + +;; first byte after (0xf0) 4-byte prefix not a continuation byte +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\00\05" ;; custom section + "\04\f0\c0\90\90" ;; "\f0\c0\90\90" + ) + "invalid UTF-8 encoding" +) + +;; first byte after (0xf0) 4-byte prefix not a continuation byte +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\00\05" ;; custom section + "\04\f0\fd\90\90" ;; "\f0\fd\90\90" + ) + "invalid UTF-8 encoding" +) + +;; first byte after (first normal) 4-byte prefix not a continuation byte +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\00\05" ;; custom section + "\04\f1\00\80\80" ;; "\f1\00\80\80" + ) + "invalid UTF-8 encoding" +) + +;; first byte after (first normal) 4-byte prefix not a continuation byte +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\00\05" ;; custom section + "\04\f1\7f\80\80" ;; "\f1\7f\80\80" + ) + "invalid UTF-8 encoding" +) + +;; first byte after (first normal) 4-byte prefix not a continuation byte +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\00\05" ;; custom section + "\04\f1\c0\80\80" ;; "\f1\c0\80\80" + ) + "invalid UTF-8 encoding" +) + +;; first byte after (first normal) 4-byte prefix not a continuation byte +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\00\05" ;; custom section + "\04\f1\fd\80\80" ;; "\f1\fd\80\80" + ) + "invalid UTF-8 encoding" +) + +;; first byte after (last normal) 4-byte prefix not a continuation byte +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\00\05" ;; custom section + "\04\f3\00\80\80" ;; "\f3\00\80\80" + ) + "invalid UTF-8 encoding" +) + +;; first byte after (last normal) 4-byte prefix not a continuation byte +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\00\05" ;; custom section + "\04\f3\7f\80\80" ;; "\f3\7f\80\80" + ) + "invalid UTF-8 encoding" +) + +;; first byte after (last normal) 4-byte prefix not a continuation byte +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\00\05" ;; custom section + "\04\f3\c0\80\80" ;; "\f3\c0\80\80" + ) + "invalid UTF-8 encoding" +) + +;; first byte after (last normal) 4-byte prefix not a continuation byte +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\00\05" ;; custom section + "\04\f3\fd\80\80" ;; "\f3\fd\80\80" + ) + "invalid UTF-8 encoding" +) + +;; first byte after (0xf4) 4-byte prefix not a continuation byte +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\00\05" ;; custom section + "\04\f4\00\80\80" ;; "\f4\00\80\80" + ) + "invalid UTF-8 encoding" +) + +;; first byte after (0xf4) 4-byte prefix not a continuation byte +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\00\05" ;; custom section + "\04\f4\7f\80\80" ;; "\f4\7f\80\80" + ) + "invalid UTF-8 encoding" +) + +;; (first) invalid code point +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\00\05" ;; custom section + "\04\f4\90\80\80" ;; "\f4\90\80\80" + ) + "invalid UTF-8 encoding" +) + +;; invalid code point +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\00\05" ;; custom section + "\04\f4\bf\80\80" ;; "\f4\bf\80\80" + ) + "invalid UTF-8 encoding" +) + +;; first byte after (0xf4) 4-byte prefix not a continuation byte +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\00\05" ;; custom section + "\04\f4\c0\80\80" ;; "\f4\c0\80\80" + ) + "invalid UTF-8 encoding" +) + +;; first byte after (0xf4) 4-byte prefix not a continuation byte +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\00\05" ;; custom section + "\04\f4\fd\80\80" ;; "\f4\fd\80\80" + ) + "invalid UTF-8 encoding" +) + +;; (first) invalid 4-byte prefix +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\00\05" ;; custom section + "\04\f5\80\80\80" ;; "\f5\80\80\80" + ) + "invalid UTF-8 encoding" +) + +;; (last) invalid 4-byte prefix +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\00\05" ;; custom section + "\04\f7\80\80\80" ;; "\f7\80\80\80" + ) + "invalid UTF-8 encoding" +) + +;; (last) invalid 4-byte prefix +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\00\05" ;; custom section + "\04\f7\bf\bf\bf" ;; "\f7\bf\bf\bf" + ) + "invalid UTF-8 encoding" +) + +;;;; 4-byte sequence contents (third byte) + +;; second byte after (0xf0) 4-byte prefix not a continuation byte +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\00\05" ;; custom section + "\04\f0\90\00\90" ;; "\f0\90\00\90" + ) + "invalid UTF-8 encoding" +) + +;; second byte after (0xf0) 4-byte prefix not a continuation byte +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\00\05" ;; custom section + "\04\f0\90\7f\90" ;; "\f0\90\7f\90" + ) + "invalid UTF-8 encoding" +) + +;; second byte after (0xf0) 4-byte prefix not a continuation byte +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\00\05" ;; custom section + "\04\f0\90\c0\90" ;; "\f0\90\c0\90" + ) + "invalid UTF-8 encoding" +) + +;; second byte after (0xf0) 4-byte prefix not a continuation byte +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\00\05" ;; custom section + "\04\f0\90\fd\90" ;; "\f0\90\fd\90" + ) + "invalid UTF-8 encoding" +) + +;; second byte after (first normal) 4-byte prefix not a continuation byte +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\00\05" ;; custom section + "\04\f1\80\00\80" ;; "\f1\80\00\80" + ) + "invalid UTF-8 encoding" +) + +;; second byte after (first normal) 4-byte prefix not a continuation byte +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\00\05" ;; custom section + "\04\f1\80\7f\80" ;; "\f1\80\7f\80" + ) + "invalid UTF-8 encoding" +) + +;; second byte after (first normal) 4-byte prefix not a continuation byte +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\00\05" ;; custom section + "\04\f1\80\c0\80" ;; "\f1\80\c0\80" + ) + "invalid UTF-8 encoding" +) + +;; second byte after (first normal) 4-byte prefix not a continuation byte +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\00\05" ;; custom section + "\04\f1\80\fd\80" ;; "\f1\80\fd\80" + ) + "invalid UTF-8 encoding" +) + +;; second byte after (last normal) 4-byte prefix not a continuation byte +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\00\05" ;; custom section + "\04\f3\80\00\80" ;; "\f3\80\00\80" + ) + "invalid UTF-8 encoding" +) + +;; second byte after (last normal) 4-byte prefix not a continuation byte +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\00\05" ;; custom section + "\04\f3\80\7f\80" ;; "\f3\80\7f\80" + ) + "invalid UTF-8 encoding" +) + +;; second byte after (last normal) 4-byte prefix not a continuation byte +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\00\05" ;; custom section + "\04\f3\80\c0\80" ;; "\f3\80\c0\80" + ) + "invalid UTF-8 encoding" +) + +;; second byte after (last normal) 4-byte prefix not a continuation byte +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\00\05" ;; custom section + "\04\f3\80\fd\80" ;; "\f3\80\fd\80" + ) + "invalid UTF-8 encoding" +) + +;; second byte after (0xf4) 4-byte prefix not a continuation byte +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\00\05" ;; custom section + "\04\f4\80\00\80" ;; "\f4\80\00\80" + ) + "invalid UTF-8 encoding" +) + +;; second byte after (0xf4) 4-byte prefix not a continuation byte +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\00\05" ;; custom section + "\04\f4\80\7f\80" ;; "\f4\80\7f\80" + ) + "invalid UTF-8 encoding" +) + +;; second byte after (0xf4) 4-byte prefix not a continuation byte +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\00\05" ;; custom section + "\04\f4\80\c0\80" ;; "\f4\80\c0\80" + ) + "invalid UTF-8 encoding" +) + +;; second byte after (0xf4) 4-byte prefix not a continuation byte +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\00\05" ;; custom section + "\04\f4\80\fd\80" ;; "\f4\80\fd\80" + ) + "invalid UTF-8 encoding" +) + +;;;; 4-byte sequence contents (fourth byte) + +;; third byte after (0xf0) 4-byte prefix not a continuation byte +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\00\05" ;; custom section + "\04\f0\90\90\00" ;; "\f0\90\90\00" + ) + "invalid UTF-8 encoding" +) + +;; third byte after (0xf0) 4-byte prefix not a continuation byte +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\00\05" ;; custom section + "\04\f0\90\90\7f" ;; "\f0\90\90\7f" + ) + "invalid UTF-8 encoding" +) + +;; third byte after (0xf0) 4-byte prefix not a continuation byte +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\00\05" ;; custom section + "\04\f0\90\90\c0" ;; "\f0\90\90\c0" + ) + "invalid UTF-8 encoding" +) + +;; third byte after (0xf0) 4-byte prefix not a continuation byte +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\00\05" ;; custom section + "\04\f0\90\90\fd" ;; "\f0\90\90\fd" + ) + "invalid UTF-8 encoding" +) + +;; third byte after (first normal) 4-byte prefix not a continuation byte +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\00\05" ;; custom section + "\04\f1\80\80\00" ;; "\f1\80\80\00" + ) + "invalid UTF-8 encoding" +) + +;; third byte after (first normal) 4-byte prefix not a continuation byte +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\00\05" ;; custom section + "\04\f1\80\80\7f" ;; "\f1\80\80\7f" + ) + "invalid UTF-8 encoding" +) + +;; third byte after (first normal) 4-byte prefix not a continuation byte +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\00\05" ;; custom section + "\04\f1\80\80\c0" ;; "\f1\80\80\c0" + ) + "invalid UTF-8 encoding" +) + +;; third byte after (first normal) 4-byte prefix not a continuation byte +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\00\05" ;; custom section + "\04\f1\80\80\fd" ;; "\f1\80\80\fd" + ) + "invalid UTF-8 encoding" +) + +;; third byte after (last normal) 4-byte prefix not a continuation byte +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\00\05" ;; custom section + "\04\f3\80\80\00" ;; "\f3\80\80\00" + ) + "invalid UTF-8 encoding" +) + +;; third byte after (last normal) 4-byte prefix not a continuation byte +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\00\05" ;; custom section + "\04\f3\80\80\7f" ;; "\f3\80\80\7f" + ) + "invalid UTF-8 encoding" +) + +;; third byte after (last normal) 4-byte prefix not a continuation byte +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\00\05" ;; custom section + "\04\f3\80\80\c0" ;; "\f3\80\80\c0" + ) + "invalid UTF-8 encoding" +) + +;; third byte after (last normal) 4-byte prefix not a continuation byte +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\00\05" ;; custom section + "\04\f3\80\80\fd" ;; "\f3\80\80\fd" + ) + "invalid UTF-8 encoding" +) + +;; third byte after (0xf4) 4-byte prefix not a continuation byte +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\00\05" ;; custom section + "\04\f4\80\80\00" ;; "\f4\80\80\00" + ) + "invalid UTF-8 encoding" +) + +;; third byte after (0xf4) 4-byte prefix not a continuation byte +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\00\05" ;; custom section + "\04\f4\80\80\7f" ;; "\f4\80\80\7f" + ) + "invalid UTF-8 encoding" +) + +;; third byte after (0xf4) 4-byte prefix not a continuation byte +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\00\05" ;; custom section + "\04\f4\80\80\c0" ;; "\f4\80\80\c0" + ) + "invalid UTF-8 encoding" +) + +;; third byte after (0xf4) 4-byte prefix not a continuation byte +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\00\05" ;; custom section + "\04\f4\80\80\fd" ;; "\f4\80\80\fd" + ) + "invalid UTF-8 encoding" +) + +;;;; 5-byte sequences + +;; 5-byte sequence contains 6 bytes +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\00\07" ;; custom section + "\06\f8\80\80\80\80\80" ;; "\f8\80\80\80\80\80" + ) + "invalid UTF-8 encoding" +) + +;; 5-byte sequence contains 4 bytes at end of string +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\00\05" ;; custom section + "\04\f8\80\80\80" ;; "\f8\80\80\80" + ) + "invalid UTF-8 encoding" +) + +;; 5-byte sequence contains 4 bytes +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\00\06" ;; custom section + "\05\f8\80\80\80\23" ;; "\f8\80\80\80#" + ) + "invalid UTF-8 encoding" +) + +;; 5-byte sequence contains 3 bytes at end of string +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\00\04" ;; custom section + "\03\f8\80\80" ;; "\f8\80\80" + ) + "invalid UTF-8 encoding" +) + +;; 5-byte sequence contains 3 bytes +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\00\05" ;; custom section + "\04\f8\80\80\23" ;; "\f8\80\80#" + ) + "invalid UTF-8 encoding" +) + +;; 5-byte sequence contains 2 bytes at end of string +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\00\03" ;; custom section + "\02\f8\80" ;; "\f8\80" + ) + "invalid UTF-8 encoding" +) + +;; 5-byte sequence contains 2 bytes +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\00\04" ;; custom section + "\03\f8\80\23" ;; "\f8\80#" + ) + "invalid UTF-8 encoding" +) + +;; 5-byte sequence contains 1 byte at end of string +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\00\02" ;; custom section + "\01\f8" ;; "\f8" + ) + "invalid UTF-8 encoding" +) + +;; 5-byte sequence contains 1 byte +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\00\03" ;; custom section + "\02\f8\23" ;; "\f8#" + ) + "invalid UTF-8 encoding" +) + +;;;; 5-byte sequence contents + +;; (first) invalid 5-byte prefix +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\00\06" ;; custom section + "\05\f8\80\80\80\80" ;; "\f8\80\80\80\80" + ) + "invalid UTF-8 encoding" +) + +;; (last) invalid 5-byte prefix +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\00\06" ;; custom section + "\05\fb\bf\bf\bf\bf" ;; "\fb\bf\bf\bf\bf" + ) + "invalid UTF-8 encoding" +) + +;;;; 6-byte sequences + +;; 6-byte sequence contains 7 bytes +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\00\08" ;; custom section + "\07\fc\80\80\80\80\80\80" ;; "\fc\80\80\80\80\80\80" + ) + "invalid UTF-8 encoding" +) + +;; 6-byte sequence contains 5 bytes at end of string +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\00\06" ;; custom section + "\05\fc\80\80\80\80" ;; "\fc\80\80\80\80" + ) + "invalid UTF-8 encoding" +) + +;; 6-byte sequence contains 5 bytes +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\00\07" ;; custom section + "\06\fc\80\80\80\80\23" ;; "\fc\80\80\80\80#" + ) + "invalid UTF-8 encoding" +) + +;; 6-byte sequence contains 4 bytes at end of string +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\00\05" ;; custom section + "\04\fc\80\80\80" ;; "\fc\80\80\80" + ) + "invalid UTF-8 encoding" +) + +;; 6-byte sequence contains 4 bytes +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\00\06" ;; custom section + "\05\fc\80\80\80\23" ;; "\fc\80\80\80#" + ) + "invalid UTF-8 encoding" +) + +;; 6-byte sequence contains 3 bytes at end of string +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\00\04" ;; custom section + "\03\fc\80\80" ;; "\fc\80\80" + ) + "invalid UTF-8 encoding" +) + +;; 6-byte sequence contains 3 bytes +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\00\05" ;; custom section + "\04\fc\80\80\23" ;; "\fc\80\80#" + ) + "invalid UTF-8 encoding" +) + +;; 6-byte sequence contains 2 bytes at end of string +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\00\03" ;; custom section + "\02\fc\80" ;; "\fc\80" + ) + "invalid UTF-8 encoding" +) + +;; 6-byte sequence contains 2 bytes +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\00\04" ;; custom section + "\03\fc\80\23" ;; "\fc\80#" + ) + "invalid UTF-8 encoding" +) + +;; 6-byte sequence contains 1 byte at end of string +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\00\02" ;; custom section + "\01\fc" ;; "\fc" + ) + "invalid UTF-8 encoding" +) + +;; 6-byte sequence contains 1 byte +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\00\03" ;; custom section + "\02\fc\23" ;; "\fc#" + ) + "invalid UTF-8 encoding" +) + +;;;; 6-byte sequence contents + +;; (first) invalid 6-byte prefix +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\00\07" ;; custom section + "\06\fc\80\80\80\80\80" ;; "\fc\80\80\80\80\80" + ) + "invalid UTF-8 encoding" +) + +;; (last) invalid 6-byte prefix +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\00\07" ;; custom section + "\06\fd\bf\bf\bf\bf\bf" ;; "\fd\bf\bf\bf\bf\bf" + ) + "invalid UTF-8 encoding" +) + +;;;; Miscellaneous invalid bytes + +;; invalid byte +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\00\02" ;; custom section + "\01\fe" ;; "\fe" + ) + "invalid UTF-8 encoding" +) + +;; invalid byte +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\00\02" ;; custom section + "\01\ff" ;; "\ff" + ) + "invalid UTF-8 encoding" +) + +;; UTF-16BE BOM +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\00\03" ;; custom section + "\02\fe\ff" ;; "\fe\ff" + ) + "invalid UTF-8 encoding" +) + +;; UTF-32BE BOM +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\00\05" ;; custom section + "\04\00\00\fe\ff" ;; "\00\00\fe\ff" + ) + "invalid UTF-8 encoding" +) + +;; UTF-16LE BOM +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\00\03" ;; custom section + "\02\ff\fe" ;; "\ff\fe" + ) + "invalid UTF-8 encoding" +) + +;; UTF-32LE BOM +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\00\05" ;; custom section + "\04\ff\fe\00\00" ;; "\ff\fe\00\00" + ) + "invalid UTF-8 encoding" +) + diff --git a/test/core/utf8-import-field.wast b/test/core/utf8-import-field.wast new file mode 100644 index 00000000..256eb8a4 --- /dev/null +++ b/test/core/utf8-import-field.wast @@ -0,0 +1,2672 @@ +;;;;;; Invalid UTF-8 import field names + +;;;; Continuation bytes not preceded by prefixes + +;; encoding starts with (first) continuation byte +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\02\0b" ;; import section + "\01" ;; length 1 + "\01\80" ;; "\80" + "\04\74\65\73\74" ;; "test" + "\03" ;; GlobalImport + "\7f" ;; i32 + "\00" ;; immutable + ) + "invalid UTF-8 encoding" +) + +;; encoding starts with (0x8f) continuation byte +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\02\0b" ;; import section + "\01" ;; length 1 + "\01\8f" ;; "\8f" + "\04\74\65\73\74" ;; "test" + "\03" ;; GlobalImport + "\7f" ;; i32 + "\00" ;; immutable + ) + "invalid UTF-8 encoding" +) + +;; encoding starts with (0x90) continuation byte +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\02\0b" ;; import section + "\01" ;; length 1 + "\01\90" ;; "\90" + "\04\74\65\73\74" ;; "test" + "\03" ;; GlobalImport + "\7f" ;; i32 + "\00" ;; immutable + ) + "invalid UTF-8 encoding" +) + +;; encoding starts with (0x9f) continuation byte +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\02\0b" ;; import section + "\01" ;; length 1 + "\01\9f" ;; "\9f" + "\04\74\65\73\74" ;; "test" + "\03" ;; GlobalImport + "\7f" ;; i32 + "\00" ;; immutable + ) + "invalid UTF-8 encoding" +) + +;; encoding starts with (0xa0) continuation byte +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\02\0b" ;; import section + "\01" ;; length 1 + "\01\a0" ;; "\a0" + "\04\74\65\73\74" ;; "test" + "\03" ;; GlobalImport + "\7f" ;; i32 + "\00" ;; immutable + ) + "invalid UTF-8 encoding" +) + +;; encoding starts with (last) continuation byte +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\02\0b" ;; import section + "\01" ;; length 1 + "\01\bf" ;; "\bf" + "\04\74\65\73\74" ;; "test" + "\03" ;; GlobalImport + "\7f" ;; i32 + "\00" ;; immutable + ) + "invalid UTF-8 encoding" +) + +;;;; 2-byte sequences + +;; 2-byte sequence contains 3 bytes +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\02\0d" ;; import section + "\01" ;; length 1 + "\03\c2\80\80" ;; "\c2\80\80" + "\04\74\65\73\74" ;; "test" + "\03" ;; GlobalImport + "\7f" ;; i32 + "\00" ;; immutable + ) + "invalid UTF-8 encoding" +) + +;; 2-byte sequence contains 1 byte at end of string +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\02\0b" ;; import section + "\01" ;; length 1 + "\01\c2" ;; "\c2" + "\04\74\65\73\74" ;; "test" + "\03" ;; GlobalImport + "\7f" ;; i32 + "\00" ;; immutable + ) + "invalid UTF-8 encoding" +) + +;; 2-byte sequence contains 1 byte +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\02\0c" ;; import section + "\01" ;; length 1 + "\02\c2\2e" ;; "\c2." + "\04\74\65\73\74" ;; "test" + "\03" ;; GlobalImport + "\7f" ;; i32 + "\00" ;; immutable + ) + "invalid UTF-8 encoding" +) + +;;;; 2-byte sequence contents + +;; overlong encoding after 0xc0 prefix +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\02\0c" ;; import section + "\01" ;; length 1 + "\02\c0\80" ;; "\c0\80" + "\04\74\65\73\74" ;; "test" + "\03" ;; GlobalImport + "\7f" ;; i32 + "\00" ;; immutable + ) + "invalid UTF-8 encoding" +) + +;; overlong encoding after 0xc0 prefix +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\02\0c" ;; import section + "\01" ;; length 1 + "\02\c0\bf" ;; "\c0\bf" + "\04\74\65\73\74" ;; "test" + "\03" ;; GlobalImport + "\7f" ;; i32 + "\00" ;; immutable + ) + "invalid UTF-8 encoding" +) + +;; overlong encoding after 0xc1 prefix +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\02\0c" ;; import section + "\01" ;; length 1 + "\02\c1\80" ;; "\c1\80" + "\04\74\65\73\74" ;; "test" + "\03" ;; GlobalImport + "\7f" ;; i32 + "\00" ;; immutable + ) + "invalid UTF-8 encoding" +) + +;; overlong encoding after 0xc1 prefix +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\02\0c" ;; import section + "\01" ;; length 1 + "\02\c1\bf" ;; "\c1\bf" + "\04\74\65\73\74" ;; "test" + "\03" ;; GlobalImport + "\7f" ;; i32 + "\00" ;; immutable + ) + "invalid UTF-8 encoding" +) + +;; byte after (first) 2-byte prefix not a contination byte +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\02\0c" ;; import section + "\01" ;; length 1 + "\02\c2\00" ;; "\c2\00" + "\04\74\65\73\74" ;; "test" + "\03" ;; GlobalImport + "\7f" ;; i32 + "\00" ;; immutable + ) + "invalid UTF-8 encoding" +) + +;; byte after (first) 2-byte prefix not a continuation byte +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\02\0c" ;; import section + "\01" ;; length 1 + "\02\c2\7f" ;; "\c2\7f" + "\04\74\65\73\74" ;; "test" + "\03" ;; GlobalImport + "\7f" ;; i32 + "\00" ;; immutable + ) + "invalid UTF-8 encoding" +) + +;; byte after (first) 2-byte prefix not a continuation byte +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\02\0c" ;; import section + "\01" ;; length 1 + "\02\c2\c0" ;; "\c2\c0" + "\04\74\65\73\74" ;; "test" + "\03" ;; GlobalImport + "\7f" ;; i32 + "\00" ;; immutable + ) + "invalid UTF-8 encoding" +) + +;; byte after (first) 2-byte prefix not a continuation byte +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\02\0c" ;; import section + "\01" ;; length 1 + "\02\c2\fd" ;; "\c2\fd" + "\04\74\65\73\74" ;; "test" + "\03" ;; GlobalImport + "\7f" ;; i32 + "\00" ;; immutable + ) + "invalid UTF-8 encoding" +) + +;; byte after (last) 2-byte prefix not a continuation byte +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\02\0c" ;; import section + "\01" ;; length 1 + "\02\df\00" ;; "\df\00" + "\04\74\65\73\74" ;; "test" + "\03" ;; GlobalImport + "\7f" ;; i32 + "\00" ;; immutable + ) + "invalid UTF-8 encoding" +) + +;; byte after (last) 2-byte prefix not a continuation byte +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\02\0c" ;; import section + "\01" ;; length 1 + "\02\df\7f" ;; "\df\7f" + "\04\74\65\73\74" ;; "test" + "\03" ;; GlobalImport + "\7f" ;; i32 + "\00" ;; immutable + ) + "invalid UTF-8 encoding" +) + +;; byte after (last) 2-byte prefix not a continuation byte +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\02\0c" ;; import section + "\01" ;; length 1 + "\02\df\c0" ;; "\df\c0" + "\04\74\65\73\74" ;; "test" + "\03" ;; GlobalImport + "\7f" ;; i32 + "\00" ;; immutable + ) + "invalid UTF-8 encoding" +) + +;; byte after (last) 2-byte prefix not a continuation byte +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\02\0c" ;; import section + "\01" ;; length 1 + "\02\df\fd" ;; "\df\fd" + "\04\74\65\73\74" ;; "test" + "\03" ;; GlobalImport + "\7f" ;; i32 + "\00" ;; immutable + ) + "invalid UTF-8 encoding" +) + +;;;; 3-byte sequences + +;; 3-byte sequence contains 4 bytes +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\02\0e" ;; import section + "\01" ;; length 1 + "\04\e1\80\80\80" ;; "\e1\80\80\80" + "\04\74\65\73\74" ;; "test" + "\03" ;; GlobalImport + "\7f" ;; i32 + "\00" ;; immutable + ) + "invalid UTF-8 encoding" +) + +;; 3-byte sequence contains 2 bytes at end of string +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\02\0c" ;; import section + "\01" ;; length 1 + "\02\e1\80" ;; "\e1\80" + "\04\74\65\73\74" ;; "test" + "\03" ;; GlobalImport + "\7f" ;; i32 + "\00" ;; immutable + ) + "invalid UTF-8 encoding" +) + +;; 3-byte sequence contains 2 bytes +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\02\0d" ;; import section + "\01" ;; length 1 + "\03\e1\80\2e" ;; "\e1\80." + "\04\74\65\73\74" ;; "test" + "\03" ;; GlobalImport + "\7f" ;; i32 + "\00" ;; immutable + ) + "invalid UTF-8 encoding" +) + +;; 3-byte sequence contains 1 byte at end of string +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\02\0b" ;; import section + "\01" ;; length 1 + "\01\e1" ;; "\e1" + "\04\74\65\73\74" ;; "test" + "\03" ;; GlobalImport + "\7f" ;; i32 + "\00" ;; immutable + ) + "invalid UTF-8 encoding" +) + +;; 3-byte sequence contains 1 byte +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\02\0c" ;; import section + "\01" ;; length 1 + "\02\e1\2e" ;; "\e1." + "\04\74\65\73\74" ;; "test" + "\03" ;; GlobalImport + "\7f" ;; i32 + "\00" ;; immutable + ) + "invalid UTF-8 encoding" +) + +;;;; 3-byte sequence contents + +;; first byte after (0xe0) 3-byte prefix not a continuation byte +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\02\0d" ;; import section + "\01" ;; length 1 + "\03\e0\00\a0" ;; "\e0\00\a0" + "\04\74\65\73\74" ;; "test" + "\03" ;; GlobalImport + "\7f" ;; i32 + "\00" ;; immutable + ) + "invalid UTF-8 encoding" +) + +;; first byte after (0xe0) 3-byte prefix not a continuation byte +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\02\0d" ;; import section + "\01" ;; length 1 + "\03\e0\7f\a0" ;; "\e0\7f\a0" + "\04\74\65\73\74" ;; "test" + "\03" ;; GlobalImport + "\7f" ;; i32 + "\00" ;; immutable + ) + "invalid UTF-8 encoding" +) + +;; overlong encoding after 0xe0 prefix +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\02\0d" ;; import section + "\01" ;; length 1 + "\03\e0\80\80" ;; "\e0\80\80" + "\04\74\65\73\74" ;; "test" + "\03" ;; GlobalImport + "\7f" ;; i32 + "\00" ;; immutable + ) + "invalid UTF-8 encoding" +) + +;; overlong encoding after 0xe0 prefix +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\02\0d" ;; import section + "\01" ;; length 1 + "\03\e0\80\a0" ;; "\e0\80\a0" + "\04\74\65\73\74" ;; "test" + "\03" ;; GlobalImport + "\7f" ;; i32 + "\00" ;; immutable + ) + "invalid UTF-8 encoding" +) + +;; overlong encoding after 0xe0 prefix +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\02\0d" ;; import section + "\01" ;; length 1 + "\03\e0\9f\a0" ;; "\e0\9f\a0" + "\04\74\65\73\74" ;; "test" + "\03" ;; GlobalImport + "\7f" ;; i32 + "\00" ;; immutable + ) + "invalid UTF-8 encoding" +) + +;; overlong encoding after 0xe0 prefix +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\02\0d" ;; import section + "\01" ;; length 1 + "\03\e0\9f\bf" ;; "\e0\9f\bf" + "\04\74\65\73\74" ;; "test" + "\03" ;; GlobalImport + "\7f" ;; i32 + "\00" ;; immutable + ) + "invalid UTF-8 encoding" +) + +;; first byte after (0xe0) 3-byte prefix not a continuation byte +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\02\0d" ;; import section + "\01" ;; length 1 + "\03\e0\c0\a0" ;; "\e0\c0\a0" + "\04\74\65\73\74" ;; "test" + "\03" ;; GlobalImport + "\7f" ;; i32 + "\00" ;; immutable + ) + "invalid UTF-8 encoding" +) + +;; first byte after (0xe0) 3-byte prefix not a continuation byte +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\02\0d" ;; import section + "\01" ;; length 1 + "\03\e0\fd\a0" ;; "\e0\fd\a0" + "\04\74\65\73\74" ;; "test" + "\03" ;; GlobalImport + "\7f" ;; i32 + "\00" ;; immutable + ) + "invalid UTF-8 encoding" +) + +;; first byte after (first normal) 3-byte prefix not a continuation byte +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\02\0d" ;; import section + "\01" ;; length 1 + "\03\e1\00\80" ;; "\e1\00\80" + "\04\74\65\73\74" ;; "test" + "\03" ;; GlobalImport + "\7f" ;; i32 + "\00" ;; immutable + ) + "invalid UTF-8 encoding" +) + +;; first byte after (first normal) 3-byte prefix not a continuation byte +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\02\0d" ;; import section + "\01" ;; length 1 + "\03\e1\7f\80" ;; "\e1\7f\80" + "\04\74\65\73\74" ;; "test" + "\03" ;; GlobalImport + "\7f" ;; i32 + "\00" ;; immutable + ) + "invalid UTF-8 encoding" +) + +;; first byte after (first normal) 3-byte prefix not a continuation byte +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\02\0d" ;; import section + "\01" ;; length 1 + "\03\e1\c0\80" ;; "\e1\c0\80" + "\04\74\65\73\74" ;; "test" + "\03" ;; GlobalImport + "\7f" ;; i32 + "\00" ;; immutable + ) + "invalid UTF-8 encoding" +) + +;; first byte after (first normal) 3-byte prefix not a continuation byte +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\02\0d" ;; import section + "\01" ;; length 1 + "\03\e1\fd\80" ;; "\e1\fd\80" + "\04\74\65\73\74" ;; "test" + "\03" ;; GlobalImport + "\7f" ;; i32 + "\00" ;; immutable + ) + "invalid UTF-8 encoding" +) + +;; first byte after (normal) 3-byte prefix not a continuation byte +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\02\0d" ;; import section + "\01" ;; length 1 + "\03\ec\00\80" ;; "\ec\00\80" + "\04\74\65\73\74" ;; "test" + "\03" ;; GlobalImport + "\7f" ;; i32 + "\00" ;; immutable + ) + "invalid UTF-8 encoding" +) + +;; first byte after (normal) 3-byte prefix not a continuation byte +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\02\0d" ;; import section + "\01" ;; length 1 + "\03\ec\7f\80" ;; "\ec\7f\80" + "\04\74\65\73\74" ;; "test" + "\03" ;; GlobalImport + "\7f" ;; i32 + "\00" ;; immutable + ) + "invalid UTF-8 encoding" +) + +;; first byte after (normal) 3-byte prefix not a continuation byte +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\02\0d" ;; import section + "\01" ;; length 1 + "\03\ec\c0\80" ;; "\ec\c0\80" + "\04\74\65\73\74" ;; "test" + "\03" ;; GlobalImport + "\7f" ;; i32 + "\00" ;; immutable + ) + "invalid UTF-8 encoding" +) + +;; first byte after (normal) 3-byte prefix not a continuation byte +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\02\0d" ;; import section + "\01" ;; length 1 + "\03\ec\fd\80" ;; "\ec\fd\80" + "\04\74\65\73\74" ;; "test" + "\03" ;; GlobalImport + "\7f" ;; i32 + "\00" ;; immutable + ) + "invalid UTF-8 encoding" +) + +;; first byte after (0xed) 3-byte prefix not a continuation byte +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\02\0d" ;; import section + "\01" ;; length 1 + "\03\ed\00\80" ;; "\ed\00\80" + "\04\74\65\73\74" ;; "test" + "\03" ;; GlobalImport + "\7f" ;; i32 + "\00" ;; immutable + ) + "invalid UTF-8 encoding" +) + +;; first byte after (0xed) 3-byte prefix not a continuation byte +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\02\0d" ;; import section + "\01" ;; length 1 + "\03\ed\7f\80" ;; "\ed\7f\80" + "\04\74\65\73\74" ;; "test" + "\03" ;; GlobalImport + "\7f" ;; i32 + "\00" ;; immutable + ) + "invalid UTF-8 encoding" +) + +;; byte sequence reserved for UTF-16 surrogate half +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\02\0d" ;; import section + "\01" ;; length 1 + "\03\ed\a0\80" ;; "\ed\a0\80" + "\04\74\65\73\74" ;; "test" + "\03" ;; GlobalImport + "\7f" ;; i32 + "\00" ;; immutable + ) + "invalid UTF-8 encoding" +) + +;; byte sequence reserved for UTF-16 surrogate half +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\02\0d" ;; import section + "\01" ;; length 1 + "\03\ed\a0\bf" ;; "\ed\a0\bf" + "\04\74\65\73\74" ;; "test" + "\03" ;; GlobalImport + "\7f" ;; i32 + "\00" ;; immutable + ) + "invalid UTF-8 encoding" +) + +;; byte sequence reserved for UTF-16 surrogate half +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\02\0d" ;; import section + "\01" ;; length 1 + "\03\ed\bf\80" ;; "\ed\bf\80" + "\04\74\65\73\74" ;; "test" + "\03" ;; GlobalImport + "\7f" ;; i32 + "\00" ;; immutable + ) + "invalid UTF-8 encoding" +) + +;; byte sequence reserved for UTF-16 surrogate half +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\02\0d" ;; import section + "\01" ;; length 1 + "\03\ed\bf\bf" ;; "\ed\bf\bf" + "\04\74\65\73\74" ;; "test" + "\03" ;; GlobalImport + "\7f" ;; i32 + "\00" ;; immutable + ) + "invalid UTF-8 encoding" +) + +;; first byte after (0xed) 3-byte prefix not a continuation byte +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\02\0d" ;; import section + "\01" ;; length 1 + "\03\ed\c0\80" ;; "\ed\c0\80" + "\04\74\65\73\74" ;; "test" + "\03" ;; GlobalImport + "\7f" ;; i32 + "\00" ;; immutable + ) + "invalid UTF-8 encoding" +) + +;; first byte after (0xed) 3-byte prefix not a continuation byte +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\02\0d" ;; import section + "\01" ;; length 1 + "\03\ed\fd\80" ;; "\ed\fd\80" + "\04\74\65\73\74" ;; "test" + "\03" ;; GlobalImport + "\7f" ;; i32 + "\00" ;; immutable + ) + "invalid UTF-8 encoding" +) + +;; first byte after (normal) 3-byte prefix not a continuation byte +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\02\0d" ;; import section + "\01" ;; length 1 + "\03\ee\00\80" ;; "\ee\00\80" + "\04\74\65\73\74" ;; "test" + "\03" ;; GlobalImport + "\7f" ;; i32 + "\00" ;; immutable + ) + "invalid UTF-8 encoding" +) + +;; first byte after (normal) 3-byte prefix not a continuation byte +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\02\0d" ;; import section + "\01" ;; length 1 + "\03\ee\7f\80" ;; "\ee\7f\80" + "\04\74\65\73\74" ;; "test" + "\03" ;; GlobalImport + "\7f" ;; i32 + "\00" ;; immutable + ) + "invalid UTF-8 encoding" +) + +;; first byte after (normal) 3-byte prefix not a continuation byte +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\02\0d" ;; import section + "\01" ;; length 1 + "\03\ee\c0\80" ;; "\ee\c0\80" + "\04\74\65\73\74" ;; "test" + "\03" ;; GlobalImport + "\7f" ;; i32 + "\00" ;; immutable + ) + "invalid UTF-8 encoding" +) + +;; first byte after (normal) 3-byte prefix not a continuation byte +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\02\0d" ;; import section + "\01" ;; length 1 + "\03\ee\fd\80" ;; "\ee\fd\80" + "\04\74\65\73\74" ;; "test" + "\03" ;; GlobalImport + "\7f" ;; i32 + "\00" ;; immutable + ) + "invalid UTF-8 encoding" +) + +;; first byte after (last normal) 3-byte prefix not a continuation byte +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\02\0d" ;; import section + "\01" ;; length 1 + "\03\ef\00\80" ;; "\ef\00\80" + "\04\74\65\73\74" ;; "test" + "\03" ;; GlobalImport + "\7f" ;; i32 + "\00" ;; immutable + ) + "invalid UTF-8 encoding" +) + +;; first byte after (last normal) 3-byte prefix not a continuation byte +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\02\0d" ;; import section + "\01" ;; length 1 + "\03\ef\7f\80" ;; "\ef\7f\80" + "\04\74\65\73\74" ;; "test" + "\03" ;; GlobalImport + "\7f" ;; i32 + "\00" ;; immutable + ) + "invalid UTF-8 encoding" +) + +;; first byte after (last normal) 3-byte prefix not a continuation byte +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\02\0d" ;; import section + "\01" ;; length 1 + "\03\ef\c0\80" ;; "\ef\c0\80" + "\04\74\65\73\74" ;; "test" + "\03" ;; GlobalImport + "\7f" ;; i32 + "\00" ;; immutable + ) + "invalid UTF-8 encoding" +) + +;; first byte after (last normal) 3-byte prefix not a continuation byte +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\02\0d" ;; import section + "\01" ;; length 1 + "\03\ef\fd\80" ;; "\ef\fd\80" + "\04\74\65\73\74" ;; "test" + "\03" ;; GlobalImport + "\7f" ;; i32 + "\00" ;; immutable + ) + "invalid UTF-8 encoding" +) + +;;;; 3-byte sequence contents (third byte) + +;; second byte after (0xe0) 3-byte prefix not a continuation byte +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\02\0d" ;; import section + "\01" ;; length 1 + "\03\e0\a0\00" ;; "\e0\a0\00" + "\04\74\65\73\74" ;; "test" + "\03" ;; GlobalImport + "\7f" ;; i32 + "\00" ;; immutable + ) + "invalid UTF-8 encoding" +) + +;; second byte after (0xe0) 3-byte prefix not a continuation byte +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\02\0d" ;; import section + "\01" ;; length 1 + "\03\e0\a0\7f" ;; "\e0\a0\7f" + "\04\74\65\73\74" ;; "test" + "\03" ;; GlobalImport + "\7f" ;; i32 + "\00" ;; immutable + ) + "invalid UTF-8 encoding" +) + +;; second byte after (0xe0) 3-byte prefix not a continuation byte +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\02\0d" ;; import section + "\01" ;; length 1 + "\03\e0\a0\c0" ;; "\e0\a0\c0" + "\04\74\65\73\74" ;; "test" + "\03" ;; GlobalImport + "\7f" ;; i32 + "\00" ;; immutable + ) + "invalid UTF-8 encoding" +) + +;; second byte after (0xe0) 3-byte prefix not a continuation byte +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\02\0d" ;; import section + "\01" ;; length 1 + "\03\e0\a0\fd" ;; "\e0\a0\fd" + "\04\74\65\73\74" ;; "test" + "\03" ;; GlobalImport + "\7f" ;; i32 + "\00" ;; immutable + ) + "invalid UTF-8 encoding" +) + +;; second byte after (first normal) 3-byte prefix not a continuation byte +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\02\0d" ;; import section + "\01" ;; length 1 + "\03\e1\80\00" ;; "\e1\80\00" + "\04\74\65\73\74" ;; "test" + "\03" ;; GlobalImport + "\7f" ;; i32 + "\00" ;; immutable + ) + "invalid UTF-8 encoding" +) + +;; second byte after (first normal) 3-byte prefix not a continuation byte +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\02\0d" ;; import section + "\01" ;; length 1 + "\03\e1\80\7f" ;; "\e1\80\7f" + "\04\74\65\73\74" ;; "test" + "\03" ;; GlobalImport + "\7f" ;; i32 + "\00" ;; immutable + ) + "invalid UTF-8 encoding" +) + +;; second byte after (first normal) 3-byte prefix not a continuation byte +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\02\0d" ;; import section + "\01" ;; length 1 + "\03\e1\80\c0" ;; "\e1\80\c0" + "\04\74\65\73\74" ;; "test" + "\03" ;; GlobalImport + "\7f" ;; i32 + "\00" ;; immutable + ) + "invalid UTF-8 encoding" +) + +;; second byte after (first normal) 3-byte prefix not a continuation byte +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\02\0d" ;; import section + "\01" ;; length 1 + "\03\e1\80\fd" ;; "\e1\80\fd" + "\04\74\65\73\74" ;; "test" + "\03" ;; GlobalImport + "\7f" ;; i32 + "\00" ;; immutable + ) + "invalid UTF-8 encoding" +) + +;; second byte after (normal) 3-byte prefix not a continuation byte +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\02\0d" ;; import section + "\01" ;; length 1 + "\03\ec\80\00" ;; "\ec\80\00" + "\04\74\65\73\74" ;; "test" + "\03" ;; GlobalImport + "\7f" ;; i32 + "\00" ;; immutable + ) + "invalid UTF-8 encoding" +) + +;; second byte after (normal) 3-byte prefix not a continuation byte +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\02\0d" ;; import section + "\01" ;; length 1 + "\03\ec\80\7f" ;; "\ec\80\7f" + "\04\74\65\73\74" ;; "test" + "\03" ;; GlobalImport + "\7f" ;; i32 + "\00" ;; immutable + ) + "invalid UTF-8 encoding" +) + +;; second byte after (normal) 3-byte prefix not a continuation byte +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\02\0d" ;; import section + "\01" ;; length 1 + "\03\ec\80\c0" ;; "\ec\80\c0" + "\04\74\65\73\74" ;; "test" + "\03" ;; GlobalImport + "\7f" ;; i32 + "\00" ;; immutable + ) + "invalid UTF-8 encoding" +) + +;; second byte after (normal) 3-byte prefix not a continuation byte +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\02\0d" ;; import section + "\01" ;; length 1 + "\03\ec\80\fd" ;; "\ec\80\fd" + "\04\74\65\73\74" ;; "test" + "\03" ;; GlobalImport + "\7f" ;; i32 + "\00" ;; immutable + ) + "invalid UTF-8 encoding" +) + +;; second byte after (0xed) 3-byte prefix not a continuation byte +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\02\0d" ;; import section + "\01" ;; length 1 + "\03\ed\80\00" ;; "\ed\80\00" + "\04\74\65\73\74" ;; "test" + "\03" ;; GlobalImport + "\7f" ;; i32 + "\00" ;; immutable + ) + "invalid UTF-8 encoding" +) + +;; second byte after (0xed) 3-byte prefix not a continuation byte +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\02\0d" ;; import section + "\01" ;; length 1 + "\03\ed\80\7f" ;; "\ed\80\7f" + "\04\74\65\73\74" ;; "test" + "\03" ;; GlobalImport + "\7f" ;; i32 + "\00" ;; immutable + ) + "invalid UTF-8 encoding" +) + +;; second byte after (0xed) 3-byte prefix not a continuation byte +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\02\0d" ;; import section + "\01" ;; length 1 + "\03\ed\80\c0" ;; "\ed\80\c0" + "\04\74\65\73\74" ;; "test" + "\03" ;; GlobalImport + "\7f" ;; i32 + "\00" ;; immutable + ) + "invalid UTF-8 encoding" +) + +;; second byte after (0xed) 3-byte prefix not a continuation byte +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\02\0d" ;; import section + "\01" ;; length 1 + "\03\ed\80\fd" ;; "\ed\80\fd" + "\04\74\65\73\74" ;; "test" + "\03" ;; GlobalImport + "\7f" ;; i32 + "\00" ;; immutable + ) + "invalid UTF-8 encoding" +) + +;; second byte after (normal) 3-byte prefix not a continuation byte +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\02\0d" ;; import section + "\01" ;; length 1 + "\03\ee\80\00" ;; "\ee\80\00" + "\04\74\65\73\74" ;; "test" + "\03" ;; GlobalImport + "\7f" ;; i32 + "\00" ;; immutable + ) + "invalid UTF-8 encoding" +) + +;; second byte after (normal) 3-byte prefix not a continuation byte +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\02\0d" ;; import section + "\01" ;; length 1 + "\03\ee\80\7f" ;; "\ee\80\7f" + "\04\74\65\73\74" ;; "test" + "\03" ;; GlobalImport + "\7f" ;; i32 + "\00" ;; immutable + ) + "invalid UTF-8 encoding" +) + +;; second byte after (normal) 3-byte prefix not a continuation byte +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\02\0d" ;; import section + "\01" ;; length 1 + "\03\ee\80\c0" ;; "\ee\80\c0" + "\04\74\65\73\74" ;; "test" + "\03" ;; GlobalImport + "\7f" ;; i32 + "\00" ;; immutable + ) + "invalid UTF-8 encoding" +) + +;; second byte after (normal) 3-byte prefix not a continuation byte +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\02\0d" ;; import section + "\01" ;; length 1 + "\03\ee\80\fd" ;; "\ee\80\fd" + "\04\74\65\73\74" ;; "test" + "\03" ;; GlobalImport + "\7f" ;; i32 + "\00" ;; immutable + ) + "invalid UTF-8 encoding" +) + +;; second byte after (last normal) 3-byte prefix not a continuation byte +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\02\0d" ;; import section + "\01" ;; length 1 + "\03\ef\80\00" ;; "\ef\80\00" + "\04\74\65\73\74" ;; "test" + "\03" ;; GlobalImport + "\7f" ;; i32 + "\00" ;; immutable + ) + "invalid UTF-8 encoding" +) + +;; second byte after (last normal) 3-byte prefix not a continuation byte +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\02\0d" ;; import section + "\01" ;; length 1 + "\03\ef\80\7f" ;; "\ef\80\7f" + "\04\74\65\73\74" ;; "test" + "\03" ;; GlobalImport + "\7f" ;; i32 + "\00" ;; immutable + ) + "invalid UTF-8 encoding" +) + +;; second byte after (last normal) 3-byte prefix not a continuation byte +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\02\0d" ;; import section + "\01" ;; length 1 + "\03\ef\80\c0" ;; "\ef\80\c0" + "\04\74\65\73\74" ;; "test" + "\03" ;; GlobalImport + "\7f" ;; i32 + "\00" ;; immutable + ) + "invalid UTF-8 encoding" +) + +;; second byte after (last normal) 3-byte prefix not a continuation byte +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\02\0d" ;; import section + "\01" ;; length 1 + "\03\ef\80\fd" ;; "\ef\80\fd" + "\04\74\65\73\74" ;; "test" + "\03" ;; GlobalImport + "\7f" ;; i32 + "\00" ;; immutable + ) + "invalid UTF-8 encoding" +) + +;;;; 4-byte sequences + +;; 4-byte sequence contains 5 bytes +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\02\0f" ;; import section + "\01" ;; length 1 + "\05\f1\80\80\80\80" ;; "\f1\80\80\80\80" + "\04\74\65\73\74" ;; "test" + "\03" ;; GlobalImport + "\7f" ;; i32 + "\00" ;; immutable + ) + "invalid UTF-8 encoding" +) + +;; 4-byte sequence contains 3 bytes at end of string +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\02\0d" ;; import section + "\01" ;; length 1 + "\03\f1\80\80" ;; "\f1\80\80" + "\04\74\65\73\74" ;; "test" + "\03" ;; GlobalImport + "\7f" ;; i32 + "\00" ;; immutable + ) + "invalid UTF-8 encoding" +) + +;; 4-byte sequence contains 3 bytes +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\02\0e" ;; import section + "\01" ;; length 1 + "\04\f1\80\80\23" ;; "\f1\80\80#" + "\04\74\65\73\74" ;; "test" + "\03" ;; GlobalImport + "\7f" ;; i32 + "\00" ;; immutable + ) + "invalid UTF-8 encoding" +) + +;; 4-byte sequence contains 2 bytes at end of string +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\02\0c" ;; import section + "\01" ;; length 1 + "\02\f1\80" ;; "\f1\80" + "\04\74\65\73\74" ;; "test" + "\03" ;; GlobalImport + "\7f" ;; i32 + "\00" ;; immutable + ) + "invalid UTF-8 encoding" +) + +;; 4-byte sequence contains 2 bytes +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\02\0d" ;; import section + "\01" ;; length 1 + "\03\f1\80\23" ;; "\f1\80#" + "\04\74\65\73\74" ;; "test" + "\03" ;; GlobalImport + "\7f" ;; i32 + "\00" ;; immutable + ) + "invalid UTF-8 encoding" +) + +;; 4-byte sequence contains 1 byte at end of string +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\02\0b" ;; import section + "\01" ;; length 1 + "\01\f1" ;; "\f1" + "\04\74\65\73\74" ;; "test" + "\03" ;; GlobalImport + "\7f" ;; i32 + "\00" ;; immutable + ) + "invalid UTF-8 encoding" +) + +;; 4-byte sequence contains 1 byte +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\02\0c" ;; import section + "\01" ;; length 1 + "\02\f1\23" ;; "\f1#" + "\04\74\65\73\74" ;; "test" + "\03" ;; GlobalImport + "\7f" ;; i32 + "\00" ;; immutable + ) + "invalid UTF-8 encoding" +) + +;;;; 4-byte sequence contents + +;; first byte after (0xf0) 4-byte prefix not a continuation byte +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\02\0e" ;; import section + "\01" ;; length 1 + "\04\f0\00\90\90" ;; "\f0\00\90\90" + "\04\74\65\73\74" ;; "test" + "\03" ;; GlobalImport + "\7f" ;; i32 + "\00" ;; immutable + ) + "invalid UTF-8 encoding" +) + +;; first byte after (0xf0) 4-byte prefix not a continuation byte +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\02\0e" ;; import section + "\01" ;; length 1 + "\04\f0\7f\90\90" ;; "\f0\7f\90\90" + "\04\74\65\73\74" ;; "test" + "\03" ;; GlobalImport + "\7f" ;; i32 + "\00" ;; immutable + ) + "invalid UTF-8 encoding" +) + +;; overlong encoding after 0xf0 prefix +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\02\0e" ;; import section + "\01" ;; length 1 + "\04\f0\80\80\80" ;; "\f0\80\80\80" + "\04\74\65\73\74" ;; "test" + "\03" ;; GlobalImport + "\7f" ;; i32 + "\00" ;; immutable + ) + "invalid UTF-8 encoding" +) + +;; overlong encoding after 0xf0 prefix +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\02\0e" ;; import section + "\01" ;; length 1 + "\04\f0\80\90\90" ;; "\f0\80\90\90" + "\04\74\65\73\74" ;; "test" + "\03" ;; GlobalImport + "\7f" ;; i32 + "\00" ;; immutable + ) + "invalid UTF-8 encoding" +) + +;; overlong encoding after 0xf0 prefix +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\02\0e" ;; import section + "\01" ;; length 1 + "\04\f0\8f\90\90" ;; "\f0\8f\90\90" + "\04\74\65\73\74" ;; "test" + "\03" ;; GlobalImport + "\7f" ;; i32 + "\00" ;; immutable + ) + "invalid UTF-8 encoding" +) + +;; overlong encoding after 0xf0 prefix +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\02\0e" ;; import section + "\01" ;; length 1 + "\04\f0\8f\bf\bf" ;; "\f0\8f\bf\bf" + "\04\74\65\73\74" ;; "test" + "\03" ;; GlobalImport + "\7f" ;; i32 + "\00" ;; immutable + ) + "invalid UTF-8 encoding" +) + +;; first byte after (0xf0) 4-byte prefix not a continuation byte +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\02\0e" ;; import section + "\01" ;; length 1 + "\04\f0\c0\90\90" ;; "\f0\c0\90\90" + "\04\74\65\73\74" ;; "test" + "\03" ;; GlobalImport + "\7f" ;; i32 + "\00" ;; immutable + ) + "invalid UTF-8 encoding" +) + +;; first byte after (0xf0) 4-byte prefix not a continuation byte +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\02\0e" ;; import section + "\01" ;; length 1 + "\04\f0\fd\90\90" ;; "\f0\fd\90\90" + "\04\74\65\73\74" ;; "test" + "\03" ;; GlobalImport + "\7f" ;; i32 + "\00" ;; immutable + ) + "invalid UTF-8 encoding" +) + +;; first byte after (first normal) 4-byte prefix not a continuation byte +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\02\0e" ;; import section + "\01" ;; length 1 + "\04\f1\00\80\80" ;; "\f1\00\80\80" + "\04\74\65\73\74" ;; "test" + "\03" ;; GlobalImport + "\7f" ;; i32 + "\00" ;; immutable + ) + "invalid UTF-8 encoding" +) + +;; first byte after (first normal) 4-byte prefix not a continuation byte +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\02\0e" ;; import section + "\01" ;; length 1 + "\04\f1\7f\80\80" ;; "\f1\7f\80\80" + "\04\74\65\73\74" ;; "test" + "\03" ;; GlobalImport + "\7f" ;; i32 + "\00" ;; immutable + ) + "invalid UTF-8 encoding" +) + +;; first byte after (first normal) 4-byte prefix not a continuation byte +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\02\0e" ;; import section + "\01" ;; length 1 + "\04\f1\c0\80\80" ;; "\f1\c0\80\80" + "\04\74\65\73\74" ;; "test" + "\03" ;; GlobalImport + "\7f" ;; i32 + "\00" ;; immutable + ) + "invalid UTF-8 encoding" +) + +;; first byte after (first normal) 4-byte prefix not a continuation byte +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\02\0e" ;; import section + "\01" ;; length 1 + "\04\f1\fd\80\80" ;; "\f1\fd\80\80" + "\04\74\65\73\74" ;; "test" + "\03" ;; GlobalImport + "\7f" ;; i32 + "\00" ;; immutable + ) + "invalid UTF-8 encoding" +) + +;; first byte after (last normal) 4-byte prefix not a continuation byte +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\02\0e" ;; import section + "\01" ;; length 1 + "\04\f3\00\80\80" ;; "\f3\00\80\80" + "\04\74\65\73\74" ;; "test" + "\03" ;; GlobalImport + "\7f" ;; i32 + "\00" ;; immutable + ) + "invalid UTF-8 encoding" +) + +;; first byte after (last normal) 4-byte prefix not a continuation byte +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\02\0e" ;; import section + "\01" ;; length 1 + "\04\f3\7f\80\80" ;; "\f3\7f\80\80" + "\04\74\65\73\74" ;; "test" + "\03" ;; GlobalImport + "\7f" ;; i32 + "\00" ;; immutable + ) + "invalid UTF-8 encoding" +) + +;; first byte after (last normal) 4-byte prefix not a continuation byte +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\02\0e" ;; import section + "\01" ;; length 1 + "\04\f3\c0\80\80" ;; "\f3\c0\80\80" + "\04\74\65\73\74" ;; "test" + "\03" ;; GlobalImport + "\7f" ;; i32 + "\00" ;; immutable + ) + "invalid UTF-8 encoding" +) + +;; first byte after (last normal) 4-byte prefix not a continuation byte +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\02\0e" ;; import section + "\01" ;; length 1 + "\04\f3\fd\80\80" ;; "\f3\fd\80\80" + "\04\74\65\73\74" ;; "test" + "\03" ;; GlobalImport + "\7f" ;; i32 + "\00" ;; immutable + ) + "invalid UTF-8 encoding" +) + +;; first byte after (0xf4) 4-byte prefix not a continuation byte +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\02\0e" ;; import section + "\01" ;; length 1 + "\04\f4\00\80\80" ;; "\f4\00\80\80" + "\04\74\65\73\74" ;; "test" + "\03" ;; GlobalImport + "\7f" ;; i32 + "\00" ;; immutable + ) + "invalid UTF-8 encoding" +) + +;; first byte after (0xf4) 4-byte prefix not a continuation byte +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\02\0e" ;; import section + "\01" ;; length 1 + "\04\f4\7f\80\80" ;; "\f4\7f\80\80" + "\04\74\65\73\74" ;; "test" + "\03" ;; GlobalImport + "\7f" ;; i32 + "\00" ;; immutable + ) + "invalid UTF-8 encoding" +) + +;; (first) invalid code point +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\02\0e" ;; import section + "\01" ;; length 1 + "\04\f4\90\80\80" ;; "\f4\90\80\80" + "\04\74\65\73\74" ;; "test" + "\03" ;; GlobalImport + "\7f" ;; i32 + "\00" ;; immutable + ) + "invalid UTF-8 encoding" +) + +;; invalid code point +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\02\0e" ;; import section + "\01" ;; length 1 + "\04\f4\bf\80\80" ;; "\f4\bf\80\80" + "\04\74\65\73\74" ;; "test" + "\03" ;; GlobalImport + "\7f" ;; i32 + "\00" ;; immutable + ) + "invalid UTF-8 encoding" +) + +;; first byte after (0xf4) 4-byte prefix not a continuation byte +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\02\0e" ;; import section + "\01" ;; length 1 + "\04\f4\c0\80\80" ;; "\f4\c0\80\80" + "\04\74\65\73\74" ;; "test" + "\03" ;; GlobalImport + "\7f" ;; i32 + "\00" ;; immutable + ) + "invalid UTF-8 encoding" +) + +;; first byte after (0xf4) 4-byte prefix not a continuation byte +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\02\0e" ;; import section + "\01" ;; length 1 + "\04\f4\fd\80\80" ;; "\f4\fd\80\80" + "\04\74\65\73\74" ;; "test" + "\03" ;; GlobalImport + "\7f" ;; i32 + "\00" ;; immutable + ) + "invalid UTF-8 encoding" +) + +;; (first) invalid 4-byte prefix +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\02\0e" ;; import section + "\01" ;; length 1 + "\04\f5\80\80\80" ;; "\f5\80\80\80" + "\04\74\65\73\74" ;; "test" + "\03" ;; GlobalImport + "\7f" ;; i32 + "\00" ;; immutable + ) + "invalid UTF-8 encoding" +) + +;; (last) invalid 4-byte prefix +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\02\0e" ;; import section + "\01" ;; length 1 + "\04\f7\80\80\80" ;; "\f7\80\80\80" + "\04\74\65\73\74" ;; "test" + "\03" ;; GlobalImport + "\7f" ;; i32 + "\00" ;; immutable + ) + "invalid UTF-8 encoding" +) + +;; (last) invalid 4-byte prefix +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\02\0e" ;; import section + "\01" ;; length 1 + "\04\f7\bf\bf\bf" ;; "\f7\bf\bf\bf" + "\04\74\65\73\74" ;; "test" + "\03" ;; GlobalImport + "\7f" ;; i32 + "\00" ;; immutable + ) + "invalid UTF-8 encoding" +) + +;;;; 4-byte sequence contents (third byte) + +;; second byte after (0xf0) 4-byte prefix not a continuation byte +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\02\0e" ;; import section + "\01" ;; length 1 + "\04\f0\90\00\90" ;; "\f0\90\00\90" + "\04\74\65\73\74" ;; "test" + "\03" ;; GlobalImport + "\7f" ;; i32 + "\00" ;; immutable + ) + "invalid UTF-8 encoding" +) + +;; second byte after (0xf0) 4-byte prefix not a continuation byte +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\02\0e" ;; import section + "\01" ;; length 1 + "\04\f0\90\7f\90" ;; "\f0\90\7f\90" + "\04\74\65\73\74" ;; "test" + "\03" ;; GlobalImport + "\7f" ;; i32 + "\00" ;; immutable + ) + "invalid UTF-8 encoding" +) + +;; second byte after (0xf0) 4-byte prefix not a continuation byte +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\02\0e" ;; import section + "\01" ;; length 1 + "\04\f0\90\c0\90" ;; "\f0\90\c0\90" + "\04\74\65\73\74" ;; "test" + "\03" ;; GlobalImport + "\7f" ;; i32 + "\00" ;; immutable + ) + "invalid UTF-8 encoding" +) + +;; second byte after (0xf0) 4-byte prefix not a continuation byte +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\02\0e" ;; import section + "\01" ;; length 1 + "\04\f0\90\fd\90" ;; "\f0\90\fd\90" + "\04\74\65\73\74" ;; "test" + "\03" ;; GlobalImport + "\7f" ;; i32 + "\00" ;; immutable + ) + "invalid UTF-8 encoding" +) + +;; second byte after (first normal) 4-byte prefix not a continuation byte +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\02\0e" ;; import section + "\01" ;; length 1 + "\04\f1\80\00\80" ;; "\f1\80\00\80" + "\04\74\65\73\74" ;; "test" + "\03" ;; GlobalImport + "\7f" ;; i32 + "\00" ;; immutable + ) + "invalid UTF-8 encoding" +) + +;; second byte after (first normal) 4-byte prefix not a continuation byte +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\02\0e" ;; import section + "\01" ;; length 1 + "\04\f1\80\7f\80" ;; "\f1\80\7f\80" + "\04\74\65\73\74" ;; "test" + "\03" ;; GlobalImport + "\7f" ;; i32 + "\00" ;; immutable + ) + "invalid UTF-8 encoding" +) + +;; second byte after (first normal) 4-byte prefix not a continuation byte +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\02\0e" ;; import section + "\01" ;; length 1 + "\04\f1\80\c0\80" ;; "\f1\80\c0\80" + "\04\74\65\73\74" ;; "test" + "\03" ;; GlobalImport + "\7f" ;; i32 + "\00" ;; immutable + ) + "invalid UTF-8 encoding" +) + +;; second byte after (first normal) 4-byte prefix not a continuation byte +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\02\0e" ;; import section + "\01" ;; length 1 + "\04\f1\80\fd\80" ;; "\f1\80\fd\80" + "\04\74\65\73\74" ;; "test" + "\03" ;; GlobalImport + "\7f" ;; i32 + "\00" ;; immutable + ) + "invalid UTF-8 encoding" +) + +;; second byte after (last normal) 4-byte prefix not a continuation byte +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\02\0e" ;; import section + "\01" ;; length 1 + "\04\f3\80\00\80" ;; "\f3\80\00\80" + "\04\74\65\73\74" ;; "test" + "\03" ;; GlobalImport + "\7f" ;; i32 + "\00" ;; immutable + ) + "invalid UTF-8 encoding" +) + +;; second byte after (last normal) 4-byte prefix not a continuation byte +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\02\0e" ;; import section + "\01" ;; length 1 + "\04\f3\80\7f\80" ;; "\f3\80\7f\80" + "\04\74\65\73\74" ;; "test" + "\03" ;; GlobalImport + "\7f" ;; i32 + "\00" ;; immutable + ) + "invalid UTF-8 encoding" +) + +;; second byte after (last normal) 4-byte prefix not a continuation byte +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\02\0e" ;; import section + "\01" ;; length 1 + "\04\f3\80\c0\80" ;; "\f3\80\c0\80" + "\04\74\65\73\74" ;; "test" + "\03" ;; GlobalImport + "\7f" ;; i32 + "\00" ;; immutable + ) + "invalid UTF-8 encoding" +) + +;; second byte after (last normal) 4-byte prefix not a continuation byte +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\02\0e" ;; import section + "\01" ;; length 1 + "\04\f3\80\fd\80" ;; "\f3\80\fd\80" + "\04\74\65\73\74" ;; "test" + "\03" ;; GlobalImport + "\7f" ;; i32 + "\00" ;; immutable + ) + "invalid UTF-8 encoding" +) + +;; second byte after (0xf4) 4-byte prefix not a continuation byte +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\02\0e" ;; import section + "\01" ;; length 1 + "\04\f4\80\00\80" ;; "\f4\80\00\80" + "\04\74\65\73\74" ;; "test" + "\03" ;; GlobalImport + "\7f" ;; i32 + "\00" ;; immutable + ) + "invalid UTF-8 encoding" +) + +;; second byte after (0xf4) 4-byte prefix not a continuation byte +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\02\0e" ;; import section + "\01" ;; length 1 + "\04\f4\80\7f\80" ;; "\f4\80\7f\80" + "\04\74\65\73\74" ;; "test" + "\03" ;; GlobalImport + "\7f" ;; i32 + "\00" ;; immutable + ) + "invalid UTF-8 encoding" +) + +;; second byte after (0xf4) 4-byte prefix not a continuation byte +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\02\0e" ;; import section + "\01" ;; length 1 + "\04\f4\80\c0\80" ;; "\f4\80\c0\80" + "\04\74\65\73\74" ;; "test" + "\03" ;; GlobalImport + "\7f" ;; i32 + "\00" ;; immutable + ) + "invalid UTF-8 encoding" +) + +;; second byte after (0xf4) 4-byte prefix not a continuation byte +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\02\0e" ;; import section + "\01" ;; length 1 + "\04\f4\80\fd\80" ;; "\f4\80\fd\80" + "\04\74\65\73\74" ;; "test" + "\03" ;; GlobalImport + "\7f" ;; i32 + "\00" ;; immutable + ) + "invalid UTF-8 encoding" +) + +;;;; 4-byte sequence contents (fourth byte) + +;; third byte after (0xf0) 4-byte prefix not a continuation byte +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\02\0e" ;; import section + "\01" ;; length 1 + "\04\f0\90\90\00" ;; "\f0\90\90\00" + "\04\74\65\73\74" ;; "test" + "\03" ;; GlobalImport + "\7f" ;; i32 + "\00" ;; immutable + ) + "invalid UTF-8 encoding" +) + +;; third byte after (0xf0) 4-byte prefix not a continuation byte +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\02\0e" ;; import section + "\01" ;; length 1 + "\04\f0\90\90\7f" ;; "\f0\90\90\7f" + "\04\74\65\73\74" ;; "test" + "\03" ;; GlobalImport + "\7f" ;; i32 + "\00" ;; immutable + ) + "invalid UTF-8 encoding" +) + +;; third byte after (0xf0) 4-byte prefix not a continuation byte +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\02\0e" ;; import section + "\01" ;; length 1 + "\04\f0\90\90\c0" ;; "\f0\90\90\c0" + "\04\74\65\73\74" ;; "test" + "\03" ;; GlobalImport + "\7f" ;; i32 + "\00" ;; immutable + ) + "invalid UTF-8 encoding" +) + +;; third byte after (0xf0) 4-byte prefix not a continuation byte +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\02\0e" ;; import section + "\01" ;; length 1 + "\04\f0\90\90\fd" ;; "\f0\90\90\fd" + "\04\74\65\73\74" ;; "test" + "\03" ;; GlobalImport + "\7f" ;; i32 + "\00" ;; immutable + ) + "invalid UTF-8 encoding" +) + +;; third byte after (first normal) 4-byte prefix not a continuation byte +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\02\0e" ;; import section + "\01" ;; length 1 + "\04\f1\80\80\00" ;; "\f1\80\80\00" + "\04\74\65\73\74" ;; "test" + "\03" ;; GlobalImport + "\7f" ;; i32 + "\00" ;; immutable + ) + "invalid UTF-8 encoding" +) + +;; third byte after (first normal) 4-byte prefix not a continuation byte +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\02\0e" ;; import section + "\01" ;; length 1 + "\04\f1\80\80\7f" ;; "\f1\80\80\7f" + "\04\74\65\73\74" ;; "test" + "\03" ;; GlobalImport + "\7f" ;; i32 + "\00" ;; immutable + ) + "invalid UTF-8 encoding" +) + +;; third byte after (first normal) 4-byte prefix not a continuation byte +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\02\0e" ;; import section + "\01" ;; length 1 + "\04\f1\80\80\c0" ;; "\f1\80\80\c0" + "\04\74\65\73\74" ;; "test" + "\03" ;; GlobalImport + "\7f" ;; i32 + "\00" ;; immutable + ) + "invalid UTF-8 encoding" +) + +;; third byte after (first normal) 4-byte prefix not a continuation byte +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\02\0e" ;; import section + "\01" ;; length 1 + "\04\f1\80\80\fd" ;; "\f1\80\80\fd" + "\04\74\65\73\74" ;; "test" + "\03" ;; GlobalImport + "\7f" ;; i32 + "\00" ;; immutable + ) + "invalid UTF-8 encoding" +) + +;; third byte after (last normal) 4-byte prefix not a continuation byte +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\02\0e" ;; import section + "\01" ;; length 1 + "\04\f3\80\80\00" ;; "\f3\80\80\00" + "\04\74\65\73\74" ;; "test" + "\03" ;; GlobalImport + "\7f" ;; i32 + "\00" ;; immutable + ) + "invalid UTF-8 encoding" +) + +;; third byte after (last normal) 4-byte prefix not a continuation byte +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\02\0e" ;; import section + "\01" ;; length 1 + "\04\f3\80\80\7f" ;; "\f3\80\80\7f" + "\04\74\65\73\74" ;; "test" + "\03" ;; GlobalImport + "\7f" ;; i32 + "\00" ;; immutable + ) + "invalid UTF-8 encoding" +) + +;; third byte after (last normal) 4-byte prefix not a continuation byte +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\02\0e" ;; import section + "\01" ;; length 1 + "\04\f3\80\80\c0" ;; "\f3\80\80\c0" + "\04\74\65\73\74" ;; "test" + "\03" ;; GlobalImport + "\7f" ;; i32 + "\00" ;; immutable + ) + "invalid UTF-8 encoding" +) + +;; third byte after (last normal) 4-byte prefix not a continuation byte +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\02\0e" ;; import section + "\01" ;; length 1 + "\04\f3\80\80\fd" ;; "\f3\80\80\fd" + "\04\74\65\73\74" ;; "test" + "\03" ;; GlobalImport + "\7f" ;; i32 + "\00" ;; immutable + ) + "invalid UTF-8 encoding" +) + +;; third byte after (0xf4) 4-byte prefix not a continuation byte +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\02\0e" ;; import section + "\01" ;; length 1 + "\04\f4\80\80\00" ;; "\f4\80\80\00" + "\04\74\65\73\74" ;; "test" + "\03" ;; GlobalImport + "\7f" ;; i32 + "\00" ;; immutable + ) + "invalid UTF-8 encoding" +) + +;; third byte after (0xf4) 4-byte prefix not a continuation byte +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\02\0e" ;; import section + "\01" ;; length 1 + "\04\f4\80\80\7f" ;; "\f4\80\80\7f" + "\04\74\65\73\74" ;; "test" + "\03" ;; GlobalImport + "\7f" ;; i32 + "\00" ;; immutable + ) + "invalid UTF-8 encoding" +) + +;; third byte after (0xf4) 4-byte prefix not a continuation byte +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\02\0e" ;; import section + "\01" ;; length 1 + "\04\f4\80\80\c0" ;; "\f4\80\80\c0" + "\04\74\65\73\74" ;; "test" + "\03" ;; GlobalImport + "\7f" ;; i32 + "\00" ;; immutable + ) + "invalid UTF-8 encoding" +) + +;; third byte after (0xf4) 4-byte prefix not a continuation byte +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\02\0e" ;; import section + "\01" ;; length 1 + "\04\f4\80\80\fd" ;; "\f4\80\80\fd" + "\04\74\65\73\74" ;; "test" + "\03" ;; GlobalImport + "\7f" ;; i32 + "\00" ;; immutable + ) + "invalid UTF-8 encoding" +) + +;;;; 5-byte sequences + +;; 5-byte sequence contains 6 bytes +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\02\10" ;; import section + "\01" ;; length 1 + "\06\f8\80\80\80\80\80" ;; "\f8\80\80\80\80\80" + "\04\74\65\73\74" ;; "test" + "\03" ;; GlobalImport + "\7f" ;; i32 + "\00" ;; immutable + ) + "invalid UTF-8 encoding" +) + +;; 5-byte sequence contains 4 bytes at end of string +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\02\0e" ;; import section + "\01" ;; length 1 + "\04\f8\80\80\80" ;; "\f8\80\80\80" + "\04\74\65\73\74" ;; "test" + "\03" ;; GlobalImport + "\7f" ;; i32 + "\00" ;; immutable + ) + "invalid UTF-8 encoding" +) + +;; 5-byte sequence contains 4 bytes +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\02\0f" ;; import section + "\01" ;; length 1 + "\05\f8\80\80\80\23" ;; "\f8\80\80\80#" + "\04\74\65\73\74" ;; "test" + "\03" ;; GlobalImport + "\7f" ;; i32 + "\00" ;; immutable + ) + "invalid UTF-8 encoding" +) + +;; 5-byte sequence contains 3 bytes at end of string +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\02\0d" ;; import section + "\01" ;; length 1 + "\03\f8\80\80" ;; "\f8\80\80" + "\04\74\65\73\74" ;; "test" + "\03" ;; GlobalImport + "\7f" ;; i32 + "\00" ;; immutable + ) + "invalid UTF-8 encoding" +) + +;; 5-byte sequence contains 3 bytes +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\02\0e" ;; import section + "\01" ;; length 1 + "\04\f8\80\80\23" ;; "\f8\80\80#" + "\04\74\65\73\74" ;; "test" + "\03" ;; GlobalImport + "\7f" ;; i32 + "\00" ;; immutable + ) + "invalid UTF-8 encoding" +) + +;; 5-byte sequence contains 2 bytes at end of string +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\02\0c" ;; import section + "\01" ;; length 1 + "\02\f8\80" ;; "\f8\80" + "\04\74\65\73\74" ;; "test" + "\03" ;; GlobalImport + "\7f" ;; i32 + "\00" ;; immutable + ) + "invalid UTF-8 encoding" +) + +;; 5-byte sequence contains 2 bytes +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\02\0d" ;; import section + "\01" ;; length 1 + "\03\f8\80\23" ;; "\f8\80#" + "\04\74\65\73\74" ;; "test" + "\03" ;; GlobalImport + "\7f" ;; i32 + "\00" ;; immutable + ) + "invalid UTF-8 encoding" +) + +;; 5-byte sequence contains 1 byte at end of string +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\02\0b" ;; import section + "\01" ;; length 1 + "\01\f8" ;; "\f8" + "\04\74\65\73\74" ;; "test" + "\03" ;; GlobalImport + "\7f" ;; i32 + "\00" ;; immutable + ) + "invalid UTF-8 encoding" +) + +;; 5-byte sequence contains 1 byte +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\02\0c" ;; import section + "\01" ;; length 1 + "\02\f8\23" ;; "\f8#" + "\04\74\65\73\74" ;; "test" + "\03" ;; GlobalImport + "\7f" ;; i32 + "\00" ;; immutable + ) + "invalid UTF-8 encoding" +) + +;;;; 5-byte sequence contents + +;; (first) invalid 5-byte prefix +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\02\0f" ;; import section + "\01" ;; length 1 + "\05\f8\80\80\80\80" ;; "\f8\80\80\80\80" + "\04\74\65\73\74" ;; "test" + "\03" ;; GlobalImport + "\7f" ;; i32 + "\00" ;; immutable + ) + "invalid UTF-8 encoding" +) + +;; (last) invalid 5-byte prefix +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\02\0f" ;; import section + "\01" ;; length 1 + "\05\fb\bf\bf\bf\bf" ;; "\fb\bf\bf\bf\bf" + "\04\74\65\73\74" ;; "test" + "\03" ;; GlobalImport + "\7f" ;; i32 + "\00" ;; immutable + ) + "invalid UTF-8 encoding" +) + +;;;; 6-byte sequences + +;; 6-byte sequence contains 7 bytes +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\02\11" ;; import section + "\01" ;; length 1 + "\07\fc\80\80\80\80\80\80" ;; "\fc\80\80\80\80\80\80" + "\04\74\65\73\74" ;; "test" + "\03" ;; GlobalImport + "\7f" ;; i32 + "\00" ;; immutable + ) + "invalid UTF-8 encoding" +) + +;; 6-byte sequence contains 5 bytes at end of string +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\02\0f" ;; import section + "\01" ;; length 1 + "\05\fc\80\80\80\80" ;; "\fc\80\80\80\80" + "\04\74\65\73\74" ;; "test" + "\03" ;; GlobalImport + "\7f" ;; i32 + "\00" ;; immutable + ) + "invalid UTF-8 encoding" +) + +;; 6-byte sequence contains 5 bytes +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\02\10" ;; import section + "\01" ;; length 1 + "\06\fc\80\80\80\80\23" ;; "\fc\80\80\80\80#" + "\04\74\65\73\74" ;; "test" + "\03" ;; GlobalImport + "\7f" ;; i32 + "\00" ;; immutable + ) + "invalid UTF-8 encoding" +) + +;; 6-byte sequence contains 4 bytes at end of string +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\02\0e" ;; import section + "\01" ;; length 1 + "\04\fc\80\80\80" ;; "\fc\80\80\80" + "\04\74\65\73\74" ;; "test" + "\03" ;; GlobalImport + "\7f" ;; i32 + "\00" ;; immutable + ) + "invalid UTF-8 encoding" +) + +;; 6-byte sequence contains 4 bytes +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\02\0f" ;; import section + "\01" ;; length 1 + "\05\fc\80\80\80\23" ;; "\fc\80\80\80#" + "\04\74\65\73\74" ;; "test" + "\03" ;; GlobalImport + "\7f" ;; i32 + "\00" ;; immutable + ) + "invalid UTF-8 encoding" +) + +;; 6-byte sequence contains 3 bytes at end of string +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\02\0d" ;; import section + "\01" ;; length 1 + "\03\fc\80\80" ;; "\fc\80\80" + "\04\74\65\73\74" ;; "test" + "\03" ;; GlobalImport + "\7f" ;; i32 + "\00" ;; immutable + ) + "invalid UTF-8 encoding" +) + +;; 6-byte sequence contains 3 bytes +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\02\0e" ;; import section + "\01" ;; length 1 + "\04\fc\80\80\23" ;; "\fc\80\80#" + "\04\74\65\73\74" ;; "test" + "\03" ;; GlobalImport + "\7f" ;; i32 + "\00" ;; immutable + ) + "invalid UTF-8 encoding" +) + +;; 6-byte sequence contains 2 bytes at end of string +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\02\0c" ;; import section + "\01" ;; length 1 + "\02\fc\80" ;; "\fc\80" + "\04\74\65\73\74" ;; "test" + "\03" ;; GlobalImport + "\7f" ;; i32 + "\00" ;; immutable + ) + "invalid UTF-8 encoding" +) + +;; 6-byte sequence contains 2 bytes +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\02\0d" ;; import section + "\01" ;; length 1 + "\03\fc\80\23" ;; "\fc\80#" + "\04\74\65\73\74" ;; "test" + "\03" ;; GlobalImport + "\7f" ;; i32 + "\00" ;; immutable + ) + "invalid UTF-8 encoding" +) + +;; 6-byte sequence contains 1 byte at end of string +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\02\0b" ;; import section + "\01" ;; length 1 + "\01\fc" ;; "\fc" + "\04\74\65\73\74" ;; "test" + "\03" ;; GlobalImport + "\7f" ;; i32 + "\00" ;; immutable + ) + "invalid UTF-8 encoding" +) + +;; 6-byte sequence contains 1 byte +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\02\0c" ;; import section + "\01" ;; length 1 + "\02\fc\23" ;; "\fc#" + "\04\74\65\73\74" ;; "test" + "\03" ;; GlobalImport + "\7f" ;; i32 + "\00" ;; immutable + ) + "invalid UTF-8 encoding" +) + +;;;; 6-byte sequence contents + +;; (first) invalid 6-byte prefix +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\02\10" ;; import section + "\01" ;; length 1 + "\06\fc\80\80\80\80\80" ;; "\fc\80\80\80\80\80" + "\04\74\65\73\74" ;; "test" + "\03" ;; GlobalImport + "\7f" ;; i32 + "\00" ;; immutable + ) + "invalid UTF-8 encoding" +) + +;; (last) invalid 6-byte prefix +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\02\10" ;; import section + "\01" ;; length 1 + "\06\fd\bf\bf\bf\bf\bf" ;; "\fd\bf\bf\bf\bf\bf" + "\04\74\65\73\74" ;; "test" + "\03" ;; GlobalImport + "\7f" ;; i32 + "\00" ;; immutable + ) + "invalid UTF-8 encoding" +) + +;;;; Miscellaneous invalid bytes + +;; invalid byte +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\02\0b" ;; import section + "\01" ;; length 1 + "\01\fe" ;; "\fe" + "\04\74\65\73\74" ;; "test" + "\03" ;; GlobalImport + "\7f" ;; i32 + "\00" ;; immutable + ) + "invalid UTF-8 encoding" +) + +;; invalid byte +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\02\0b" ;; import section + "\01" ;; length 1 + "\01\ff" ;; "\ff" + "\04\74\65\73\74" ;; "test" + "\03" ;; GlobalImport + "\7f" ;; i32 + "\00" ;; immutable + ) + "invalid UTF-8 encoding" +) + +;; UTF-16BE BOM +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\02\0c" ;; import section + "\01" ;; length 1 + "\02\fe\ff" ;; "\fe\ff" + "\04\74\65\73\74" ;; "test" + "\03" ;; GlobalImport + "\7f" ;; i32 + "\00" ;; immutable + ) + "invalid UTF-8 encoding" +) + +;; UTF-32BE BOM +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\02\0e" ;; import section + "\01" ;; length 1 + "\04\00\00\fe\ff" ;; "\00\00\fe\ff" + "\04\74\65\73\74" ;; "test" + "\03" ;; GlobalImport + "\7f" ;; i32 + "\00" ;; immutable + ) + "invalid UTF-8 encoding" +) + +;; UTF-16LE BOM +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\02\0c" ;; import section + "\01" ;; length 1 + "\02\ff\fe" ;; "\ff\fe" + "\04\74\65\73\74" ;; "test" + "\03" ;; GlobalImport + "\7f" ;; i32 + "\00" ;; immutable + ) + "invalid UTF-8 encoding" +) + +;; UTF-32LE BOM +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\02\0e" ;; import section + "\01" ;; length 1 + "\04\ff\fe\00\00" ;; "\ff\fe\00\00" + "\04\74\65\73\74" ;; "test" + "\03" ;; GlobalImport + "\7f" ;; i32 + "\00" ;; immutable + ) + "invalid UTF-8 encoding" +) + diff --git a/test/core/utf8-import-module.wast b/test/core/utf8-import-module.wast new file mode 100644 index 00000000..900f6bfb --- /dev/null +++ b/test/core/utf8-import-module.wast @@ -0,0 +1,2672 @@ +;;;;;; Invalid UTF-8 import module names + +;;;; Continuation bytes not preceded by prefixes + +;; encoding starts with (first) continuation byte +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\02\0b" ;; import section + "\01" ;; length 1 + "\04\74\65\73\74" ;; "test" + "\01\80" ;; "\80" + "\03" ;; GlobalImport + "\7f" ;; i32 + "\00" ;; immutable + ) + "invalid UTF-8 encoding" +) + +;; encoding starts with (0x8f) continuation byte +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\02\0b" ;; import section + "\01" ;; length 1 + "\04\74\65\73\74" ;; "test" + "\01\8f" ;; "\8f" + "\03" ;; GlobalImport + "\7f" ;; i32 + "\00" ;; immutable + ) + "invalid UTF-8 encoding" +) + +;; encoding starts with (0x90) continuation byte +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\02\0b" ;; import section + "\01" ;; length 1 + "\04\74\65\73\74" ;; "test" + "\01\90" ;; "\90" + "\03" ;; GlobalImport + "\7f" ;; i32 + "\00" ;; immutable + ) + "invalid UTF-8 encoding" +) + +;; encoding starts with (0x9f) continuation byte +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\02\0b" ;; import section + "\01" ;; length 1 + "\04\74\65\73\74" ;; "test" + "\01\9f" ;; "\9f" + "\03" ;; GlobalImport + "\7f" ;; i32 + "\00" ;; immutable + ) + "invalid UTF-8 encoding" +) + +;; encoding starts with (0xa0) continuation byte +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\02\0b" ;; import section + "\01" ;; length 1 + "\04\74\65\73\74" ;; "test" + "\01\a0" ;; "\a0" + "\03" ;; GlobalImport + "\7f" ;; i32 + "\00" ;; immutable + ) + "invalid UTF-8 encoding" +) + +;; encoding starts with (last) continuation byte +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\02\0b" ;; import section + "\01" ;; length 1 + "\04\74\65\73\74" ;; "test" + "\01\bf" ;; "\bf" + "\03" ;; GlobalImport + "\7f" ;; i32 + "\00" ;; immutable + ) + "invalid UTF-8 encoding" +) + +;;;; 2-byte sequences + +;; 2-byte sequence contains 3 bytes +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\02\0d" ;; import section + "\01" ;; length 1 + "\04\74\65\73\74" ;; "test" + "\03\c2\80\80" ;; "\c2\80\80" + "\03" ;; GlobalImport + "\7f" ;; i32 + "\00" ;; immutable + ) + "invalid UTF-8 encoding" +) + +;; 2-byte sequence contains 1 byte at end of string +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\02\0b" ;; import section + "\01" ;; length 1 + "\04\74\65\73\74" ;; "test" + "\01\c2" ;; "\c2" + "\03" ;; GlobalImport + "\7f" ;; i32 + "\00" ;; immutable + ) + "invalid UTF-8 encoding" +) + +;; 2-byte sequence contains 1 byte +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\02\0c" ;; import section + "\01" ;; length 1 + "\04\74\65\73\74" ;; "test" + "\02\c2\2e" ;; "\c2." + "\03" ;; GlobalImport + "\7f" ;; i32 + "\00" ;; immutable + ) + "invalid UTF-8 encoding" +) + +;;;; 2-byte sequence contents + +;; overlong encoding after 0xc0 prefix +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\02\0c" ;; import section + "\01" ;; length 1 + "\04\74\65\73\74" ;; "test" + "\02\c0\80" ;; "\c0\80" + "\03" ;; GlobalImport + "\7f" ;; i32 + "\00" ;; immutable + ) + "invalid UTF-8 encoding" +) + +;; overlong encoding after 0xc0 prefix +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\02\0c" ;; import section + "\01" ;; length 1 + "\04\74\65\73\74" ;; "test" + "\02\c0\bf" ;; "\c0\bf" + "\03" ;; GlobalImport + "\7f" ;; i32 + "\00" ;; immutable + ) + "invalid UTF-8 encoding" +) + +;; overlong encoding after 0xc1 prefix +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\02\0c" ;; import section + "\01" ;; length 1 + "\04\74\65\73\74" ;; "test" + "\02\c1\80" ;; "\c1\80" + "\03" ;; GlobalImport + "\7f" ;; i32 + "\00" ;; immutable + ) + "invalid UTF-8 encoding" +) + +;; overlong encoding after 0xc1 prefix +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\02\0c" ;; import section + "\01" ;; length 1 + "\04\74\65\73\74" ;; "test" + "\02\c1\bf" ;; "\c1\bf" + "\03" ;; GlobalImport + "\7f" ;; i32 + "\00" ;; immutable + ) + "invalid UTF-8 encoding" +) + +;; byte after (first) 2-byte prefix not a contination byte +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\02\0c" ;; import section + "\01" ;; length 1 + "\04\74\65\73\74" ;; "test" + "\02\c2\00" ;; "\c2\00" + "\03" ;; GlobalImport + "\7f" ;; i32 + "\00" ;; immutable + ) + "invalid UTF-8 encoding" +) + +;; byte after (first) 2-byte prefix not a continuation byte +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\02\0c" ;; import section + "\01" ;; length 1 + "\04\74\65\73\74" ;; "test" + "\02\c2\7f" ;; "\c2\7f" + "\03" ;; GlobalImport + "\7f" ;; i32 + "\00" ;; immutable + ) + "invalid UTF-8 encoding" +) + +;; byte after (first) 2-byte prefix not a continuation byte +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\02\0c" ;; import section + "\01" ;; length 1 + "\04\74\65\73\74" ;; "test" + "\02\c2\c0" ;; "\c2\c0" + "\03" ;; GlobalImport + "\7f" ;; i32 + "\00" ;; immutable + ) + "invalid UTF-8 encoding" +) + +;; byte after (first) 2-byte prefix not a continuation byte +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\02\0c" ;; import section + "\01" ;; length 1 + "\04\74\65\73\74" ;; "test" + "\02\c2\fd" ;; "\c2\fd" + "\03" ;; GlobalImport + "\7f" ;; i32 + "\00" ;; immutable + ) + "invalid UTF-8 encoding" +) + +;; byte after (last) 2-byte prefix not a continuation byte +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\02\0c" ;; import section + "\01" ;; length 1 + "\04\74\65\73\74" ;; "test" + "\02\df\00" ;; "\df\00" + "\03" ;; GlobalImport + "\7f" ;; i32 + "\00" ;; immutable + ) + "invalid UTF-8 encoding" +) + +;; byte after (last) 2-byte prefix not a continuation byte +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\02\0c" ;; import section + "\01" ;; length 1 + "\04\74\65\73\74" ;; "test" + "\02\df\7f" ;; "\df\7f" + "\03" ;; GlobalImport + "\7f" ;; i32 + "\00" ;; immutable + ) + "invalid UTF-8 encoding" +) + +;; byte after (last) 2-byte prefix not a continuation byte +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\02\0c" ;; import section + "\01" ;; length 1 + "\04\74\65\73\74" ;; "test" + "\02\df\c0" ;; "\df\c0" + "\03" ;; GlobalImport + "\7f" ;; i32 + "\00" ;; immutable + ) + "invalid UTF-8 encoding" +) + +;; byte after (last) 2-byte prefix not a continuation byte +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\02\0c" ;; import section + "\01" ;; length 1 + "\04\74\65\73\74" ;; "test" + "\02\df\fd" ;; "\df\fd" + "\03" ;; GlobalImport + "\7f" ;; i32 + "\00" ;; immutable + ) + "invalid UTF-8 encoding" +) + +;;;; 3-byte sequences + +;; 3-byte sequence contains 4 bytes +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\02\0e" ;; import section + "\01" ;; length 1 + "\04\74\65\73\74" ;; "test" + "\04\e1\80\80\80" ;; "\e1\80\80\80" + "\03" ;; GlobalImport + "\7f" ;; i32 + "\00" ;; immutable + ) + "invalid UTF-8 encoding" +) + +;; 3-byte sequence contains 2 bytes at end of string +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\02\0c" ;; import section + "\01" ;; length 1 + "\04\74\65\73\74" ;; "test" + "\02\e1\80" ;; "\e1\80" + "\03" ;; GlobalImport + "\7f" ;; i32 + "\00" ;; immutable + ) + "invalid UTF-8 encoding" +) + +;; 3-byte sequence contains 2 bytes +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\02\0d" ;; import section + "\01" ;; length 1 + "\04\74\65\73\74" ;; "test" + "\03\e1\80\2e" ;; "\e1\80." + "\03" ;; GlobalImport + "\7f" ;; i32 + "\00" ;; immutable + ) + "invalid UTF-8 encoding" +) + +;; 3-byte sequence contains 1 byte at end of string +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\02\0b" ;; import section + "\01" ;; length 1 + "\04\74\65\73\74" ;; "test" + "\01\e1" ;; "\e1" + "\03" ;; GlobalImport + "\7f" ;; i32 + "\00" ;; immutable + ) + "invalid UTF-8 encoding" +) + +;; 3-byte sequence contains 1 byte +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\02\0c" ;; import section + "\01" ;; length 1 + "\04\74\65\73\74" ;; "test" + "\02\e1\2e" ;; "\e1." + "\03" ;; GlobalImport + "\7f" ;; i32 + "\00" ;; immutable + ) + "invalid UTF-8 encoding" +) + +;;;; 3-byte sequence contents + +;; first byte after (0xe0) 3-byte prefix not a continuation byte +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\02\0d" ;; import section + "\01" ;; length 1 + "\04\74\65\73\74" ;; "test" + "\03\e0\00\a0" ;; "\e0\00\a0" + "\03" ;; GlobalImport + "\7f" ;; i32 + "\00" ;; immutable + ) + "invalid UTF-8 encoding" +) + +;; first byte after (0xe0) 3-byte prefix not a continuation byte +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\02\0d" ;; import section + "\01" ;; length 1 + "\04\74\65\73\74" ;; "test" + "\03\e0\7f\a0" ;; "\e0\7f\a0" + "\03" ;; GlobalImport + "\7f" ;; i32 + "\00" ;; immutable + ) + "invalid UTF-8 encoding" +) + +;; overlong encoding after 0xe0 prefix +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\02\0d" ;; import section + "\01" ;; length 1 + "\04\74\65\73\74" ;; "test" + "\03\e0\80\80" ;; "\e0\80\80" + "\03" ;; GlobalImport + "\7f" ;; i32 + "\00" ;; immutable + ) + "invalid UTF-8 encoding" +) + +;; overlong encoding after 0xe0 prefix +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\02\0d" ;; import section + "\01" ;; length 1 + "\04\74\65\73\74" ;; "test" + "\03\e0\80\a0" ;; "\e0\80\a0" + "\03" ;; GlobalImport + "\7f" ;; i32 + "\00" ;; immutable + ) + "invalid UTF-8 encoding" +) + +;; overlong encoding after 0xe0 prefix +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\02\0d" ;; import section + "\01" ;; length 1 + "\04\74\65\73\74" ;; "test" + "\03\e0\9f\a0" ;; "\e0\9f\a0" + "\03" ;; GlobalImport + "\7f" ;; i32 + "\00" ;; immutable + ) + "invalid UTF-8 encoding" +) + +;; overlong encoding after 0xe0 prefix +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\02\0d" ;; import section + "\01" ;; length 1 + "\04\74\65\73\74" ;; "test" + "\03\e0\9f\bf" ;; "\e0\9f\bf" + "\03" ;; GlobalImport + "\7f" ;; i32 + "\00" ;; immutable + ) + "invalid UTF-8 encoding" +) + +;; first byte after (0xe0) 3-byte prefix not a continuation byte +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\02\0d" ;; import section + "\01" ;; length 1 + "\04\74\65\73\74" ;; "test" + "\03\e0\c0\a0" ;; "\e0\c0\a0" + "\03" ;; GlobalImport + "\7f" ;; i32 + "\00" ;; immutable + ) + "invalid UTF-8 encoding" +) + +;; first byte after (0xe0) 3-byte prefix not a continuation byte +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\02\0d" ;; import section + "\01" ;; length 1 + "\04\74\65\73\74" ;; "test" + "\03\e0\fd\a0" ;; "\e0\fd\a0" + "\03" ;; GlobalImport + "\7f" ;; i32 + "\00" ;; immutable + ) + "invalid UTF-8 encoding" +) + +;; first byte after (first normal) 3-byte prefix not a continuation byte +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\02\0d" ;; import section + "\01" ;; length 1 + "\04\74\65\73\74" ;; "test" + "\03\e1\00\80" ;; "\e1\00\80" + "\03" ;; GlobalImport + "\7f" ;; i32 + "\00" ;; immutable + ) + "invalid UTF-8 encoding" +) + +;; first byte after (first normal) 3-byte prefix not a continuation byte +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\02\0d" ;; import section + "\01" ;; length 1 + "\04\74\65\73\74" ;; "test" + "\03\e1\7f\80" ;; "\e1\7f\80" + "\03" ;; GlobalImport + "\7f" ;; i32 + "\00" ;; immutable + ) + "invalid UTF-8 encoding" +) + +;; first byte after (first normal) 3-byte prefix not a continuation byte +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\02\0d" ;; import section + "\01" ;; length 1 + "\04\74\65\73\74" ;; "test" + "\03\e1\c0\80" ;; "\e1\c0\80" + "\03" ;; GlobalImport + "\7f" ;; i32 + "\00" ;; immutable + ) + "invalid UTF-8 encoding" +) + +;; first byte after (first normal) 3-byte prefix not a continuation byte +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\02\0d" ;; import section + "\01" ;; length 1 + "\04\74\65\73\74" ;; "test" + "\03\e1\fd\80" ;; "\e1\fd\80" + "\03" ;; GlobalImport + "\7f" ;; i32 + "\00" ;; immutable + ) + "invalid UTF-8 encoding" +) + +;; first byte after (normal) 3-byte prefix not a continuation byte +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\02\0d" ;; import section + "\01" ;; length 1 + "\04\74\65\73\74" ;; "test" + "\03\ec\00\80" ;; "\ec\00\80" + "\03" ;; GlobalImport + "\7f" ;; i32 + "\00" ;; immutable + ) + "invalid UTF-8 encoding" +) + +;; first byte after (normal) 3-byte prefix not a continuation byte +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\02\0d" ;; import section + "\01" ;; length 1 + "\04\74\65\73\74" ;; "test" + "\03\ec\7f\80" ;; "\ec\7f\80" + "\03" ;; GlobalImport + "\7f" ;; i32 + "\00" ;; immutable + ) + "invalid UTF-8 encoding" +) + +;; first byte after (normal) 3-byte prefix not a continuation byte +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\02\0d" ;; import section + "\01" ;; length 1 + "\04\74\65\73\74" ;; "test" + "\03\ec\c0\80" ;; "\ec\c0\80" + "\03" ;; GlobalImport + "\7f" ;; i32 + "\00" ;; immutable + ) + "invalid UTF-8 encoding" +) + +;; first byte after (normal) 3-byte prefix not a continuation byte +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\02\0d" ;; import section + "\01" ;; length 1 + "\04\74\65\73\74" ;; "test" + "\03\ec\fd\80" ;; "\ec\fd\80" + "\03" ;; GlobalImport + "\7f" ;; i32 + "\00" ;; immutable + ) + "invalid UTF-8 encoding" +) + +;; first byte after (0xed) 3-byte prefix not a continuation byte +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\02\0d" ;; import section + "\01" ;; length 1 + "\04\74\65\73\74" ;; "test" + "\03\ed\00\80" ;; "\ed\00\80" + "\03" ;; GlobalImport + "\7f" ;; i32 + "\00" ;; immutable + ) + "invalid UTF-8 encoding" +) + +;; first byte after (0xed) 3-byte prefix not a continuation byte +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\02\0d" ;; import section + "\01" ;; length 1 + "\04\74\65\73\74" ;; "test" + "\03\ed\7f\80" ;; "\ed\7f\80" + "\03" ;; GlobalImport + "\7f" ;; i32 + "\00" ;; immutable + ) + "invalid UTF-8 encoding" +) + +;; byte sequence reserved for UTF-16 surrogate half +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\02\0d" ;; import section + "\01" ;; length 1 + "\04\74\65\73\74" ;; "test" + "\03\ed\a0\80" ;; "\ed\a0\80" + "\03" ;; GlobalImport + "\7f" ;; i32 + "\00" ;; immutable + ) + "invalid UTF-8 encoding" +) + +;; byte sequence reserved for UTF-16 surrogate half +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\02\0d" ;; import section + "\01" ;; length 1 + "\04\74\65\73\74" ;; "test" + "\03\ed\a0\bf" ;; "\ed\a0\bf" + "\03" ;; GlobalImport + "\7f" ;; i32 + "\00" ;; immutable + ) + "invalid UTF-8 encoding" +) + +;; byte sequence reserved for UTF-16 surrogate half +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\02\0d" ;; import section + "\01" ;; length 1 + "\04\74\65\73\74" ;; "test" + "\03\ed\bf\80" ;; "\ed\bf\80" + "\03" ;; GlobalImport + "\7f" ;; i32 + "\00" ;; immutable + ) + "invalid UTF-8 encoding" +) + +;; byte sequence reserved for UTF-16 surrogate half +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\02\0d" ;; import section + "\01" ;; length 1 + "\04\74\65\73\74" ;; "test" + "\03\ed\bf\bf" ;; "\ed\bf\bf" + "\03" ;; GlobalImport + "\7f" ;; i32 + "\00" ;; immutable + ) + "invalid UTF-8 encoding" +) + +;; first byte after (0xed) 3-byte prefix not a continuation byte +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\02\0d" ;; import section + "\01" ;; length 1 + "\04\74\65\73\74" ;; "test" + "\03\ed\c0\80" ;; "\ed\c0\80" + "\03" ;; GlobalImport + "\7f" ;; i32 + "\00" ;; immutable + ) + "invalid UTF-8 encoding" +) + +;; first byte after (0xed) 3-byte prefix not a continuation byte +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\02\0d" ;; import section + "\01" ;; length 1 + "\04\74\65\73\74" ;; "test" + "\03\ed\fd\80" ;; "\ed\fd\80" + "\03" ;; GlobalImport + "\7f" ;; i32 + "\00" ;; immutable + ) + "invalid UTF-8 encoding" +) + +;; first byte after (normal) 3-byte prefix not a continuation byte +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\02\0d" ;; import section + "\01" ;; length 1 + "\04\74\65\73\74" ;; "test" + "\03\ee\00\80" ;; "\ee\00\80" + "\03" ;; GlobalImport + "\7f" ;; i32 + "\00" ;; immutable + ) + "invalid UTF-8 encoding" +) + +;; first byte after (normal) 3-byte prefix not a continuation byte +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\02\0d" ;; import section + "\01" ;; length 1 + "\04\74\65\73\74" ;; "test" + "\03\ee\7f\80" ;; "\ee\7f\80" + "\03" ;; GlobalImport + "\7f" ;; i32 + "\00" ;; immutable + ) + "invalid UTF-8 encoding" +) + +;; first byte after (normal) 3-byte prefix not a continuation byte +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\02\0d" ;; import section + "\01" ;; length 1 + "\04\74\65\73\74" ;; "test" + "\03\ee\c0\80" ;; "\ee\c0\80" + "\03" ;; GlobalImport + "\7f" ;; i32 + "\00" ;; immutable + ) + "invalid UTF-8 encoding" +) + +;; first byte after (normal) 3-byte prefix not a continuation byte +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\02\0d" ;; import section + "\01" ;; length 1 + "\04\74\65\73\74" ;; "test" + "\03\ee\fd\80" ;; "\ee\fd\80" + "\03" ;; GlobalImport + "\7f" ;; i32 + "\00" ;; immutable + ) + "invalid UTF-8 encoding" +) + +;; first byte after (last normal) 3-byte prefix not a continuation byte +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\02\0d" ;; import section + "\01" ;; length 1 + "\04\74\65\73\74" ;; "test" + "\03\ef\00\80" ;; "\ef\00\80" + "\03" ;; GlobalImport + "\7f" ;; i32 + "\00" ;; immutable + ) + "invalid UTF-8 encoding" +) + +;; first byte after (last normal) 3-byte prefix not a continuation byte +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\02\0d" ;; import section + "\01" ;; length 1 + "\04\74\65\73\74" ;; "test" + "\03\ef\7f\80" ;; "\ef\7f\80" + "\03" ;; GlobalImport + "\7f" ;; i32 + "\00" ;; immutable + ) + "invalid UTF-8 encoding" +) + +;; first byte after (last normal) 3-byte prefix not a continuation byte +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\02\0d" ;; import section + "\01" ;; length 1 + "\04\74\65\73\74" ;; "test" + "\03\ef\c0\80" ;; "\ef\c0\80" + "\03" ;; GlobalImport + "\7f" ;; i32 + "\00" ;; immutable + ) + "invalid UTF-8 encoding" +) + +;; first byte after (last normal) 3-byte prefix not a continuation byte +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\02\0d" ;; import section + "\01" ;; length 1 + "\04\74\65\73\74" ;; "test" + "\03\ef\fd\80" ;; "\ef\fd\80" + "\03" ;; GlobalImport + "\7f" ;; i32 + "\00" ;; immutable + ) + "invalid UTF-8 encoding" +) + +;;;; 3-byte sequence contents (third byte) + +;; second byte after (0xe0) 3-byte prefix not a continuation byte +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\02\0d" ;; import section + "\01" ;; length 1 + "\04\74\65\73\74" ;; "test" + "\03\e0\a0\00" ;; "\e0\a0\00" + "\03" ;; GlobalImport + "\7f" ;; i32 + "\00" ;; immutable + ) + "invalid UTF-8 encoding" +) + +;; second byte after (0xe0) 3-byte prefix not a continuation byte +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\02\0d" ;; import section + "\01" ;; length 1 + "\04\74\65\73\74" ;; "test" + "\03\e0\a0\7f" ;; "\e0\a0\7f" + "\03" ;; GlobalImport + "\7f" ;; i32 + "\00" ;; immutable + ) + "invalid UTF-8 encoding" +) + +;; second byte after (0xe0) 3-byte prefix not a continuation byte +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\02\0d" ;; import section + "\01" ;; length 1 + "\04\74\65\73\74" ;; "test" + "\03\e0\a0\c0" ;; "\e0\a0\c0" + "\03" ;; GlobalImport + "\7f" ;; i32 + "\00" ;; immutable + ) + "invalid UTF-8 encoding" +) + +;; second byte after (0xe0) 3-byte prefix not a continuation byte +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\02\0d" ;; import section + "\01" ;; length 1 + "\04\74\65\73\74" ;; "test" + "\03\e0\a0\fd" ;; "\e0\a0\fd" + "\03" ;; GlobalImport + "\7f" ;; i32 + "\00" ;; immutable + ) + "invalid UTF-8 encoding" +) + +;; second byte after (first normal) 3-byte prefix not a continuation byte +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\02\0d" ;; import section + "\01" ;; length 1 + "\04\74\65\73\74" ;; "test" + "\03\e1\80\00" ;; "\e1\80\00" + "\03" ;; GlobalImport + "\7f" ;; i32 + "\00" ;; immutable + ) + "invalid UTF-8 encoding" +) + +;; second byte after (first normal) 3-byte prefix not a continuation byte +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\02\0d" ;; import section + "\01" ;; length 1 + "\04\74\65\73\74" ;; "test" + "\03\e1\80\7f" ;; "\e1\80\7f" + "\03" ;; GlobalImport + "\7f" ;; i32 + "\00" ;; immutable + ) + "invalid UTF-8 encoding" +) + +;; second byte after (first normal) 3-byte prefix not a continuation byte +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\02\0d" ;; import section + "\01" ;; length 1 + "\04\74\65\73\74" ;; "test" + "\03\e1\80\c0" ;; "\e1\80\c0" + "\03" ;; GlobalImport + "\7f" ;; i32 + "\00" ;; immutable + ) + "invalid UTF-8 encoding" +) + +;; second byte after (first normal) 3-byte prefix not a continuation byte +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\02\0d" ;; import section + "\01" ;; length 1 + "\04\74\65\73\74" ;; "test" + "\03\e1\80\fd" ;; "\e1\80\fd" + "\03" ;; GlobalImport + "\7f" ;; i32 + "\00" ;; immutable + ) + "invalid UTF-8 encoding" +) + +;; second byte after (normal) 3-byte prefix not a continuation byte +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\02\0d" ;; import section + "\01" ;; length 1 + "\04\74\65\73\74" ;; "test" + "\03\ec\80\00" ;; "\ec\80\00" + "\03" ;; GlobalImport + "\7f" ;; i32 + "\00" ;; immutable + ) + "invalid UTF-8 encoding" +) + +;; second byte after (normal) 3-byte prefix not a continuation byte +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\02\0d" ;; import section + "\01" ;; length 1 + "\04\74\65\73\74" ;; "test" + "\03\ec\80\7f" ;; "\ec\80\7f" + "\03" ;; GlobalImport + "\7f" ;; i32 + "\00" ;; immutable + ) + "invalid UTF-8 encoding" +) + +;; second byte after (normal) 3-byte prefix not a continuation byte +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\02\0d" ;; import section + "\01" ;; length 1 + "\04\74\65\73\74" ;; "test" + "\03\ec\80\c0" ;; "\ec\80\c0" + "\03" ;; GlobalImport + "\7f" ;; i32 + "\00" ;; immutable + ) + "invalid UTF-8 encoding" +) + +;; second byte after (normal) 3-byte prefix not a continuation byte +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\02\0d" ;; import section + "\01" ;; length 1 + "\04\74\65\73\74" ;; "test" + "\03\ec\80\fd" ;; "\ec\80\fd" + "\03" ;; GlobalImport + "\7f" ;; i32 + "\00" ;; immutable + ) + "invalid UTF-8 encoding" +) + +;; second byte after (0xed) 3-byte prefix not a continuation byte +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\02\0d" ;; import section + "\01" ;; length 1 + "\04\74\65\73\74" ;; "test" + "\03\ed\80\00" ;; "\ed\80\00" + "\03" ;; GlobalImport + "\7f" ;; i32 + "\00" ;; immutable + ) + "invalid UTF-8 encoding" +) + +;; second byte after (0xed) 3-byte prefix not a continuation byte +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\02\0d" ;; import section + "\01" ;; length 1 + "\04\74\65\73\74" ;; "test" + "\03\ed\80\7f" ;; "\ed\80\7f" + "\03" ;; GlobalImport + "\7f" ;; i32 + "\00" ;; immutable + ) + "invalid UTF-8 encoding" +) + +;; second byte after (0xed) 3-byte prefix not a continuation byte +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\02\0d" ;; import section + "\01" ;; length 1 + "\04\74\65\73\74" ;; "test" + "\03\ed\80\c0" ;; "\ed\80\c0" + "\03" ;; GlobalImport + "\7f" ;; i32 + "\00" ;; immutable + ) + "invalid UTF-8 encoding" +) + +;; second byte after (0xed) 3-byte prefix not a continuation byte +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\02\0d" ;; import section + "\01" ;; length 1 + "\04\74\65\73\74" ;; "test" + "\03\ed\80\fd" ;; "\ed\80\fd" + "\03" ;; GlobalImport + "\7f" ;; i32 + "\00" ;; immutable + ) + "invalid UTF-8 encoding" +) + +;; second byte after (normal) 3-byte prefix not a continuation byte +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\02\0d" ;; import section + "\01" ;; length 1 + "\04\74\65\73\74" ;; "test" + "\03\ee\80\00" ;; "\ee\80\00" + "\03" ;; GlobalImport + "\7f" ;; i32 + "\00" ;; immutable + ) + "invalid UTF-8 encoding" +) + +;; second byte after (normal) 3-byte prefix not a continuation byte +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\02\0d" ;; import section + "\01" ;; length 1 + "\04\74\65\73\74" ;; "test" + "\03\ee\80\7f" ;; "\ee\80\7f" + "\03" ;; GlobalImport + "\7f" ;; i32 + "\00" ;; immutable + ) + "invalid UTF-8 encoding" +) + +;; second byte after (normal) 3-byte prefix not a continuation byte +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\02\0d" ;; import section + "\01" ;; length 1 + "\04\74\65\73\74" ;; "test" + "\03\ee\80\c0" ;; "\ee\80\c0" + "\03" ;; GlobalImport + "\7f" ;; i32 + "\00" ;; immutable + ) + "invalid UTF-8 encoding" +) + +;; second byte after (normal) 3-byte prefix not a continuation byte +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\02\0d" ;; import section + "\01" ;; length 1 + "\04\74\65\73\74" ;; "test" + "\03\ee\80\fd" ;; "\ee\80\fd" + "\03" ;; GlobalImport + "\7f" ;; i32 + "\00" ;; immutable + ) + "invalid UTF-8 encoding" +) + +;; second byte after (last normal) 3-byte prefix not a continuation byte +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\02\0d" ;; import section + "\01" ;; length 1 + "\04\74\65\73\74" ;; "test" + "\03\ef\80\00" ;; "\ef\80\00" + "\03" ;; GlobalImport + "\7f" ;; i32 + "\00" ;; immutable + ) + "invalid UTF-8 encoding" +) + +;; second byte after (last normal) 3-byte prefix not a continuation byte +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\02\0d" ;; import section + "\01" ;; length 1 + "\04\74\65\73\74" ;; "test" + "\03\ef\80\7f" ;; "\ef\80\7f" + "\03" ;; GlobalImport + "\7f" ;; i32 + "\00" ;; immutable + ) + "invalid UTF-8 encoding" +) + +;; second byte after (last normal) 3-byte prefix not a continuation byte +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\02\0d" ;; import section + "\01" ;; length 1 + "\04\74\65\73\74" ;; "test" + "\03\ef\80\c0" ;; "\ef\80\c0" + "\03" ;; GlobalImport + "\7f" ;; i32 + "\00" ;; immutable + ) + "invalid UTF-8 encoding" +) + +;; second byte after (last normal) 3-byte prefix not a continuation byte +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\02\0d" ;; import section + "\01" ;; length 1 + "\04\74\65\73\74" ;; "test" + "\03\ef\80\fd" ;; "\ef\80\fd" + "\03" ;; GlobalImport + "\7f" ;; i32 + "\00" ;; immutable + ) + "invalid UTF-8 encoding" +) + +;;;; 4-byte sequences + +;; 4-byte sequence contains 5 bytes +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\02\0f" ;; import section + "\01" ;; length 1 + "\04\74\65\73\74" ;; "test" + "\05\f1\80\80\80\80" ;; "\f1\80\80\80\80" + "\03" ;; GlobalImport + "\7f" ;; i32 + "\00" ;; immutable + ) + "invalid UTF-8 encoding" +) + +;; 4-byte sequence contains 3 bytes at end of string +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\02\0d" ;; import section + "\01" ;; length 1 + "\04\74\65\73\74" ;; "test" + "\03\f1\80\80" ;; "\f1\80\80" + "\03" ;; GlobalImport + "\7f" ;; i32 + "\00" ;; immutable + ) + "invalid UTF-8 encoding" +) + +;; 4-byte sequence contains 3 bytes +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\02\0e" ;; import section + "\01" ;; length 1 + "\04\74\65\73\74" ;; "test" + "\04\f1\80\80\23" ;; "\f1\80\80#" + "\03" ;; GlobalImport + "\7f" ;; i32 + "\00" ;; immutable + ) + "invalid UTF-8 encoding" +) + +;; 4-byte sequence contains 2 bytes at end of string +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\02\0c" ;; import section + "\01" ;; length 1 + "\04\74\65\73\74" ;; "test" + "\02\f1\80" ;; "\f1\80" + "\03" ;; GlobalImport + "\7f" ;; i32 + "\00" ;; immutable + ) + "invalid UTF-8 encoding" +) + +;; 4-byte sequence contains 2 bytes +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\02\0d" ;; import section + "\01" ;; length 1 + "\04\74\65\73\74" ;; "test" + "\03\f1\80\23" ;; "\f1\80#" + "\03" ;; GlobalImport + "\7f" ;; i32 + "\00" ;; immutable + ) + "invalid UTF-8 encoding" +) + +;; 4-byte sequence contains 1 byte at end of string +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\02\0b" ;; import section + "\01" ;; length 1 + "\04\74\65\73\74" ;; "test" + "\01\f1" ;; "\f1" + "\03" ;; GlobalImport + "\7f" ;; i32 + "\00" ;; immutable + ) + "invalid UTF-8 encoding" +) + +;; 4-byte sequence contains 1 byte +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\02\0c" ;; import section + "\01" ;; length 1 + "\04\74\65\73\74" ;; "test" + "\02\f1\23" ;; "\f1#" + "\03" ;; GlobalImport + "\7f" ;; i32 + "\00" ;; immutable + ) + "invalid UTF-8 encoding" +) + +;;;; 4-byte sequence contents + +;; first byte after (0xf0) 4-byte prefix not a continuation byte +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\02\0e" ;; import section + "\01" ;; length 1 + "\04\74\65\73\74" ;; "test" + "\04\f0\00\90\90" ;; "\f0\00\90\90" + "\03" ;; GlobalImport + "\7f" ;; i32 + "\00" ;; immutable + ) + "invalid UTF-8 encoding" +) + +;; first byte after (0xf0) 4-byte prefix not a continuation byte +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\02\0e" ;; import section + "\01" ;; length 1 + "\04\74\65\73\74" ;; "test" + "\04\f0\7f\90\90" ;; "\f0\7f\90\90" + "\03" ;; GlobalImport + "\7f" ;; i32 + "\00" ;; immutable + ) + "invalid UTF-8 encoding" +) + +;; overlong encoding after 0xf0 prefix +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\02\0e" ;; import section + "\01" ;; length 1 + "\04\74\65\73\74" ;; "test" + "\04\f0\80\80\80" ;; "\f0\80\80\80" + "\03" ;; GlobalImport + "\7f" ;; i32 + "\00" ;; immutable + ) + "invalid UTF-8 encoding" +) + +;; overlong encoding after 0xf0 prefix +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\02\0e" ;; import section + "\01" ;; length 1 + "\04\74\65\73\74" ;; "test" + "\04\f0\80\90\90" ;; "\f0\80\90\90" + "\03" ;; GlobalImport + "\7f" ;; i32 + "\00" ;; immutable + ) + "invalid UTF-8 encoding" +) + +;; overlong encoding after 0xf0 prefix +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\02\0e" ;; import section + "\01" ;; length 1 + "\04\74\65\73\74" ;; "test" + "\04\f0\8f\90\90" ;; "\f0\8f\90\90" + "\03" ;; GlobalImport + "\7f" ;; i32 + "\00" ;; immutable + ) + "invalid UTF-8 encoding" +) + +;; overlong encoding after 0xf0 prefix +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\02\0e" ;; import section + "\01" ;; length 1 + "\04\74\65\73\74" ;; "test" + "\04\f0\8f\bf\bf" ;; "\f0\8f\bf\bf" + "\03" ;; GlobalImport + "\7f" ;; i32 + "\00" ;; immutable + ) + "invalid UTF-8 encoding" +) + +;; first byte after (0xf0) 4-byte prefix not a continuation byte +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\02\0e" ;; import section + "\01" ;; length 1 + "\04\74\65\73\74" ;; "test" + "\04\f0\c0\90\90" ;; "\f0\c0\90\90" + "\03" ;; GlobalImport + "\7f" ;; i32 + "\00" ;; immutable + ) + "invalid UTF-8 encoding" +) + +;; first byte after (0xf0) 4-byte prefix not a continuation byte +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\02\0e" ;; import section + "\01" ;; length 1 + "\04\74\65\73\74" ;; "test" + "\04\f0\fd\90\90" ;; "\f0\fd\90\90" + "\03" ;; GlobalImport + "\7f" ;; i32 + "\00" ;; immutable + ) + "invalid UTF-8 encoding" +) + +;; first byte after (first normal) 4-byte prefix not a continuation byte +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\02\0e" ;; import section + "\01" ;; length 1 + "\04\74\65\73\74" ;; "test" + "\04\f1\00\80\80" ;; "\f1\00\80\80" + "\03" ;; GlobalImport + "\7f" ;; i32 + "\00" ;; immutable + ) + "invalid UTF-8 encoding" +) + +;; first byte after (first normal) 4-byte prefix not a continuation byte +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\02\0e" ;; import section + "\01" ;; length 1 + "\04\74\65\73\74" ;; "test" + "\04\f1\7f\80\80" ;; "\f1\7f\80\80" + "\03" ;; GlobalImport + "\7f" ;; i32 + "\00" ;; immutable + ) + "invalid UTF-8 encoding" +) + +;; first byte after (first normal) 4-byte prefix not a continuation byte +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\02\0e" ;; import section + "\01" ;; length 1 + "\04\74\65\73\74" ;; "test" + "\04\f1\c0\80\80" ;; "\f1\c0\80\80" + "\03" ;; GlobalImport + "\7f" ;; i32 + "\00" ;; immutable + ) + "invalid UTF-8 encoding" +) + +;; first byte after (first normal) 4-byte prefix not a continuation byte +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\02\0e" ;; import section + "\01" ;; length 1 + "\04\74\65\73\74" ;; "test" + "\04\f1\fd\80\80" ;; "\f1\fd\80\80" + "\03" ;; GlobalImport + "\7f" ;; i32 + "\00" ;; immutable + ) + "invalid UTF-8 encoding" +) + +;; first byte after (last normal) 4-byte prefix not a continuation byte +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\02\0e" ;; import section + "\01" ;; length 1 + "\04\74\65\73\74" ;; "test" + "\04\f3\00\80\80" ;; "\f3\00\80\80" + "\03" ;; GlobalImport + "\7f" ;; i32 + "\00" ;; immutable + ) + "invalid UTF-8 encoding" +) + +;; first byte after (last normal) 4-byte prefix not a continuation byte +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\02\0e" ;; import section + "\01" ;; length 1 + "\04\74\65\73\74" ;; "test" + "\04\f3\7f\80\80" ;; "\f3\7f\80\80" + "\03" ;; GlobalImport + "\7f" ;; i32 + "\00" ;; immutable + ) + "invalid UTF-8 encoding" +) + +;; first byte after (last normal) 4-byte prefix not a continuation byte +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\02\0e" ;; import section + "\01" ;; length 1 + "\04\74\65\73\74" ;; "test" + "\04\f3\c0\80\80" ;; "\f3\c0\80\80" + "\03" ;; GlobalImport + "\7f" ;; i32 + "\00" ;; immutable + ) + "invalid UTF-8 encoding" +) + +;; first byte after (last normal) 4-byte prefix not a continuation byte +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\02\0e" ;; import section + "\01" ;; length 1 + "\04\74\65\73\74" ;; "test" + "\04\f3\fd\80\80" ;; "\f3\fd\80\80" + "\03" ;; GlobalImport + "\7f" ;; i32 + "\00" ;; immutable + ) + "invalid UTF-8 encoding" +) + +;; first byte after (0xf4) 4-byte prefix not a continuation byte +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\02\0e" ;; import section + "\01" ;; length 1 + "\04\74\65\73\74" ;; "test" + "\04\f4\00\80\80" ;; "\f4\00\80\80" + "\03" ;; GlobalImport + "\7f" ;; i32 + "\00" ;; immutable + ) + "invalid UTF-8 encoding" +) + +;; first byte after (0xf4) 4-byte prefix not a continuation byte +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\02\0e" ;; import section + "\01" ;; length 1 + "\04\74\65\73\74" ;; "test" + "\04\f4\7f\80\80" ;; "\f4\7f\80\80" + "\03" ;; GlobalImport + "\7f" ;; i32 + "\00" ;; immutable + ) + "invalid UTF-8 encoding" +) + +;; (first) invalid code point +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\02\0e" ;; import section + "\01" ;; length 1 + "\04\74\65\73\74" ;; "test" + "\04\f4\90\80\80" ;; "\f4\90\80\80" + "\03" ;; GlobalImport + "\7f" ;; i32 + "\00" ;; immutable + ) + "invalid UTF-8 encoding" +) + +;; invalid code point +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\02\0e" ;; import section + "\01" ;; length 1 + "\04\74\65\73\74" ;; "test" + "\04\f4\bf\80\80" ;; "\f4\bf\80\80" + "\03" ;; GlobalImport + "\7f" ;; i32 + "\00" ;; immutable + ) + "invalid UTF-8 encoding" +) + +;; first byte after (0xf4) 4-byte prefix not a continuation byte +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\02\0e" ;; import section + "\01" ;; length 1 + "\04\74\65\73\74" ;; "test" + "\04\f4\c0\80\80" ;; "\f4\c0\80\80" + "\03" ;; GlobalImport + "\7f" ;; i32 + "\00" ;; immutable + ) + "invalid UTF-8 encoding" +) + +;; first byte after (0xf4) 4-byte prefix not a continuation byte +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\02\0e" ;; import section + "\01" ;; length 1 + "\04\74\65\73\74" ;; "test" + "\04\f4\fd\80\80" ;; "\f4\fd\80\80" + "\03" ;; GlobalImport + "\7f" ;; i32 + "\00" ;; immutable + ) + "invalid UTF-8 encoding" +) + +;; (first) invalid 4-byte prefix +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\02\0e" ;; import section + "\01" ;; length 1 + "\04\74\65\73\74" ;; "test" + "\04\f5\80\80\80" ;; "\f5\80\80\80" + "\03" ;; GlobalImport + "\7f" ;; i32 + "\00" ;; immutable + ) + "invalid UTF-8 encoding" +) + +;; (last) invalid 4-byte prefix +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\02\0e" ;; import section + "\01" ;; length 1 + "\04\74\65\73\74" ;; "test" + "\04\f7\80\80\80" ;; "\f7\80\80\80" + "\03" ;; GlobalImport + "\7f" ;; i32 + "\00" ;; immutable + ) + "invalid UTF-8 encoding" +) + +;; (last) invalid 4-byte prefix +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\02\0e" ;; import section + "\01" ;; length 1 + "\04\74\65\73\74" ;; "test" + "\04\f7\bf\bf\bf" ;; "\f7\bf\bf\bf" + "\03" ;; GlobalImport + "\7f" ;; i32 + "\00" ;; immutable + ) + "invalid UTF-8 encoding" +) + +;;;; 4-byte sequence contents (third byte) + +;; second byte after (0xf0) 4-byte prefix not a continuation byte +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\02\0e" ;; import section + "\01" ;; length 1 + "\04\74\65\73\74" ;; "test" + "\04\f0\90\00\90" ;; "\f0\90\00\90" + "\03" ;; GlobalImport + "\7f" ;; i32 + "\00" ;; immutable + ) + "invalid UTF-8 encoding" +) + +;; second byte after (0xf0) 4-byte prefix not a continuation byte +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\02\0e" ;; import section + "\01" ;; length 1 + "\04\74\65\73\74" ;; "test" + "\04\f0\90\7f\90" ;; "\f0\90\7f\90" + "\03" ;; GlobalImport + "\7f" ;; i32 + "\00" ;; immutable + ) + "invalid UTF-8 encoding" +) + +;; second byte after (0xf0) 4-byte prefix not a continuation byte +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\02\0e" ;; import section + "\01" ;; length 1 + "\04\74\65\73\74" ;; "test" + "\04\f0\90\c0\90" ;; "\f0\90\c0\90" + "\03" ;; GlobalImport + "\7f" ;; i32 + "\00" ;; immutable + ) + "invalid UTF-8 encoding" +) + +;; second byte after (0xf0) 4-byte prefix not a continuation byte +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\02\0e" ;; import section + "\01" ;; length 1 + "\04\74\65\73\74" ;; "test" + "\04\f0\90\fd\90" ;; "\f0\90\fd\90" + "\03" ;; GlobalImport + "\7f" ;; i32 + "\00" ;; immutable + ) + "invalid UTF-8 encoding" +) + +;; second byte after (first normal) 4-byte prefix not a continuation byte +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\02\0e" ;; import section + "\01" ;; length 1 + "\04\74\65\73\74" ;; "test" + "\04\f1\80\00\80" ;; "\f1\80\00\80" + "\03" ;; GlobalImport + "\7f" ;; i32 + "\00" ;; immutable + ) + "invalid UTF-8 encoding" +) + +;; second byte after (first normal) 4-byte prefix not a continuation byte +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\02\0e" ;; import section + "\01" ;; length 1 + "\04\74\65\73\74" ;; "test" + "\04\f1\80\7f\80" ;; "\f1\80\7f\80" + "\03" ;; GlobalImport + "\7f" ;; i32 + "\00" ;; immutable + ) + "invalid UTF-8 encoding" +) + +;; second byte after (first normal) 4-byte prefix not a continuation byte +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\02\0e" ;; import section + "\01" ;; length 1 + "\04\74\65\73\74" ;; "test" + "\04\f1\80\c0\80" ;; "\f1\80\c0\80" + "\03" ;; GlobalImport + "\7f" ;; i32 + "\00" ;; immutable + ) + "invalid UTF-8 encoding" +) + +;; second byte after (first normal) 4-byte prefix not a continuation byte +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\02\0e" ;; import section + "\01" ;; length 1 + "\04\74\65\73\74" ;; "test" + "\04\f1\80\fd\80" ;; "\f1\80\fd\80" + "\03" ;; GlobalImport + "\7f" ;; i32 + "\00" ;; immutable + ) + "invalid UTF-8 encoding" +) + +;; second byte after (last normal) 4-byte prefix not a continuation byte +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\02\0e" ;; import section + "\01" ;; length 1 + "\04\74\65\73\74" ;; "test" + "\04\f3\80\00\80" ;; "\f3\80\00\80" + "\03" ;; GlobalImport + "\7f" ;; i32 + "\00" ;; immutable + ) + "invalid UTF-8 encoding" +) + +;; second byte after (last normal) 4-byte prefix not a continuation byte +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\02\0e" ;; import section + "\01" ;; length 1 + "\04\74\65\73\74" ;; "test" + "\04\f3\80\7f\80" ;; "\f3\80\7f\80" + "\03" ;; GlobalImport + "\7f" ;; i32 + "\00" ;; immutable + ) + "invalid UTF-8 encoding" +) + +;; second byte after (last normal) 4-byte prefix not a continuation byte +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\02\0e" ;; import section + "\01" ;; length 1 + "\04\74\65\73\74" ;; "test" + "\04\f3\80\c0\80" ;; "\f3\80\c0\80" + "\03" ;; GlobalImport + "\7f" ;; i32 + "\00" ;; immutable + ) + "invalid UTF-8 encoding" +) + +;; second byte after (last normal) 4-byte prefix not a continuation byte +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\02\0e" ;; import section + "\01" ;; length 1 + "\04\74\65\73\74" ;; "test" + "\04\f3\80\fd\80" ;; "\f3\80\fd\80" + "\03" ;; GlobalImport + "\7f" ;; i32 + "\00" ;; immutable + ) + "invalid UTF-8 encoding" +) + +;; second byte after (0xf4) 4-byte prefix not a continuation byte +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\02\0e" ;; import section + "\01" ;; length 1 + "\04\74\65\73\74" ;; "test" + "\04\f4\80\00\80" ;; "\f4\80\00\80" + "\03" ;; GlobalImport + "\7f" ;; i32 + "\00" ;; immutable + ) + "invalid UTF-8 encoding" +) + +;; second byte after (0xf4) 4-byte prefix not a continuation byte +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\02\0e" ;; import section + "\01" ;; length 1 + "\04\74\65\73\74" ;; "test" + "\04\f4\80\7f\80" ;; "\f4\80\7f\80" + "\03" ;; GlobalImport + "\7f" ;; i32 + "\00" ;; immutable + ) + "invalid UTF-8 encoding" +) + +;; second byte after (0xf4) 4-byte prefix not a continuation byte +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\02\0e" ;; import section + "\01" ;; length 1 + "\04\74\65\73\74" ;; "test" + "\04\f4\80\c0\80" ;; "\f4\80\c0\80" + "\03" ;; GlobalImport + "\7f" ;; i32 + "\00" ;; immutable + ) + "invalid UTF-8 encoding" +) + +;; second byte after (0xf4) 4-byte prefix not a continuation byte +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\02\0e" ;; import section + "\01" ;; length 1 + "\04\74\65\73\74" ;; "test" + "\04\f4\80\fd\80" ;; "\f4\80\fd\80" + "\03" ;; GlobalImport + "\7f" ;; i32 + "\00" ;; immutable + ) + "invalid UTF-8 encoding" +) + +;;;; 4-byte sequence contents (fourth byte) + +;; third byte after (0xf0) 4-byte prefix not a continuation byte +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\02\0e" ;; import section + "\01" ;; length 1 + "\04\74\65\73\74" ;; "test" + "\04\f0\90\90\00" ;; "\f0\90\90\00" + "\03" ;; GlobalImport + "\7f" ;; i32 + "\00" ;; immutable + ) + "invalid UTF-8 encoding" +) + +;; third byte after (0xf0) 4-byte prefix not a continuation byte +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\02\0e" ;; import section + "\01" ;; length 1 + "\04\74\65\73\74" ;; "test" + "\04\f0\90\90\7f" ;; "\f0\90\90\7f" + "\03" ;; GlobalImport + "\7f" ;; i32 + "\00" ;; immutable + ) + "invalid UTF-8 encoding" +) + +;; third byte after (0xf0) 4-byte prefix not a continuation byte +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\02\0e" ;; import section + "\01" ;; length 1 + "\04\74\65\73\74" ;; "test" + "\04\f0\90\90\c0" ;; "\f0\90\90\c0" + "\03" ;; GlobalImport + "\7f" ;; i32 + "\00" ;; immutable + ) + "invalid UTF-8 encoding" +) + +;; third byte after (0xf0) 4-byte prefix not a continuation byte +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\02\0e" ;; import section + "\01" ;; length 1 + "\04\74\65\73\74" ;; "test" + "\04\f0\90\90\fd" ;; "\f0\90\90\fd" + "\03" ;; GlobalImport + "\7f" ;; i32 + "\00" ;; immutable + ) + "invalid UTF-8 encoding" +) + +;; third byte after (first normal) 4-byte prefix not a continuation byte +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\02\0e" ;; import section + "\01" ;; length 1 + "\04\74\65\73\74" ;; "test" + "\04\f1\80\80\00" ;; "\f1\80\80\00" + "\03" ;; GlobalImport + "\7f" ;; i32 + "\00" ;; immutable + ) + "invalid UTF-8 encoding" +) + +;; third byte after (first normal) 4-byte prefix not a continuation byte +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\02\0e" ;; import section + "\01" ;; length 1 + "\04\74\65\73\74" ;; "test" + "\04\f1\80\80\7f" ;; "\f1\80\80\7f" + "\03" ;; GlobalImport + "\7f" ;; i32 + "\00" ;; immutable + ) + "invalid UTF-8 encoding" +) + +;; third byte after (first normal) 4-byte prefix not a continuation byte +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\02\0e" ;; import section + "\01" ;; length 1 + "\04\74\65\73\74" ;; "test" + "\04\f1\80\80\c0" ;; "\f1\80\80\c0" + "\03" ;; GlobalImport + "\7f" ;; i32 + "\00" ;; immutable + ) + "invalid UTF-8 encoding" +) + +;; third byte after (first normal) 4-byte prefix not a continuation byte +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\02\0e" ;; import section + "\01" ;; length 1 + "\04\74\65\73\74" ;; "test" + "\04\f1\80\80\fd" ;; "\f1\80\80\fd" + "\03" ;; GlobalImport + "\7f" ;; i32 + "\00" ;; immutable + ) + "invalid UTF-8 encoding" +) + +;; third byte after (last normal) 4-byte prefix not a continuation byte +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\02\0e" ;; import section + "\01" ;; length 1 + "\04\74\65\73\74" ;; "test" + "\04\f3\80\80\00" ;; "\f3\80\80\00" + "\03" ;; GlobalImport + "\7f" ;; i32 + "\00" ;; immutable + ) + "invalid UTF-8 encoding" +) + +;; third byte after (last normal) 4-byte prefix not a continuation byte +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\02\0e" ;; import section + "\01" ;; length 1 + "\04\74\65\73\74" ;; "test" + "\04\f3\80\80\7f" ;; "\f3\80\80\7f" + "\03" ;; GlobalImport + "\7f" ;; i32 + "\00" ;; immutable + ) + "invalid UTF-8 encoding" +) + +;; third byte after (last normal) 4-byte prefix not a continuation byte +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\02\0e" ;; import section + "\01" ;; length 1 + "\04\74\65\73\74" ;; "test" + "\04\f3\80\80\c0" ;; "\f3\80\80\c0" + "\03" ;; GlobalImport + "\7f" ;; i32 + "\00" ;; immutable + ) + "invalid UTF-8 encoding" +) + +;; third byte after (last normal) 4-byte prefix not a continuation byte +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\02\0e" ;; import section + "\01" ;; length 1 + "\04\74\65\73\74" ;; "test" + "\04\f3\80\80\fd" ;; "\f3\80\80\fd" + "\03" ;; GlobalImport + "\7f" ;; i32 + "\00" ;; immutable + ) + "invalid UTF-8 encoding" +) + +;; third byte after (0xf4) 4-byte prefix not a continuation byte +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\02\0e" ;; import section + "\01" ;; length 1 + "\04\74\65\73\74" ;; "test" + "\04\f4\80\80\00" ;; "\f4\80\80\00" + "\03" ;; GlobalImport + "\7f" ;; i32 + "\00" ;; immutable + ) + "invalid UTF-8 encoding" +) + +;; third byte after (0xf4) 4-byte prefix not a continuation byte +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\02\0e" ;; import section + "\01" ;; length 1 + "\04\74\65\73\74" ;; "test" + "\04\f4\80\80\7f" ;; "\f4\80\80\7f" + "\03" ;; GlobalImport + "\7f" ;; i32 + "\00" ;; immutable + ) + "invalid UTF-8 encoding" +) + +;; third byte after (0xf4) 4-byte prefix not a continuation byte +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\02\0e" ;; import section + "\01" ;; length 1 + "\04\74\65\73\74" ;; "test" + "\04\f4\80\80\c0" ;; "\f4\80\80\c0" + "\03" ;; GlobalImport + "\7f" ;; i32 + "\00" ;; immutable + ) + "invalid UTF-8 encoding" +) + +;; third byte after (0xf4) 4-byte prefix not a continuation byte +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\02\0e" ;; import section + "\01" ;; length 1 + "\04\74\65\73\74" ;; "test" + "\04\f4\80\80\fd" ;; "\f4\80\80\fd" + "\03" ;; GlobalImport + "\7f" ;; i32 + "\00" ;; immutable + ) + "invalid UTF-8 encoding" +) + +;;;; 5-byte sequences + +;; 5-byte sequence contains 6 bytes +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\02\10" ;; import section + "\01" ;; length 1 + "\04\74\65\73\74" ;; "test" + "\06\f8\80\80\80\80\80" ;; "\f8\80\80\80\80\80" + "\03" ;; GlobalImport + "\7f" ;; i32 + "\00" ;; immutable + ) + "invalid UTF-8 encoding" +) + +;; 5-byte sequence contains 4 bytes at end of string +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\02\0e" ;; import section + "\01" ;; length 1 + "\04\74\65\73\74" ;; "test" + "\04\f8\80\80\80" ;; "\f8\80\80\80" + "\03" ;; GlobalImport + "\7f" ;; i32 + "\00" ;; immutable + ) + "invalid UTF-8 encoding" +) + +;; 5-byte sequence contains 4 bytes +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\02\0f" ;; import section + "\01" ;; length 1 + "\04\74\65\73\74" ;; "test" + "\05\f8\80\80\80\23" ;; "\f8\80\80\80#" + "\03" ;; GlobalImport + "\7f" ;; i32 + "\00" ;; immutable + ) + "invalid UTF-8 encoding" +) + +;; 5-byte sequence contains 3 bytes at end of string +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\02\0d" ;; import section + "\01" ;; length 1 + "\04\74\65\73\74" ;; "test" + "\03\f8\80\80" ;; "\f8\80\80" + "\03" ;; GlobalImport + "\7f" ;; i32 + "\00" ;; immutable + ) + "invalid UTF-8 encoding" +) + +;; 5-byte sequence contains 3 bytes +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\02\0e" ;; import section + "\01" ;; length 1 + "\04\74\65\73\74" ;; "test" + "\04\f8\80\80\23" ;; "\f8\80\80#" + "\03" ;; GlobalImport + "\7f" ;; i32 + "\00" ;; immutable + ) + "invalid UTF-8 encoding" +) + +;; 5-byte sequence contains 2 bytes at end of string +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\02\0c" ;; import section + "\01" ;; length 1 + "\04\74\65\73\74" ;; "test" + "\02\f8\80" ;; "\f8\80" + "\03" ;; GlobalImport + "\7f" ;; i32 + "\00" ;; immutable + ) + "invalid UTF-8 encoding" +) + +;; 5-byte sequence contains 2 bytes +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\02\0d" ;; import section + "\01" ;; length 1 + "\04\74\65\73\74" ;; "test" + "\03\f8\80\23" ;; "\f8\80#" + "\03" ;; GlobalImport + "\7f" ;; i32 + "\00" ;; immutable + ) + "invalid UTF-8 encoding" +) + +;; 5-byte sequence contains 1 byte at end of string +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\02\0b" ;; import section + "\01" ;; length 1 + "\04\74\65\73\74" ;; "test" + "\01\f8" ;; "\f8" + "\03" ;; GlobalImport + "\7f" ;; i32 + "\00" ;; immutable + ) + "invalid UTF-8 encoding" +) + +;; 5-byte sequence contains 1 byte +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\02\0c" ;; import section + "\01" ;; length 1 + "\04\74\65\73\74" ;; "test" + "\02\f8\23" ;; "\f8#" + "\03" ;; GlobalImport + "\7f" ;; i32 + "\00" ;; immutable + ) + "invalid UTF-8 encoding" +) + +;;;; 5-byte sequence contents + +;; (first) invalid 5-byte prefix +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\02\0f" ;; import section + "\01" ;; length 1 + "\04\74\65\73\74" ;; "test" + "\05\f8\80\80\80\80" ;; "\f8\80\80\80\80" + "\03" ;; GlobalImport + "\7f" ;; i32 + "\00" ;; immutable + ) + "invalid UTF-8 encoding" +) + +;; (last) invalid 5-byte prefix +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\02\0f" ;; import section + "\01" ;; length 1 + "\04\74\65\73\74" ;; "test" + "\05\fb\bf\bf\bf\bf" ;; "\fb\bf\bf\bf\bf" + "\03" ;; GlobalImport + "\7f" ;; i32 + "\00" ;; immutable + ) + "invalid UTF-8 encoding" +) + +;;;; 6-byte sequences + +;; 6-byte sequence contains 7 bytes +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\02\11" ;; import section + "\01" ;; length 1 + "\04\74\65\73\74" ;; "test" + "\07\fc\80\80\80\80\80\80" ;; "\fc\80\80\80\80\80\80" + "\03" ;; GlobalImport + "\7f" ;; i32 + "\00" ;; immutable + ) + "invalid UTF-8 encoding" +) + +;; 6-byte sequence contains 5 bytes at end of string +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\02\0f" ;; import section + "\01" ;; length 1 + "\04\74\65\73\74" ;; "test" + "\05\fc\80\80\80\80" ;; "\fc\80\80\80\80" + "\03" ;; GlobalImport + "\7f" ;; i32 + "\00" ;; immutable + ) + "invalid UTF-8 encoding" +) + +;; 6-byte sequence contains 5 bytes +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\02\10" ;; import section + "\01" ;; length 1 + "\04\74\65\73\74" ;; "test" + "\06\fc\80\80\80\80\23" ;; "\fc\80\80\80\80#" + "\03" ;; GlobalImport + "\7f" ;; i32 + "\00" ;; immutable + ) + "invalid UTF-8 encoding" +) + +;; 6-byte sequence contains 4 bytes at end of string +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\02\0e" ;; import section + "\01" ;; length 1 + "\04\74\65\73\74" ;; "test" + "\04\fc\80\80\80" ;; "\fc\80\80\80" + "\03" ;; GlobalImport + "\7f" ;; i32 + "\00" ;; immutable + ) + "invalid UTF-8 encoding" +) + +;; 6-byte sequence contains 4 bytes +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\02\0f" ;; import section + "\01" ;; length 1 + "\04\74\65\73\74" ;; "test" + "\05\fc\80\80\80\23" ;; "\fc\80\80\80#" + "\03" ;; GlobalImport + "\7f" ;; i32 + "\00" ;; immutable + ) + "invalid UTF-8 encoding" +) + +;; 6-byte sequence contains 3 bytes at end of string +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\02\0d" ;; import section + "\01" ;; length 1 + "\04\74\65\73\74" ;; "test" + "\03\fc\80\80" ;; "\fc\80\80" + "\03" ;; GlobalImport + "\7f" ;; i32 + "\00" ;; immutable + ) + "invalid UTF-8 encoding" +) + +;; 6-byte sequence contains 3 bytes +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\02\0e" ;; import section + "\01" ;; length 1 + "\04\74\65\73\74" ;; "test" + "\04\fc\80\80\23" ;; "\fc\80\80#" + "\03" ;; GlobalImport + "\7f" ;; i32 + "\00" ;; immutable + ) + "invalid UTF-8 encoding" +) + +;; 6-byte sequence contains 2 bytes at end of string +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\02\0c" ;; import section + "\01" ;; length 1 + "\04\74\65\73\74" ;; "test" + "\02\fc\80" ;; "\fc\80" + "\03" ;; GlobalImport + "\7f" ;; i32 + "\00" ;; immutable + ) + "invalid UTF-8 encoding" +) + +;; 6-byte sequence contains 2 bytes +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\02\0d" ;; import section + "\01" ;; length 1 + "\04\74\65\73\74" ;; "test" + "\03\fc\80\23" ;; "\fc\80#" + "\03" ;; GlobalImport + "\7f" ;; i32 + "\00" ;; immutable + ) + "invalid UTF-8 encoding" +) + +;; 6-byte sequence contains 1 byte at end of string +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\02\0b" ;; import section + "\01" ;; length 1 + "\04\74\65\73\74" ;; "test" + "\01\fc" ;; "\fc" + "\03" ;; GlobalImport + "\7f" ;; i32 + "\00" ;; immutable + ) + "invalid UTF-8 encoding" +) + +;; 6-byte sequence contains 1 byte +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\02\0c" ;; import section + "\01" ;; length 1 + "\04\74\65\73\74" ;; "test" + "\02\fc\23" ;; "\fc#" + "\03" ;; GlobalImport + "\7f" ;; i32 + "\00" ;; immutable + ) + "invalid UTF-8 encoding" +) + +;;;; 6-byte sequence contents + +;; (first) invalid 6-byte prefix +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\02\10" ;; import section + "\01" ;; length 1 + "\04\74\65\73\74" ;; "test" + "\06\fc\80\80\80\80\80" ;; "\fc\80\80\80\80\80" + "\03" ;; GlobalImport + "\7f" ;; i32 + "\00" ;; immutable + ) + "invalid UTF-8 encoding" +) + +;; (last) invalid 6-byte prefix +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\02\10" ;; import section + "\01" ;; length 1 + "\04\74\65\73\74" ;; "test" + "\06\fd\bf\bf\bf\bf\bf" ;; "\fd\bf\bf\bf\bf\bf" + "\03" ;; GlobalImport + "\7f" ;; i32 + "\00" ;; immutable + ) + "invalid UTF-8 encoding" +) + +;;;; Miscellaneous invalid bytes + +;; invalid byte +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\02\0b" ;; import section + "\01" ;; length 1 + "\04\74\65\73\74" ;; "test" + "\01\fe" ;; "\fe" + "\03" ;; GlobalImport + "\7f" ;; i32 + "\00" ;; immutable + ) + "invalid UTF-8 encoding" +) + +;; invalid byte +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\02\0b" ;; import section + "\01" ;; length 1 + "\04\74\65\73\74" ;; "test" + "\01\ff" ;; "\ff" + "\03" ;; GlobalImport + "\7f" ;; i32 + "\00" ;; immutable + ) + "invalid UTF-8 encoding" +) + +;; UTF-16BE BOM +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\02\0c" ;; import section + "\01" ;; length 1 + "\04\74\65\73\74" ;; "test" + "\02\fe\ff" ;; "\fe\ff" + "\03" ;; GlobalImport + "\7f" ;; i32 + "\00" ;; immutable + ) + "invalid UTF-8 encoding" +) + +;; UTF-32BE BOM +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\02\0e" ;; import section + "\01" ;; length 1 + "\04\74\65\73\74" ;; "test" + "\04\00\00\fe\ff" ;; "\00\00\fe\ff" + "\03" ;; GlobalImport + "\7f" ;; i32 + "\00" ;; immutable + ) + "invalid UTF-8 encoding" +) + +;; UTF-16LE BOM +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\02\0c" ;; import section + "\01" ;; length 1 + "\04\74\65\73\74" ;; "test" + "\02\ff\fe" ;; "\ff\fe" + "\03" ;; GlobalImport + "\7f" ;; i32 + "\00" ;; immutable + ) + "invalid UTF-8 encoding" +) + +;; UTF-32LE BOM +(assert_malformed + (module + "\00asm" "\01\00\00\00" + "\02\0e" ;; import section + "\01" ;; length 1 + "\04\74\65\73\74" ;; "test" + "\04\ff\fe\00\00" ;; "\ff\fe\00\00" + "\03" ;; GlobalImport + "\7f" ;; i32 + "\00" ;; immutable + ) + "invalid UTF-8 encoding" +) + From 27da124848f3ebf899cf26ded3332a1dd0e37ed9 Mon Sep 17 00:00:00 2001 From: rossberg-chromium Date: Mon, 15 May 2017 12:55:29 +0200 Subject: [PATCH 005/672] 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 006/672] [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 945b391e..fb64b663 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 4431f178..bd20c8be 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 b2abed9f..8a436650 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 00000000..81d1c9f2 --- /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