diff --git a/.github/workflows/ci-interpreter.yml b/.github/workflows/ci-interpreter.yml index 51841ab9d6..bb507f1ce6 100644 --- a/.github/workflows/ci-interpreter.yml +++ b/.github/workflows/ci-interpreter.yml @@ -2,11 +2,11 @@ name: CI for interpreter & tests on: push: - branches: [ main ] + branches: [ main, wasm-3.0 ] paths: [ .github/**, interpreter/**, test/** ] pull_request: - branches: [ main ] + branches: [ main, wasm-3.0 ] paths: [ .github/**, interpreter/**, test/** ] # Allows you to run this workflow manually from the Actions tab diff --git a/.github/workflows/ci-spec.yml b/.github/workflows/ci-spec.yml index ebc3066a96..82447e640f 100644 --- a/.github/workflows/ci-spec.yml +++ b/.github/workflows/ci-spec.yml @@ -2,11 +2,11 @@ name: CI for specs on: push: - branches: [ main ] + branches: [ main, wasm-3.0 ] paths: [ .github/**, document/** ] pull_request: - branches: [ main ] + branches: [ main, wasm-3.0 ] paths: [ .github/**, document/** ] # Allows you to run this workflow manually from the Actions tab diff --git a/.github/workflows/w3c-publish.yml b/.github/workflows/w3c-publish.yml index bcb26699dd..2f10b0adb2 100644 --- a/.github/workflows/w3c-publish.yml +++ b/.github/workflows/w3c-publish.yml @@ -15,6 +15,10 @@ on: # Candidate Recommendation Snapshot). workflow_dispatch: inputs: + dry-run: + required: true + type: boolean + description: If set, Echidna will validate but not publish. w3c-status: required: true type: choice @@ -60,7 +64,9 @@ jobs: W3C_ECHIDNA_TOKEN_CORE: ${{ secrets.W3C_ECHIDNA_TOKEN_CORE }} W3C_ECHIDNA_TOKEN_JSAPI: ${{ secrets.W3C_ECHIDNA_TOKEN_JSAPI }} W3C_ECHIDNA_TOKEN_WEBAPI: ${{ secrets.W3C_ECHIDNA_TOKEN_WEBAPI }} - ECHIDNA_DRYRUN: ${{ !(github.event_name == 'push' && github.repository == 'WebAssembly/spec' && github.ref == 'refs/heads/main') }} + ECHIDNA_DRYRUN: |- + ${{ (github.event_name == 'workflow_dispatch' && inputs.dry-run) || + !(github.event_name == 'push' && github.repository == 'WebAssembly/spec' && github.ref == 'refs/heads/main') }} - name: Validate ${{ matrix.spec }} spec with Echidna if: env.W3C_USERNAME run: cd document && make -e -C ${{ matrix.spec }} WD-echidna diff --git a/README.md b/README.md index fde9c1c73f..4266634cfa 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,6 @@ +[![CI for specs](https://github.com/WebAssembly/stack-switching/actions/workflows/ci-spec.yml/badge.svg)](https://github.com/WebAssembly/stack-switching/actions/workflows/ci-spec.yml) +[![CI for interpreter & tests](https://github.com/WebAssembly/stack-switching/actions/workflows/ci-interpreter.yml/badge.svg)](https://github.com/WebAssembly/stack-switching/actions/workflows/ci-interpreter.yml) + # Stack-Switching Proposal for WebAssembly This repository is a clone of [`WebAssembly/spec`](https://github.com/WebAssembly/spec/). It is meant for discussion, prototype specification, and implementation of a proposal to add @@ -5,31 +8,6 @@ support for stack-switching. See the [explainer](proposals/stack-switching/Explainer.md) for a high-level summary of the proposal. -## Previous proposals - -The current explainer represents the unification of two previous proposals: Typed Continuations (wasmfx) and Bag of Stacks (bos). (The explainers have now been unified. Once the reference interpreter and examples are adapted for the unified proposal this section will be removed from the README.) - -#### Typed Continuations - -* See the [explainer](proposals/continuations/Explainer.md) for a high-level summary of the proposal. - -* See the [overview](proposals/continuations/Overview.md) for a more formal description of the proposal. - -* An [implementation](https://github.com/WebAssembly/stack-switching/tree/wasmfx) is available as an extension to the reference interpreter. It is accesible from the `wasmfx` branch of this repository. - -* See the [examples](proposals/continuations/examples) for Wasm code for implementing various different features including lightweight threads, actors, and async/await. - -#### Bag of Stacks Proposal - -* See the [explainer](proposals/bag-o-stacks/Explainer.md) for a high-level summary of the proposal. - -Original README from upstream repository follows. - --------------------------------------------------------------------------------- - -[![CI for specs](https://github.com/WebAssembly/stack-switching/actions/workflows/ci-spec.yml/badge.svg)](https://github.com/WebAssembly/stack-switching/actions/workflows/ci-spec.yml) -[![CI for interpreter & tests](https://github.com/WebAssembly/stack-switching/actions/workflows/ci-interpreter.yml/badge.svg)](https://github.com/WebAssembly/stack-switching/actions/workflows/ci-interpreter.yml) - # spec This repository holds the sources for the WebAssembly specification, diff --git a/document/core/appendix/changes.rst b/document/core/appendix/changes.rst index 352bc504a9..7e0e6459fb 100644 --- a/document/core/appendix/changes.rst +++ b/document/core/appendix/changes.rst @@ -308,7 +308,7 @@ Allowed basic numeric computations in constant expressions. [#proposal-extconst] - |GLOBALGET| for any previously declared immutable :ref:`global ` .. note:: - The :ref:`garbage collection ` added further constant instructions. + The :ref:`garbage collection ` extension added further constant instructions. .. index:: instruction, function, call @@ -389,6 +389,44 @@ Added the ability to use multiple memories per module. [#proposal-multimem]_ * :ref:`Data segments ` take a :ref:`memory index ` +.. index:: address type, number type, table, memory, instruction + +64-bit Address Space +.................... + +Added the ability to declare an :math:`\I64` :ref:`address type ` for :ref:`tables ` and :ref:`memories `. [#proposal-addr64]_ + +* :ref:`Address types ` denote a subset of the integral :ref:`number types ` + +* :ref:`Table types ` include an :ref:`address type ` + +* :ref:`Memory types ` include an :ref:`address type ` + +* Operand types of :ref:`table ` and :ref:`memory ` instructions now depend on the subject's declared address type: + + - |TABLEGET| + - |TABLESET| + - |TABLESIZE| + - |TABLEGROW| + - |TABLEFILL| + - |TABLECOPY| + - |TABLEINIT| + - |MEMORYSIZE| + - |MEMORYGROW| + - |MEMORYFILL| + - |MEMORYCOPY| + - |MEMORYINIT| + - :math:`t\K{.load}` + - :math:`t\K{.store}` + - :math:`t\K{.load}\!N\!\K{\_}\sx` + - :math:`t\K{.store}\!N` + - :math:`\K{v128.load}\!N\!\K{x}\!M\!\K{\_}\sx` + - :math:`\K{v128.load}\!N\!\K{\_zero}` + - :math:`\K{v128.load}\!N\!\K{\_splat}` + - :math:`\K{v128.load}\!N\!\K{\_lane}` + - :math:`\K{v128.store}\!N\!\K{\_lane}` + + .. index:: reference, reference type, heap type, value type, local, local type, instruction, instruction type, table, function, function type, matching, subtyping Typeful References @@ -584,7 +622,7 @@ mirroring the role of custom sections in the binary format. [#proposal-annot]_ .. [#proposal-extconst] - https://github.com/WebAssembly/spec/blob/main/proposals/extended-const/ + https://github.com/WebAssembly/spec/tree/main/proposals/extended-const/ .. [#proposal-tailcall] https://github.com/WebAssembly/spec/tree/main/proposals/tail-call/ @@ -593,7 +631,10 @@ mirroring the role of custom sections in the binary format. [#proposal-annot]_ https://github.com/WebAssembly/spec/tree/main/proposals/exception-handling/ .. [#proposal-multimem] - https://github.com/WebAssembly/spec/blob/main/proposals/multi-memory/ + https://github.com/WebAssembly/spec/tree/main/proposals/multi-memory/ + +.. [#proposal-addr64] + https://github.com/WebAssembly/spec/tree/main/proposals/memory64/ .. [#proposal-typedref] https://github.com/WebAssembly/spec/tree/main/proposals/function-references/ diff --git a/document/core/appendix/embedding.rst b/document/core/appendix/embedding.rst index 8dd8ffe0c5..d2d7c54d0d 100644 --- a/document/core/appendix/embedding.rst +++ b/document/core/appendix/embedding.rst @@ -21,7 +21,7 @@ Types In the description of the embedder interface, syntactic classes from the :ref:`abstract syntax ` and the :ref:`runtime's abstract machine ` are used as names for variables that range over the possible objects from that class. Hence, these syntactic classes can also be interpreted as types. -For numeric parameters, notation like :math:`n:\u32` is used to specify a symbolic name in addition to the respective value range. +For numeric parameters, notation like :math:`i:\u64` is used to specify a symbolic name in addition to the respective value range. .. _embed-bool: @@ -165,7 +165,7 @@ Modules .. _embed-module-instantiate: :math:`\F{module\_instantiate}(\store, \module, \externval^\ast) : (\store, \moduleinst ~|~ \exception ~|~ \error)` -.................................................................................................... +................................................................................................................... 1. Try :ref:`instantiating ` :math:`\module` in :math:`\store` with :ref:`external values ` :math:`\externval^\ast` as imports: @@ -383,7 +383,7 @@ Tables .. _embed-table-read: -:math:`\F{table\_read}(\store, \tableaddr, i:\u32) : \reff ~|~ \error` +:math:`\F{table\_read}(\store, \tableaddr, i:\u64) : \reff ~|~ \error` ...................................................................... 1. Let :math:`\X{ti}` be the :ref:`table instance ` :math:`\store.\STABLES[\tableaddr]`. @@ -401,7 +401,7 @@ Tables .. _embed-table-write: -:math:`\F{table\_write}(\store, \tableaddr, i:\u32, \reff) : \store ~|~ \error` +:math:`\F{table\_write}(\store, \tableaddr, i:\u64, \reff) : \store ~|~ \error` ............................................................................... 1. Let :math:`\X{ti}` be the :ref:`table instance ` :math:`\store.\STABLES[\tableaddr]`. @@ -421,7 +421,7 @@ Tables .. _embed-table-size: -:math:`\F{table\_size}(\store, \tableaddr) : \u32` +:math:`\F{table\_size}(\store, \tableaddr) : \u64` .................................................. 1. Return the length of :math:`\store.\STABLES[\tableaddr].\TIELEM`. @@ -437,7 +437,7 @@ Tables .. _embed-table-grow: -:math:`\F{table\_grow}(\store, \tableaddr, n:\u32, \reff) : \store ~|~ \error` +:math:`\F{table\_grow}(\store, \tableaddr, n:\u64, \reff) : \store ~|~ \error` .............................................................................. 1. Try :ref:`growing ` the :ref:`table instance ` :math:`\store.\STABLES[\tableaddr]` by :math:`n` elements with initialization value :math:`\reff`: @@ -495,7 +495,7 @@ Memories .. _embed-mem-read: -:math:`\F{mem\_read}(\store, \memaddr, i:\u32) : \byte ~|~ \error` +:math:`\F{mem\_read}(\store, \memaddr, i:\u64) : \byte ~|~ \error` .................................................................. 1. Let :math:`\X{mi}` be the :ref:`memory instance ` :math:`\store.\SMEMS[\memaddr]`. @@ -513,12 +513,12 @@ Memories .. _embed-mem-write: -:math:`\F{mem\_write}(\store, \memaddr, i:\u32, \byte) : \store ~|~ \error` +:math:`\F{mem\_write}(\store, \memaddr, i:\u64, \byte) : \store ~|~ \error` ........................................................................... 1. Let :math:`\X{mi}` be the :ref:`memory instance ` :math:`\store.\SMEMS[\memaddr]`. -2. If :math:`\u32` is larger than or equal to the length of :math:`\X{mi}.\MIDATA`, then return :math:`\ERROR`. +2. If :math:`i` is larger than or equal to the length of :math:`\X{mi}.\MIDATA`, then return :math:`\ERROR`. 3. Replace :math:`\X{mi}.\MIDATA[i]` with :math:`\byte`. @@ -533,7 +533,7 @@ Memories .. _embed-mem-size: -:math:`\F{mem\_size}(\store, \memaddr) : \u32` +:math:`\F{mem\_size}(\store, \memaddr) : \u64` .............................................. 1. Return the length of :math:`\store.\SMEMS[\memaddr].\MIDATA` divided by the :ref:`page size `. @@ -549,7 +549,7 @@ Memories .. _embed-mem-grow: -:math:`\F{mem\_grow}(\store, \memaddr, n:\u32) : \store ~|~ \error` +:math:`\F{mem\_grow}(\store, \memaddr, n:\u64) : \store ~|~ \error` ................................................................... 1. Try :ref:`growing ` the :ref:`memory instance ` :math:`\store.\SMEMS[\memaddr]` by :math:`n` :ref:`pages `: diff --git a/document/core/appendix/properties.rst b/document/core/appendix/properties.rst index b4c15c8f31..79a530eddc 100644 --- a/document/core/appendix/properties.rst +++ b/document/core/appendix/properties.rst @@ -513,10 +513,10 @@ where :math:`\val_1 \gg^+_S \val_2` denotes the transitive closure of the follow .. index:: table type, table instance, limits, function address .. _valid-tableinst: -:ref:`Table Instances ` :math:`\{ \TITYPE~(\limits~t), \TIELEM~\reff^\ast \}` -............................................................................................... +:ref:`Table Instances ` :math:`\{ \TITYPE~\addrtype~\limits~t, \TIELEM~\reff^\ast \}` +....................................................................................................... -* The :ref:`table type ` :math:`\limits~t` must be :ref:`valid ` under the empty :ref:`context `. +* The :ref:`table type ` :math:`\addrtype~\limits~t` must be :ref:`valid ` under the empty :ref:`context `. * The length of :math:`\reff^\ast` must equal :math:`\limits.\LMIN`. @@ -526,11 +526,11 @@ where :math:`\val_1 \gg^+_S \val_2` denotes the transitive closure of the follow * The :ref:`reference type ` :math:`t'_i` must :ref:`match ` the :ref:`reference type ` :math:`t`. -* Then the table instance is valid with :ref:`table type ` :math:`\limits~t`. +* Then the table instance is valid with :ref:`table type ` :math:`\addrtype~\limits~t`. .. math:: \frac{ - \vdashtabletype \limits~t \ok + \vdashtabletype \addrtype~\limits~t \ok \qquad n = \limits.\LMIN \qquad @@ -538,37 +538,37 @@ where :math:`\val_1 \gg^+_S \val_2` denotes the transitive closure of the follow \qquad (\vdashreftypematch t' \matchesvaltype t)^n }{ - S \vdashtableinst \{ \TITYPE~(\limits~t), \TIELEM~\reff^n \} : \limits~t + S \vdashtableinst \{ \TITYPE~\addrtype~\limits~t, \TIELEM~\reff^n \} : \addrtype~\limits~t } .. index:: memory type, memory instance, limits, byte .. _valid-meminst: -:ref:`Memory Instances ` :math:`\{ \MITYPE~\limits, \MIDATA~b^\ast \}` -...................................................................................... +:ref:`Memory Instances ` :math:`\{ \MITYPE~\addrtype~\limits, \MIDATA~b^\ast \}` +................................................................................................ -* The :ref:`memory type ` :math:`\limits` must be :ref:`valid ` under the empty :ref:`context `. +* The :ref:`memory type ` :math:`\addrtype~\limits` must be :ref:`valid ` under the empty :ref:`context `. * The length of :math:`b^\ast` must equal :math:`\limits.\LMIN` multiplied by the :ref:`page size ` :math:`64\,\F{Ki}`. -* Then the memory instance is valid with :ref:`memory type ` :math:`\limits`. +* Then the memory instance is valid with :ref:`memory type ` :math:`\addrtype~\limits`. .. math:: \frac{ - \vdashmemtype \limits \ok + \vdashmemtype \addrtype~\limits \ok \qquad n = \limits.\LMIN \cdot 64\,\F{Ki} }{ - S \vdashmeminst \{ \MITYPE~\limits, \MIDATA~b^n \} : \limits + S \vdashmeminst \{ \MITYPE~\addrtype~\limits, \MIDATA~b^n \} : \addrtype~\limits } .. index:: global type, global instance, value, mutability .. _valid-globalinst: -:ref:`Global Instances ` :math:`\{ \GITYPE~(\mut~t), \GIVALUE~\val \}` -......................................................................................... +:ref:`Global Instances ` :math:`\{ \GITYPE~\mut~t, \GIVALUE~\val \}` +....................................................................................... * The :ref:`global type ` :math:`\mut~t` must be :ref:`valid ` under the empty :ref:`context `. @@ -586,7 +586,7 @@ where :math:`\val_1 \gg^+_S \val_2` denotes the transitive closure of the follow \qquad \vdashvaltypematch t' \matchesvaltype t }{ - S \vdashglobalinst \{ \GITYPE~(\mut~t), \GIVALUE~\val \} : \mut~t + S \vdashglobalinst \{ \GITYPE~\mut~t, \GIVALUE~\val \} : \mut~t } diff --git a/document/core/binary/instructions.rst b/document/core/binary/instructions.rst index f9e505febd..af31e72eb7 100644 --- a/document/core/binary/instructions.rst +++ b/document/core/binary/instructions.rst @@ -290,9 +290,9 @@ Each variant of :ref:`memory instruction ` is encoded with .. math:: \begin{array}{llcllll} \production{memory argument} & \Bmemarg &::=& - a{:}\Bu32~~o{:}\Bu32 &\Rightarrow& 0~\{ \ALIGN~a,~\OFFSET~o \} + a{:}\Bu32~~o{:}\Bu64 &\Rightarrow& 0~\{ \ALIGN~a,~\OFFSET~o \} & (\iff a < 2^6) \\ &&|& - a{:}\Bu32~~x{:}\memidx~~o{:}\Bu32 &\Rightarrow& x~\{ \ALIGN~(a - 2^6),~\OFFSET~o \} + a{:}\Bu32~~x{:}\memidx~~o{:}\Bu64 &\Rightarrow& x~\{ \ALIGN~(a - 2^6),~\OFFSET~o \} & (\iff 2^6 \leq a < 2^7) \\ \production{instruction} & \Binstr &::=& \dots \\ &&|& \hex{28}~~m{:}\Bmemarg &\Rightarrow& \I32.\LOAD~m \\ &&|& diff --git a/document/core/binary/types.rst b/document/core/binary/types.rst index c6212ed643..3ab538a09d 100644 --- a/document/core/binary/types.rst +++ b/document/core/binary/types.rst @@ -251,13 +251,15 @@ Additional shorthands are recognized for unary recursions and sub types without Limits ~~~~~~ -:ref:`Limits ` are encoded with a preceding flag indicating whether a maximum is present. +:ref:`Limits ` are encoded with a preceding flag indicating whether a maximum is present, and a flag for the :ref:`address type `. .. math:: \begin{array}{llclll} \production{limits} & \Blimits &::=& - \hex{00}~~n{:}\Bu32 &\Rightarrow& \{ \LMIN~n, \LMAX~\epsilon \} \\ &&|& - \hex{01}~~n{:}\Bu32~~m{:}\Bu32 &\Rightarrow& \{ \LMIN~n, \LMAX~m \} \\ + \hex{00}~~n{:}\Bu64 &\Rightarrow& (\I32, \{ \LMIN~n, \LMAX~\epsilon \}) \\ &&|& + \hex{01}~~n{:}\Bu64~~m{:}\Bu64 &\Rightarrow& (\I32, \{ \LMIN~n, \LMAX~m \}) \\ &&|& + \hex{04}~~n{:}\Bu64 &\Rightarrow& (\I64, \{ \LMIN~n, \LMAX~\epsilon \}) \\ &&|& + \hex{05}~~n{:}\Bu64~~m{:}\Bu64 &\Rightarrow& (\I64, \{ \LMIN~n, \LMAX~m \}) \end{array} @@ -273,7 +275,7 @@ Memory Types .. math:: \begin{array}{llclll@{\qquad\qquad}l} \production{memory type} & \Bmemtype &::=& - \X{lim}{:}\Blimits &\Rightarrow& \X{lim} \\ + (\X{at},\X{lim}){:}\Blimits &\Rightarrow& \X{at}~\X{lim} \\ \end{array} @@ -289,7 +291,7 @@ Table Types .. math:: \begin{array}{llclll} \production{table type} & \Btabletype &::=& - \X{et}{:}\Breftype~~\X{lim}{:}\Blimits &\Rightarrow& \X{lim}~\X{et} \\ + \X{et}{:}\Breftype~~(\X{at},\X{lim}){:}\Blimits &\Rightarrow& \X{at}~\X{lim}~\X{et} \\ \end{array} diff --git a/document/core/exec/instructions.rst b/document/core/exec/instructions.rst index 46004f2900..25eb52ab95 100644 --- a/document/core/exec/instructions.rst +++ b/document/core/exec/instructions.rst @@ -2725,9 +2725,9 @@ Table Instructions 5. Let :math:`\X{tab}` be the :ref:`table instance ` :math:`S.\STABLES[a]`. -6. Assert: due to :ref:`validation `, a value of :ref:`value type ` |I32| is on the top of the stack. +6. Assert: due to :ref:`validation `, a value of some :ref:`address type ` :math:`\X{at}` is on the top of the stack. -7. Pop the value :math:`\I32.\CONST~i` from the stack. +7. Pop the value :math:`\X{at}.\CONST~i` from the stack. 8. If :math:`i` is not smaller than the length of :math:`\X{tab}.\TIELEM`, then: @@ -2741,12 +2741,12 @@ Table Instructions ~\\[-1ex] \begin{array}{l} \begin{array}{lcl@{\qquad}l} - S; F; (\I32.\CONST~i)~(\TABLEGET~x) &\stepto& S; F; \val + S; F; (\X{at}.\CONST~i)~(\TABLEGET~x) &\stepto& S; F; \val \end{array} \\ \qquad (\iff S.\STABLES[F.\AMODULE.\MITABLES[x]].\TIELEM[i] = \val) \\ \begin{array}{lcl@{\qquad}l} - S; F; (\I32.\CONST~i)~(\TABLEGET~x) &\stepto& S; F; \TRAP + S; F; (\X{at}.\CONST~i)~(\TABLEGET~x) &\stepto& S; F; \TRAP \end{array} \\ \qquad (\otherwise) \\ @@ -2772,9 +2772,9 @@ Table Instructions 7. Pop the value :math:`\val` from the stack. -8. Assert: due to :ref:`validation `, a value of :ref:`value type ` |I32| is on the top of the stack. +8. Assert: due to :ref:`validation `, a value of some :ref:`address type ` :math:`\X{at}` is on the top of the stack. -9. Pop the value :math:`\I32.\CONST~i` from the stack. +9. Pop the value :math:`\X{at}.\CONST~i` from the stack. 10. If :math:`i` is not smaller than the length of :math:`\X{tab}.\TIELEM`, then: @@ -2786,12 +2786,12 @@ Table Instructions ~\\[-1ex] \begin{array}{l} \begin{array}{lcl@{\qquad}l} - S; F; (\I32.\CONST~i)~\val~(\TABLESET~x) &\stepto& S'; F; \epsilon + S; F; (\X{at}.\CONST~i)~\val~(\TABLESET~x) &\stepto& S'; F; \epsilon \end{array} \\ \qquad (\iff S' = S \with \STABLES[F.\AMODULE.\MITABLES[x]].\TIELEM[i] = \val) \\ \begin{array}{lcl@{\qquad}l} - S; F; (\I32.\CONST~i)~\val~(\TABLESET~x) &\stepto& S; F; \TRAP + S; F; (\X{at}.\CONST~i)~\val~(\TABLESET~x) &\stepto& S; F; \TRAP \end{array} \\ \qquad (\otherwise) \\ @@ -2813,17 +2813,22 @@ Table Instructions 5. Let :math:`\X{tab}` be the :ref:`table instance ` :math:`S.\STABLES[a]`. -6. Let :math:`\X{sz}` be the length of :math:`\X{tab}.\TIELEM`. +6. Let :math:`\X{at}~\limits` be the :ref:`table type ` :math:`\X{tab}.\TITYPE`. -7. Push the value :math:`\I32.\CONST~\X{sz}` to the stack. +7. Let :math:`\X{sz}` be the length of :math:`\X{tab}.\TIELEM`. + +8. Push the value :math:`\X{at}.\CONST~\X{sz}` to the stack. .. math:: \begin{array}{l} \begin{array}{lcl@{\qquad}l} - S; F; (\TABLESIZE~x) &\stepto& S; F; (\I32.\CONST~\X{sz}) + S; F; (\TABLESIZE~x) &\stepto& S; F; (\X{at}.\CONST~\X{sz}) \end{array} \\ \qquad - (\iff |S.\STABLES[F.\AMODULE.\MITABLES[x]].\TIELEM| = \X{sz}) \\ + \begin{array}[t]{@{}r@{~}l@{}} + (\iff |S.\STABLES[F.\AMODULE.\MITABLES[x]].\TIELEM| = \X{sz} \\ + \wedge S.\STABLES[F.\AMODULE.\MITABLES[x]].\TITYPE = \X{at}~\X{lim}~t) + \end{array} \\ \end{array} @@ -2845,35 +2850,35 @@ Table Instructions 6. Let :math:`\X{sz}` be the length of :math:`S.\STABLES[a]`. -7. Assert: due to :ref:`validation `, a value of :ref:`value type ` |I32| is on the top of the stack. +7. Assert: due to :ref:`validation `, a value of some :ref:`address type ` :math:`\X{at}` is on the top of the stack. -8. Pop the value :math:`\I32.\CONST~n` from the stack. +8. Pop the value :math:`t.\CONST~n` from the stack. 9. Assert: due to :ref:`validation `, a :ref:`reference value ` is on the top of the stack. 10. Pop the value :math:`\val` from the stack. -11. Let :math:`\X{err}` be the |i32| value :math:`2^{32}-1`, for which :math:`\signed_{32}(\X{err})` is :math:`-1`. +11. Let :math:`\X{err}` be the value :math:`2^{|\X{at}|}-1`, for which :math:`\signed_{|\X{at}|}(\X{err})` is :math:`-1`. 12. Either: a. If :ref:`growing ` :math:`\X{tab}` by :math:`n` entries with initialization value :math:`\val` succeeds, then: - i. Push the value :math:`\I32.\CONST~\X{sz}` to the stack. + i. Push the value :math:`\X{at}.\CONST~\X{sz}` to the stack. b. Else: - i. Push the value :math:`\I32.\CONST~\X{err}` to the stack. + i. Push the value :math:`\X{at}.\CONST~\X{err}` to the stack. 13. Or: - a. push the value :math:`\I32.\CONST~\X{err}` to the stack. + a. push the value :math:`\X{at}.\CONST~\X{err}` to the stack. .. math:: ~\\[-1ex] \begin{array}{l} \begin{array}{lcl@{\qquad}l} - S; F; \val~(\I32.\CONST~n)~(\TABLEGROW~x) &\stepto& S'; F; (\I32.\CONST~\X{sz}) + S; F; \val~(\X{at}.\CONST~n)~(\TABLEGROW~x) &\stepto& S'; F; (\X{at}.\CONST~\X{sz}) \end{array} \\ \qquad \begin{array}[t]{@{}r@{~}l@{}} @@ -2883,7 +2888,7 @@ Table Instructions \end{array} \\[1ex] \begin{array}{lcl@{\qquad}l} - S; F; \val~(\I32.\CONST~n)~(\TABLEGROW~x) &\stepto& S; F; (\I32.\CONST~\signed_{32}^{-1}(-1)) + S; F; \val~(\X{at}.\CONST~n)~(\TABLEGROW~x) &\stepto& S; F; (\X{at}.\CONST~\signed_{|\X{at}|}^{-1}(-1)) \end{array} \end{array} @@ -2911,60 +2916,60 @@ Table Instructions 5. Let :math:`\X{tab}` be the :ref:`table instance ` :math:`S.\STABLES[\X{ta}]`. -6. Assert: due to :ref:`validation `, a value of :ref:`value type ` |I32| is on the top of the stack. +6. Assert: due to :ref:`validation `, a value of some :ref:`address type ` :math:`\X{at}` is on the top of the stack. -7. Pop the value :math:`\I32.\CONST~n` from the stack. +7. Pop the value :math:`\X{at}.\CONST~n` from the stack. 8. Assert: due to :ref:`validation `, a :ref:`reference value ` is on the top of the stack. 9. Pop the value :math:`\val` from the stack. -10. Assert: due to :ref:`validation `, a value of :ref:`value type ` |I32| is on the top of the stack. +10. Assert: due to :ref:`validation `, a value of :ref:`address type ` :math:`\X{at}` is on the top of the stack. -11. Pop the value :math:`\I32.\CONST~i` from the stack. +11. Pop the value :math:`\X{at}.\CONST~i` from the stack. 12. If :math:`i + n` is larger than the length of :math:`\X{tab}.\TIELEM`, then: a. Trap. -12. If :math:`n` is :math:`0`, then: +13. If :math:`n` is :math:`0`, then: a. Return. -13. Push the value :math:`\I32.\CONST~i` to the stack. +14. Push the value :math:`\X{at}.\CONST~i` to the stack. -14. Push the value :math:`\val` to the stack. +15. Push the value :math:`\val` to the stack. -15. Execute the instruction :math:`\TABLESET~x`. +16. Execute the instruction :math:`\TABLESET~x`. -16. Push the value :math:`\I32.\CONST~(i+1)` to the stack. +17. Push the value :math:`\X{at}.\CONST~(i+1)` to the stack. -17. Push the value :math:`\val` to the stack. +18. Push the value :math:`\val` to the stack. -18. Push the value :math:`\I32.\CONST~(n-1)` to the stack. +19. Push the value :math:`\X{at}.\CONST~(n-1)` to the stack. -19. Execute the instruction :math:`\TABLEFILL~x`. +20. Execute the instruction :math:`\TABLEFILL~x`. .. math:: \begin{array}{l} - S; F; (\I32.\CONST~i)~\val~(\I32.\CONST~n)~(\TABLEFILL~x) + S; F; (\X{at}.\CONST~i)~\val~(\X{at}.\CONST~n)~(\TABLEFILL~x) \quad\stepto\quad S; F; \TRAP \\ \qquad \begin{array}[t]{@{}r@{~}l@{}} (\iff & i + n > |S.\STABLES[F.\AMODULE.\MITABLES[x]].\TIELEM|) \\[1ex] \end{array} \\[1ex] - S; F; (\I32.\CONST~i)~\val~(\I32.\CONST~0)~(\TABLEFILL~x) + S; F; (\X{at}.\CONST~i)~\val~(\X{at}.\CONST~0)~(\TABLEFILL~x) \quad\stepto\quad S; F; \epsilon \\ \qquad (\otherwise) \\[1ex] - S; F; (\I32.\CONST~i)~\val~(\I32.\CONST~n+1)~(\TABLEFILL~x) + S; F; (\X{at}.\CONST~i)~\val~(\X{at}.\CONST~n+1)~(\TABLEFILL~x) \quad\stepto \\ \qquad S; F; \begin{array}[t]{@{}l@{}} - (\I32.\CONST~i)~\val~(\TABLESET~x) \\ - (\I32.\CONST~i+1)~\val~(\I32.\CONST~n)~(\TABLEFILL~x) \\ + (\X{at}.\CONST~i)~\val~(\TABLESET~x) \\ + (\X{at}.\CONST~i+1)~\val~(\X{at}.\CONST~n)~(\TABLEFILL~x) \\ \end{array} \\ \qquad (\otherwise) \\ @@ -2994,31 +2999,31 @@ Table Instructions 9. Let :math:`\X{tab}_y` be the :ref:`table instance ` :math:`S.\STABLES[\X{ta}_y]`. -10. Assert: due to :ref:`validation `, a value of :ref:`value type ` |I32| is on the top of the stack. +10. Assert: due to :ref:`validation `, a value of some :ref:`address type ` :math:`\X{at}_n` is on the top of the stack. -11. Pop the value :math:`\I32.\CONST~n` from the stack. +11. Pop the value :math:`\X{at}_n.\CONST~n` from the stack. -12. Assert: due to :ref:`validation `, a value of :ref:`value type ` |I32| is on the top of the stack. +12. Assert: due to :ref:`validation `, a value of some :ref:`address type ` :math:`\X{at}_s` is on the top of the stack. -13. Pop the value :math:`\I32.\CONST~s` from the stack. +13. Pop the value :math:`\X{at}_s.\CONST~s` from the stack. -14. Assert: due to :ref:`validation `, a value of :ref:`value type ` |I32| is on the top of the stack. +14. Assert: due to :ref:`validation `, a value of some :ref:`address type ` :math:`\X{at}_d` is on the top of the stack. -15. Pop the value :math:`\I32.\CONST~d` from the stack. +15. Pop the value :math:`\X{at}_d.\CONST~d` from the stack. 16. If :math:`s + n` is larger than the length of :math:`\X{tab}_y.\TIELEM` or :math:`d + n` is larger than the length of :math:`\X{tab}_x.\TIELEM`, then: a. Trap. -17. If :math:`n = 0`, then: +20. If :math:`n = 0`, then: a. Return. -18. If :math:`d \leq s`, then: +21. If :math:`d \leq s`, then: - a. Push the value :math:`\I32.\CONST~d` to the stack. + a. Push the value :math:`\X{at}_d.\CONST~d` to the stack. - b. Push the value :math:`\I32.\CONST~s` to the stack. + b. Push the value :math:`\X{at}_s.\CONST~s` to the stack. c. Execute the instruction :math:`\TABLEGET~y`. @@ -3026,38 +3031,38 @@ Table Instructions e. Assert: due to the earlier check against the table size, :math:`d+1 < 2^{32}`. - f. Push the value :math:`\I32.\CONST~(d+1)` to the stack. + f. Push the value :math:`\X{at}_d.\CONST~(d+1)` to the stack. g. Assert: due to the earlier check against the table size, :math:`s+1 < 2^{32}`. - h. Push the value :math:`\I32.\CONST~(s+1)` to the stack. + h. Push the value :math:`\X{at}_s.\CONST~(s+1)` to the stack. -19. Else: +22. Else: a. Assert: due to the earlier check against the table size, :math:`d+n-1 < 2^{32}`. - b. Push the value :math:`\I32.\CONST~(d+n-1)` to the stack. + b. Push the value :math:`\X{at}_d.\CONST~(d+n-1)` to the stack. c. Assert: due to the earlier check against the table size, :math:`s+n-1 < 2^{32}`. - d. Push the value :math:`\I32.\CONST~(s+n-1)` to the stack. + d. Push the value :math:`\X{at}_s.\CONST~(s+n-1)` to the stack. c. Execute the instruction :math:`\TABLEGET~y`. f. Execute the instruction :math:`\TABLESET~x`. - g. Push the value :math:`\I32.\CONST~d` to the stack. + g. Push the value :math:`\X{at}_d.\CONST~d` to the stack. - h. Push the value :math:`\I32.\CONST~s` to the stack. + h. Push the value :math:`\X{at}_s.\CONST~s` to the stack. -20. Push the value :math:`\I32.\CONST~(n-1)` to the stack. +23. Push the value :math:`\X{at}_n.\CONST~(n-1)` to the stack. -21. Execute the instruction :math:`\TABLECOPY~x~y`. +24. Execute the instruction :math:`\TABLECOPY~x~y`. .. math:: ~\\[-1ex] \begin{array}{l} - S; F; (\I32.\CONST~d)~(\I32.\CONST~s)~(\I32.\CONST~n)~(\TABLECOPY~x~y) + S; F; (\X{at}_d.\CONST~d)~(\X{at}_s.\CONST~s)~(\X{at}_n.\CONST~n)~(\TABLECOPY~x~y) \quad\stepto\quad S; F; \TRAP \\ \qquad \begin{array}[t]{@{}r@{~}l@{}} @@ -3065,27 +3070,27 @@ Table Instructions \vee & d + n > |S.\STABLES[F.\AMODULE.\MITABLES[x]].\TIELEM|) \\[1ex] \end{array} \\[1ex] - S; F; (\I32.\CONST~d)~(\I32.\CONST~s)~(\I32.\CONST~0)~(\TABLECOPY~x~y) + S; F; (\X{at}_d.\CONST~d)~(\X{at}_s.\CONST~s)~(\X{at}_n.\CONST~0)~(\TABLECOPY~x~y) \quad\stepto\quad S; F; \epsilon \\ \qquad (\otherwise) \\[1ex] - S; F; (\I32.\CONST~d)~(\I32.\CONST~s)~(\I32.\CONST~n+1)~(\TABLECOPY~x~y) + S; F; (\X{at}_d.\CONST~d)~(\X{at}_s.\CONST~s)~(\X{at}_n.\CONST~n+1)~(\TABLECOPY~x~y) \quad\stepto \\ \qquad S; F; \begin{array}[t]{@{}l@{}} - (\I32.\CONST~d)~(\I32.\CONST~s)~(\TABLEGET~y)~(\TABLESET~x) \\ - (\I32.\CONST~d+1)~(\I32.\CONST~s+1)~(\I32.\CONST~n)~(\TABLECOPY~x~y) \\ + (\X{at}_d.\CONST~d)~(\X{at}_s.\CONST~s)~(\TABLEGET~y)~(\TABLESET~x) \\ + (\X{at}_d.\CONST~d+1)~(\X{at}_s.\CONST~s+1)~(\X{at}_n.\CONST~n)~(\TABLECOPY~x~y) \\ \end{array} \\ \qquad (\otherwise, \iff d \leq s) \\[1ex] - S; F; (\I32.\CONST~d)~(\I32.\CONST~s)~(\I32.\CONST~n+1)~(\TABLECOPY~x~y) + S; F; (\X{at}_d.\CONST~d)~(\X{at}_s.\CONST~s)~(\X{at}_n.\CONST~n+1)~(\TABLECOPY~x~y) \quad\stepto \\ \qquad S; F; \begin{array}[t]{@{}l@{}} - (\I32.\CONST~d+n)~(\I32.\CONST~s+n)~(\TABLEGET~y)~(\TABLESET~x) \\ - (\I32.\CONST~d)~(\I32.\CONST~s)~(\I32.\CONST~n)~(\TABLECOPY~x~y) \\ + (\X{at}_d.\CONST~d+n)~(\X{at}_s.\CONST~s+n)~(\TABLEGET~y)~(\TABLESET~x) \\ + (\X{at}_d.\CONST~d)~(\X{at}_s.\CONST~s)~(\X{at}_n.\CONST~n)~(\TABLECOPY~x~y) \\ \end{array} \\ \qquad (\otherwise, \iff d > s) \\ @@ -3115,7 +3120,7 @@ Table Instructions 9. Let :math:`\X{elem}` be the :ref:`element instance ` :math:`S.\SELEMS[\X{ea}]`. -10. Assert: due to :ref:`validation `, a value of :ref:`value type ` |I32| is on the top of the stack. +10. Assert: due to :ref:`validation `, a value of :ref:`value type ` :math:`\I32` is on the top of the stack. 11. Pop the value :math:`\I32.\CONST~n` from the stack. @@ -3123,9 +3128,9 @@ Table Instructions 13. Pop the value :math:`\I32.\CONST~s` from the stack. -14. Assert: due to :ref:`validation `, a value of :ref:`value type ` |I32| is on the top of the stack. +14. Assert: due to :ref:`validation `, a value of some :ref:`address type ` :math:`\X{at}` is on the top of the stack. -15. Pop the value :math:`\I32.\CONST~d` from the stack. +15. Pop the value :math:`\X{at}.\CONST~d` from the stack. 16. If :math:`s + n` is larger than the length of :math:`\X{elem}.\EIELEM` or :math:`d + n` is larger than the length of :math:`\X{tab}.\TIELEM`, then: @@ -3137,7 +3142,7 @@ Table Instructions 18. Let :math:`\val` be the :ref:`reference value ` :math:`\X{elem}.\EIELEM[s]`. -19. Push the value :math:`\I32.\CONST~d` to the stack. +19. Push the value :math:`\X{at}.\CONST~d` to the stack. 20. Push the value :math:`\val` to the stack. @@ -3145,7 +3150,7 @@ Table Instructions 22. Assert: due to the earlier check against the table size, :math:`d+1 < 2^{32}`. -23. Push the value :math:`\I32.\CONST~(d+1)` to the stack. +23. Push the value :math:`\X{at}.\CONST~(d+1)` to the stack. 24. Assert: due to the earlier check against the segment size, :math:`s+1 < 2^{32}`. @@ -3158,7 +3163,7 @@ Table Instructions .. math:: ~\\[-1ex] \begin{array}{l} - S; F; (\I32.\CONST~d)~(\I32.\CONST~s)~(\I32.\CONST~n)~(\TABLEINIT~x~y) + S; F; (\X{at}.\CONST~d)~(\I32.\CONST~s)~(\I32.\CONST~n)~(\TABLEINIT~x~y) \quad\stepto\quad S; F; \TRAP \\ \qquad \begin{array}[t]{@{}r@{~}l@{}} @@ -3166,17 +3171,17 @@ Table Instructions \vee & d + n > |S.\STABLES[F.\AMODULE.\MITABLES[x]].\TIELEM|) \\[1ex] \end{array} \\[1ex] - S; F; (\I32.\CONST~d)~(\I32.\CONST~s)~(\I32.\CONST~0)~(\TABLEINIT~x~y) + S; F; (\X{at}.\CONST~d)~(\I32.\CONST~s)~(\I32.\CONST~0)~(\TABLEINIT~x~y) \quad\stepto\quad S; F; \epsilon \\ \qquad (\otherwise) \\[1ex] - S; F; (\I32.\CONST~d)~(\I32.\CONST~s)~(\I32.\CONST~n+1)~(\TABLEINIT~x~y) + S; F; (\X{at}.\CONST~d)~(\I32.\CONST~s)~(\I32.\CONST~n+1)~(\TABLEINIT~x~y) \quad\stepto \\ \qquad S; F; \begin{array}[t]{@{}l@{}} - (\I32.\CONST~d)~\val~(\TABLESET~x) \\ - (\I32.\CONST~d+1)~(\I32.\CONST~s+1)~(\I32.\CONST~n)~(\TABLEINIT~x~y) \\ + (\X{at}.\CONST~d)~\val~(\TABLESET~x) \\ + (\X{at}.\CONST~d+1)~(\I32.\CONST~s+1)~(\I32.\CONST~n)~(\TABLEINIT~x~y) \\ \end{array} \\ \qquad (\otherwise, \iff \val = S.\SELEMS[F.\AMODULE.\MIELEMS[y]].\EIELEM[s]) \\ @@ -3242,9 +3247,9 @@ Memory Instructions 5. Let :math:`\X{mem}` be the :ref:`memory instance ` :math:`S.\SMEMS[a]`. -6. Assert: due to :ref:`validation `, a value of :ref:`value type ` |I32| is on the top of the stack. +6. Assert: due to :ref:`validation `, a value of some :ref:`address type ` :math:`\X{at}` is on the top of the stack. -7. Pop the value :math:`\I32.\CONST~i` from the stack. +7. Pop the value :math:`\X{at}.\CONST~i` from the stack. 8. Let :math:`\X{ea}` be the integer :math:`i + \memarg.\OFFSET`. @@ -3274,7 +3279,7 @@ Memory Instructions ~\\[-1ex] \begin{array}{l} \begin{array}{lcl@{\qquad}l} - S; F; (\I32.\CONST~i)~(t.\LOAD~x~\memarg) &\stepto& S; F; (t.\CONST~c) + S; F; (\X{at}.\CONST~i)~(t.\LOAD~x~\memarg) &\stepto& S; F; (t.\CONST~c) \end{array} \\ \qquad \begin{array}[t]{@{}r@{~}l@{}} @@ -3284,7 +3289,7 @@ Memory Instructions \end{array} \\[1ex] \begin{array}{lcl@{\qquad}l} - S; F; (\I32.\CONST~i)~(t.\LOAD{N}\K{\_}\sx~x~\memarg) &\stepto& + S; F; (\X{at}.\CONST~i)~(t.\LOAD{N}\K{\_}\sx~x~\memarg) &\stepto& S; F; (t.\CONST~\extend^{\sx}_{N,|t|}(n)) \end{array} \\ \qquad @@ -3295,7 +3300,7 @@ Memory Instructions \end{array} \\[1ex] \begin{array}{lcl@{\qquad}l} - S; F; (\I32.\CONST~i)~(t.\LOAD({N}\K{\_}\sx)^?~x~\memarg) &\stepto& S; F; \TRAP + S; F; (\X{at}.\CONST~i)~(t.\LOAD({N}\K{\_}\sx)^?~x~\memarg) &\stepto& S; F; \TRAP \end{array} \\ \qquad (\otherwise) \\ @@ -3317,9 +3322,9 @@ Memory Instructions 5. Let :math:`\X{mem}` be the :ref:`memory instance ` :math:`S.\SMEMS[a]`. -6. Assert: due to :ref:`validation `, a value of :ref:`value type ` |I32| is on the top of the stack. +6. Assert: due to :ref:`validation `, a value of some :ref:`address type ` :math:`\X{at}` is on the top of the stack. -7. Pop the value :math:`\I32.\CONST~i` from the stack. +7. Pop the value :math:`\X{at}.\CONST~i` from the stack. 8. Let :math:`\X{ea}` be the integer :math:`i + \memarg.\OFFSET`. @@ -3343,7 +3348,7 @@ Memory Instructions ~\\[-1ex] \begin{array}{l} \begin{array}{lcl@{\qquad}l} - S; F; (\I32.\CONST~i)~(\V128.\LOAD{M}\K{x}N\_\sx~x~\memarg) &\stepto& + S; F; (\X{at}.\CONST~i)~(\V128.\LOAD{M}\K{x}N\_\sx~x~\memarg) &\stepto& S; F; (\V128.\CONST~c) \end{array} \\ \qquad @@ -3356,7 +3361,7 @@ Memory Instructions \end{array} \\[1ex] \begin{array}{lcl@{\qquad}l} - S; F; (\I32.\CONST~i)~(\V128.\LOAD{M}\K{x}N\K{\_}\sx~x~\memarg) &\stepto& S; F; \TRAP + S; F; (\X{at}.\CONST~i)~(\V128.\LOAD{M}\K{x}N\K{\_}\sx~x~\memarg) &\stepto& S; F; \TRAP \end{array} \\ \qquad (\otherwise) \\ @@ -3378,9 +3383,9 @@ Memory Instructions 5. Let :math:`\X{mem}` be the :ref:`memory instance ` :math:`S.\SMEMS[a]`. -6. Assert: due to :ref:`validation `, a value of :ref:`value type ` |I32| is on the top of the stack. +6. Assert: due to :ref:`validation `, a value of some :ref:`address type ` :math:`\X{at}` is on the top of the stack. -7. Pop the value :math:`\I32.\CONST~i` from the stack. +7. Pop the value :math:`\X{at}.\CONST~i` from the stack. 8. Let :math:`\X{ea}` be the integer :math:`i + \memarg.\OFFSET`. @@ -3402,7 +3407,7 @@ Memory Instructions ~\\[-1ex] \begin{array}{l} \begin{array}{lcl@{\qquad}l} - S; F; (\I32.\CONST~i)~(\V128\K{.}\LOAD{N}\K{\_splat}~x~\memarg) &\stepto& S; F; (\V128.\CONST~c) + S; F; (\X{at}.\CONST~i)~(\V128\K{.}\LOAD{N}\K{\_splat}~x~\memarg) &\stepto& S; F; (\V128.\CONST~c) \end{array} \\ \qquad \begin{array}[t]{@{}r@{~}l@{}} @@ -3413,7 +3418,7 @@ Memory Instructions \end{array} \\[1ex] \begin{array}{lcl@{\qquad}l} - S; F; (\I32.\CONST~i)~(\V128.\LOAD{N}\K{\_splat}~x~\memarg) &\stepto& S; F; \TRAP + S; F; (\X{at}.\CONST~i)~(\V128.\LOAD{N}\K{\_splat}~x~\memarg) &\stepto& S; F; \TRAP \end{array} \\ \qquad (\otherwise) \\ @@ -3435,9 +3440,9 @@ Memory Instructions 5. Let :math:`\X{mem}` be the :ref:`memory instance ` :math:`S.\SMEMS[a]`. -6. Assert: due to :ref:`validation `, a value of :ref:`value type ` |I32| is on the top of the stack. +6. Assert: due to :ref:`validation `, a value of some :ref:`address type ` :math:`\X{at}` is on the top of the stack. -7. Pop the value :math:`\I32.\CONST~i` from the stack. +7. Pop the value :math:`\X{at}.\CONST~i` from the stack. 8. Let :math:`\X{ea}` be the integer :math:`i + \memarg.\OFFSET`. @@ -3457,7 +3462,7 @@ Memory Instructions ~\\[-1ex] \begin{array}{l} \begin{array}{lcl@{\qquad}l} - S; F; (\I32.\CONST~i)~(\V128\K{.}\LOAD{N}\K{\_zero}~x~\memarg) &\stepto& S; F; (\V128.\CONST~c) + S; F; (\X{at}.\CONST~i)~(\V128\K{.}\LOAD{N}\K{\_zero}~x~\memarg) &\stepto& S; F; (\V128.\CONST~c) \end{array} \\ \qquad \begin{array}[t]{@{}r@{~}l@{}} @@ -3468,7 +3473,7 @@ Memory Instructions \end{array} \\[1ex] \begin{array}{lcl@{\qquad}l} - S; F; (\I32.\CONST~i)~(\V128.\LOAD{N}\K{\_zero}~x~\memarg) &\stepto& S; F; \TRAP + S; F; (\X{at}.\CONST~i)~(\V128.\LOAD{N}\K{\_zero}~x~\memarg) &\stepto& S; F; \TRAP \end{array} \\ \qquad (\otherwise) \\ @@ -3494,9 +3499,9 @@ Memory Instructions 7. Pop the value :math:`\V128.\CONST~v` from the stack. -8. Assert: due to :ref:`validation `, a value of :ref:`value type ` |I32| is on the top of the stack. +8. Assert: due to :ref:`validation `, a value of some :ref:`address type ` :math:`\X{at}` is on the top of the stack. -9. Pop the value :math:`\I32.\CONST~i` from the stack. +9. Pop the value :math:`\X{at}.\CONST~i` from the stack. 10. Let :math:`\X{ea}` be the integer :math:`i + \memarg.\OFFSET`. @@ -3520,7 +3525,7 @@ Memory Instructions ~\\[-1ex] \begin{array}{l} \begin{array}{lcl@{\qquad}l} - S; F; (\I32.\CONST~i)~(\V128.\CONST~v)~(\V128\K{.}\LOAD{N}\K{\_lane}~x~\memarg~y) &\stepto& S; F; (\V128.\CONST~c) + S; F; (\X{at}.\CONST~i)~(\V128.\CONST~v)~(\V128\K{.}\LOAD{N}\K{\_lane}~x~\memarg~y) &\stepto& S; F; (\V128.\CONST~c) \end{array} \\ \qquad \begin{array}[t]{@{}r@{~}l@{}} @@ -3532,7 +3537,7 @@ Memory Instructions \end{array} \\[1ex] \begin{array}{lcl@{\qquad}l} - S; F; (\I32.\CONST~i)~(\V128.\CONST~v)~(\V128.\LOAD{N}\K{\_lane}~x~\memarg~y) &\stepto& S; F; \TRAP + S; F; (\X{at}.\CONST~i)~(\V128.\CONST~v)~(\V128.\LOAD{N}\K{\_lane}~x~\memarg~y) &\stepto& S; F; \TRAP \end{array} \\ \qquad (\otherwise) \\ @@ -3559,9 +3564,9 @@ Memory Instructions 7. Pop the value :math:`t.\CONST~c` from the stack. -8. Assert: due to :ref:`validation `, a value of :ref:`value type ` |I32| is on the top of the stack. +8. Assert: due to :ref:`validation `, a value of some :ref:`address type ` :math:`\X{at}` is on the top of the stack. -9. Pop the value :math:`\I32.\CONST~i` from the stack. +9. Pop the value :math:`\X{at}.\CONST~i` from the stack. 10. Let :math:`\X{ea}` be the integer :math:`i + \memarg.\OFFSET`. @@ -3589,7 +3594,7 @@ Memory Instructions ~\\[-1ex] \begin{array}{l} \begin{array}{lcl@{\qquad}l} - S; F; (\I32.\CONST~i)~(t.\CONST~c)~(t.\STORE~x~\memarg) &\stepto& S'; F; \epsilon + S; F; (\X{at}.\CONST~i)~(t.\CONST~c)~(t.\STORE~x~\memarg) &\stepto& S'; F; \epsilon \end{array} \\ \qquad \begin{array}[t]{@{}r@{~}l@{}} @@ -3599,7 +3604,7 @@ Memory Instructions \end{array} \\[1ex] \begin{array}{lcl@{\qquad}l} - S; F; (\I32.\CONST~i)~(t.\CONST~c)~(t.\STORE{N}~x~\memarg) &\stepto& S'; F; \epsilon + S; F; (\X{at}.\CONST~i)~(t.\CONST~c)~(t.\STORE{N}~x~\memarg) &\stepto& S'; F; \epsilon \end{array} \\ \qquad \begin{array}[t]{@{}r@{~}l@{}} @@ -3609,7 +3614,7 @@ Memory Instructions \end{array} \\[1ex] \begin{array}{lcl@{\qquad}l} - S; F; (\I32.\CONST~i)~(t.\CONST~c)~(t.\STORE{N}^?~x~\memarg) &\stepto& S; F; \TRAP + S; F; (\X{at}.\CONST~i)~(t.\CONST~c)~(t.\STORE{N}^?~x~\memarg) &\stepto& S; F; \TRAP \end{array} \\ \qquad (\otherwise) \\ @@ -3635,9 +3640,9 @@ Memory Instructions 7. Pop the value :math:`\V128.\CONST~c` from the stack. -8. Assert: due to :ref:`validation `, a value of :ref:`value type ` |I32| is on the top of the stack. +8. Assert: due to :ref:`validation `, a value of some :ref:`address type ` :math:`\X{at}` is on the top of the stack. -9. Pop the value :math:`\I32.\CONST~i` from the stack. +9. Pop the value :math:`\X{at}.\CONST~i` from the stack. 10. Let :math:`\X{ea}` be the integer :math:`i + \memarg.\OFFSET`. @@ -3657,7 +3662,7 @@ Memory Instructions ~\\[-1ex] \begin{array}{l} \begin{array}{lcl@{\qquad}l} - S; F; (\I32.\CONST~i)~(\V128.\CONST~c)~(\V128.\STORE{N}\K{\_lane}~x~\memarg~y) &\stepto& S'; F; \epsilon + S; F; (\X{at}.\CONST~i)~(\V128.\CONST~c)~(\V128.\STORE{N}\K{\_lane}~x~\memarg~y) &\stepto& S'; F; \epsilon \end{array} \\ \qquad \begin{array}[t]{@{}r@{~}l@{}} @@ -3668,7 +3673,7 @@ Memory Instructions \end{array} \\[1ex] \begin{array}{lcl@{\qquad}l} - S; F; (\I32.\CONST~i)~(\V128.\CONST~c)~(\V128.\STORE{N}\K{\_lane}~x~\memarg~y) &\stepto& S; F; \TRAP + S; F; (\X{at}.\CONST~i)~(\V128.\CONST~c)~(\V128.\STORE{N}\K{\_lane}~x~\memarg~y) &\stepto& S; F; \TRAP \end{array} \\ \qquad (\otherwise) \\ @@ -3690,17 +3695,22 @@ Memory Instructions 5. Let :math:`\X{mem}` be the :ref:`memory instance ` :math:`S.\SMEMS[a]`. -6. Let :math:`\X{sz}` be the length of :math:`\X{mem}.\MIDATA` divided by the :ref:`page size `. +6. Let :math:`\X{at}~\limits` be the :ref:`memory type ` :math:`\X{mem}.\MITYPE`. + +7. Let :math:`\X{sz}` be the length of :math:`\X{mem}.\MIDATA` divided by the :ref:`page size `. -7. Push the value :math:`\I32.\CONST~\X{sz}` to the stack. +8. Push the value :math:`\X{at}.\CONST~\X{sz}` to the stack. .. math:: \begin{array}{l} \begin{array}{lcl@{\qquad}l} - S; F; (\MEMORYSIZE~x) &\stepto& S; F; (\I32.\CONST~\X{sz}) + S; F; (\MEMORYSIZE~x) &\stepto& S; F; (\X{at}.\CONST~\X{sz}) \end{array} \\ \qquad - (\iff |S.\SMEMS[F.\AMODULE.\MIMEMS[x]].\MIDATA| = \X{sz}\cdot64\,\F{Ki}) \\ + \begin{array}[t]{@{}r@{~}l@{}} + (\iff |S.\SMEMS[F.\AMODULE.\MIMEMS[x]].\MIDATA| = \X{sz}\cdot64\,\F{Ki} \\ + \wedge S.\SMEMS[F.\AMODULE.\MIMEMS[x]].\MITYPE = \X{at}~\X{lim}) + \end{array} \\ \end{array} @@ -3722,31 +3732,31 @@ Memory Instructions 6. Let :math:`\X{sz}` be the length of :math:`S.\SMEMS[a]` divided by the :ref:`page size `. -7. Assert: due to :ref:`validation `, a value of :ref:`value type ` |I32| is on the top of the stack. +7. Assert: due to :ref:`validation `, a value of some :ref:`address type ` :math:`\X{at}` is on the top of the stack. -8. Pop the value :math:`\I32.\CONST~n` from the stack. +8. Pop the value :math:`\X{at}.\CONST~n` from the stack. -9. Let :math:`\X{err}` be the |i32| value :math:`2^{32}-1`, for which :math:`\signed_{32}(\X{err})` is :math:`-1`. +9. Let :math:`\X{err}` be the :math:`\X{at}` value :math:`2^{|\X{at}|}-1`, for which :math:`\signed_{|\X{at}|}(\X{err})` is :math:`-1`. 10. Either: a. If :ref:`growing ` :math:`\X{mem}` by :math:`n` :ref:`pages ` succeeds, then: - i. Push the value :math:`\I32.\CONST~\X{sz}` to the stack. + i. Push the value :math:`\X{at}.\CONST~\X{sz}` to the stack. b. Else: - i. Push the value :math:`\I32.\CONST~\X{err}` to the stack. + i. Push the value :math:`\X{at}.\CONST~\X{err}` to the stack. 11. Or: - a. Push the value :math:`\I32.\CONST~\X{err}` to the stack. + a. Push the value :math:`\X{at}.\CONST~\X{err}` to the stack. .. math:: ~\\[-1ex] \begin{array}{l} \begin{array}{lcl@{\qquad}l} - S; F; (\I32.\CONST~n)~(\MEMORYGROW~x) &\stepto& S'; F; (\I32.\CONST~\X{sz}) + S; F; (\X{at}.\CONST~n)~(\MEMORYGROW~x) &\stepto& S'; F; (\X{at}.\CONST~\X{sz}) \end{array} \\ \qquad \begin{array}[t]{@{}r@{~}l@{}} @@ -3756,7 +3766,7 @@ Memory Instructions \end{array} \\[1ex] \begin{array}{lcl@{\qquad}l} - S; F; (\I32.\CONST~n)~(\MEMORYGROW~x) &\stepto& S; F; (\I32.\CONST~\signed_{32}^{-1}(-1)) + S; F; (\X{at}.\CONST~n)~(\MEMORYGROW~x) &\stepto& S; F; (\X{at}.\CONST~\signed_{|\X{at}|}^{-1}(-1)) \end{array} \end{array} @@ -3784,17 +3794,17 @@ Memory Instructions 5. Let :math:`\X{mem}` be the :ref:`memory instance ` :math:`S.\SMEMS[\X{ma}]`. -6. Assert: due to :ref:`validation `, a value of :ref:`value type ` |I32| is on the top of the stack. +6. Assert: due to :ref:`validation `, a value of some :ref:`address type ` :math:`\X{at}` is on the top of the stack. -7. Pop the value :math:`\I32.\CONST~n` from the stack. +7. Pop the value :math:`\X{at}.\CONST~n` from the stack. -8. Assert: due to :ref:`validation `, a value of :ref:`value type ` |I32| is on the top of the stack. +8. Assert: due to :ref:`validation `, a value is on the top of the stack. 9. Pop the value :math:`\val` from the stack. -10. Assert: due to :ref:`validation `, a value of :ref:`value type ` |I32| is on the top of the stack. +10. Assert: due to :ref:`validation `, a value of :ref:`address type ` :math:`\X{at}` is on the top of the stack. -11. Pop the value :math:`\I32.\CONST~d` from the stack. +11. Pop the value :math:`\X{at}.\CONST~d` from the stack. 12. If :math:`d + n` is larger than the length of :math:`\X{mem}.\MIDATA`, then: @@ -3808,37 +3818,37 @@ Memory Instructions 15. Push the value :math:`\val` to the stack. -16. Execute the instruction :math:`\I32\K{.}\STORE\K{8}~\{ \OFFSET~0, \ALIGN~0 \}`. +16. Execute the instruction :math:`\X{at}\K{.}\STORE\K{8}~\{ \OFFSET~0, \ALIGN~0 \}`. 17. Assert: due to the earlier check against the memory size, :math:`d+1 < 2^{32}`. -18. Push the value :math:`\I32.\CONST~(d+1)` to the stack. +18. Push the value :math:`\X{at}.\CONST~(d+1)` to the stack. 19. Push the value :math:`\val` to the stack. -20. Push the value :math:`\I32.\CONST~(n-1)` to the stack. +20. Push the value :math:`\X{at}.\CONST~(n-1)` to the stack. 21. Execute the instruction :math:`\MEMORYFILL~x`. .. math:: ~\\[-1ex] \begin{array}{l} - S; F; (\I32.\CONST~d)~\val~(\I32.\CONST~n)~\MEMORYFILL~x + S; F; (\X{at}.\CONST~d)~\val~(\X{at}.\CONST~n)~\MEMORYFILL~x \quad\stepto\quad S; F; \TRAP \\ \qquad (\iff d + n > |S.\SMEMS[F.\AMODULE.\MIMEMS[x]].\MIDATA|) \\[1ex] - S; F; (\I32.\CONST~d)~\val~(\I32.\CONST~0)~\MEMORYFILL~x + S; F; (\X{at}.\CONST~d)~\val~(\X{at}.\CONST~0)~\MEMORYFILL~x \quad\stepto\quad S; F; \epsilon \\ \qquad (\otherwise) \\[1ex] - S; F; (\I32.\CONST~d)~\val~(\I32.\CONST~n+1)~\MEMORYFILL~x + S; F; (\X{at}.\CONST~d)~\val~(\X{at}.\CONST~n+1)~\MEMORYFILL~x \quad\stepto \\ \qquad S; F; \begin{array}[t]{@{}l@{}} - (\I32.\CONST~d)~\val~(\I32\K{.}\STORE\K{8}~x~\{ \OFFSET~0, \ALIGN~0 \}) \\ - (\I32.\CONST~d+1)~\val~(\I32.\CONST~n)~\MEMORYFILL~x \\ + (\X{at}.\CONST~d)~\val~(\X{at}\K{.}\STORE\K{8}~x~\{ \OFFSET~0, \ALIGN~0 \}) \\ + (\X{at}.\CONST~d+1)~\val~(\X{at}.\CONST~n)~\MEMORYFILL~x \\ \end{array} \\ \qquad (\otherwise) \\ @@ -3868,17 +3878,17 @@ Memory Instructions 9. Let :math:`\X{mem}_s` be the :ref:`memory instance ` :math:`S.\SMEMS[\X{sa}]`. -10. Assert: due to :ref:`validation `, a value of :ref:`value type ` |I32| is on the top of the stack. +10. Assert: due to :ref:`validation `, a value of some :ref:`address type ` :math:`\X{at}_n` is on the top of the stack. -11. Pop the value :math:`\I32.\CONST~n` from the stack. +11. Pop the value :math:`\X{at}_n.\CONST~n` from the stack. -12. Assert: due to :ref:`validation `, a value of :ref:`value type ` |I32| is on the top of the stack. +12. Assert: due to :ref:`validation `, a value of some :ref:`address type ` :math:`\X{at}_s` is on the top of the stack. -13. Pop the value :math:`\I32.\CONST~s` from the stack. +13. Pop the value :math:`\X{at}_s.\CONST~s` from the stack. -14. Assert: due to :ref:`validation `, a value of :ref:`value type ` |I32| is on the top of the stack. +14. Assert: due to :ref:`validation `, a value of some :ref:`address type ` :math:`\X{at}_d` is on the top of the stack. -15. Pop the value :math:`\I32.\CONST~d` from the stack. +15. Pop the value :math:`\X{at}_d.\CONST~d` from the stack. 16. If :math:`s + n` is larger than the length of :math:`\X{mem}_s.\MIDATA` or :math:`d + n` is larger than the length of :math:`\X{mem}_d.\MIDATA`, then: @@ -3890,9 +3900,9 @@ Memory Instructions 18. If :math:`d \leq s`, then: - a. Push the value :math:`\I32.\CONST~d` to the stack. + a. Push the value :math:`\X{at}_d.\CONST~d` to the stack. - b. Push the value :math:`\I32.\CONST~s` to the stack. + b. Push the value :math:`\X{at}_s.\CONST~s` to the stack. c. Execute the instruction :math:`\I32\K{.}\LOAD\K{8\_u}~y~\{ \OFFSET~0, \ALIGN~0 \}`. @@ -3900,70 +3910,70 @@ Memory Instructions e. Assert: due to the earlier check against the memory size, :math:`d+1 < 2^{32}`. - f. Push the value :math:`\I32.\CONST~(d+1)` to the stack. + f. Push the value :math:`\X{at}_d.\CONST~(d+1)` to the stack. g. Assert: due to the earlier check against the memory size, :math:`s+1 < 2^{32}`. - h. Push the value :math:`\I32.\CONST~(s+1)` to the stack. + h. Push the value :math:`\X{at}_s.\CONST~(s+1)` to the stack. 19. Else: a. Assert: due to the earlier check against the memory size, :math:`d+n-1 < 2^{32}`. - b. Push the value :math:`\I32.\CONST~(d+n-1)` to the stack. + b. Push the value :math:`\X{at}_d.\CONST~(d+n-1)` to the stack. c. Assert: due to the earlier check against the memory size, :math:`s+n-1 < 2^{32}`. - d. Push the value :math:`\I32.\CONST~(s+n-1)` to the stack. + d. Push the value :math:`\X{at}_s.\CONST~(s+n-1)` to the stack. e. Execute the instruction :math:`\I32\K{.}\LOAD\K{8\_u}~y~\{ \OFFSET~0, \ALIGN~0 \}`. f. Execute the instruction :math:`\I32\K{.}\STORE\K{8}~x~\{ \OFFSET~0, \ALIGN~0 \}`. - g. Push the value :math:`\I32.\CONST~d` to the stack. + g. Push the value :math:`\X{at}_d.\CONST~d` to the stack. - h. Push the value :math:`\I32.\CONST~s` to the stack. + h. Push the value :math:`\X{at}_s.\CONST~s` to the stack. -20. Push the value :math:`\I32.\CONST~(n-1)` to the stack. +20. Push the value :math:`\X{at}_n.\CONST~(n-1)` to the stack. 21. Execute the instruction :math:`\MEMORYCOPY~x~y`. .. math:: ~\\[-1ex] \begin{array}{l} - S; F; (\I32.\CONST~d)~(\I32.\CONST~s)~(\I32.\CONST~n)~\MEMORYCOPY~x~y + S; F; (\X{at}_x.\CONST~d)~(\X{at}_y.\CONST~s)~(\X{at}_n.\CONST~n)~\MEMORYCOPY~x~y \quad\stepto\quad S; F; \TRAP \\ \qquad \begin{array}[t]{@{}r@{~}l@{}} - (\iff & d + n > |S.\SMEMS[F.\AMODULE.\MIMEMS[x]].\MIDATA| \\ - \vee & s + n > |S.\SMEMS[F.\AMODULE.\MIMEMS[y]].\MIDATA|) \\[1ex] + (\iff & (d + n > |S.\SMEMS[F.\AMODULE.\MIMEMS[x]].\MIDATA| \\ + \vee & s + n > |S.\SMEMS[F.\AMODULE.\MIMEMS[y]].\MIDATA|)) \\ \end{array} \\[1ex] - S; F; (\I32.\CONST~d)~(\I32.\CONST~s)~(\I32.\CONST~0)~\MEMORYCOPY~x~y + S; F; (\X{at}_x.\CONST~d)~(\X{at}_y.\CONST~s)~(\X{at}_n.\CONST~0)~\MEMORYCOPY~x~y \quad\stepto\quad S; F; \epsilon \\ \qquad (\otherwise) \\[1ex] - S; F; (\I32.\CONST~d)~(\I32.\CONST~s)~(\I32.\CONST~n+1)~\MEMORYCOPY~x~y + S; F; (\X{at}_x.\CONST~d)~(\X{at}_y.\CONST~s)~(\X{at}_n.\CONST~n+1)~\MEMORYCOPY~x~y \quad\stepto \\ \qquad S; F; \begin{array}[t]{@{}l@{}} - (\I32.\CONST~d) \\ - (\I32.\CONST~s)~(\I32\K{.}\LOAD\K{8\_u}~y~\{ \OFFSET~0, \ALIGN~0 \}) \\ + (\X{at}_x.\CONST~d) \\ + (\X{at}_y.\CONST~s)~(\I32\K{.}\LOAD\K{8\_u}~y~\{ \OFFSET~0, \ALIGN~0 \}) \\ (\I32\K{.}\STORE\K{8}~x~\{ \OFFSET~0, \ALIGN~0 \}) \\ - (\I32.\CONST~d+1)~(\I32.\CONST~s+1)~(\I32.\CONST~n)~\MEMORYCOPY~x~y \\ + (\X{at}_x.\CONST~d+1)~(\X{at}_y.\CONST~s+1)~(\X{at}_n.\CONST~n)~\MEMORYCOPY~x~y \\ \end{array} \\ \qquad (\otherwise, \iff d \leq s) \\[1ex] - S; F; (\I32.\CONST~d)~(\I32.\CONST~s)~(\I32.\CONST~n+1)~\MEMORYCOPY~x~y + S; F; (\X{at}_x.\CONST~d)~(\X{at}_y.\CONST~s)~(\X{at}_n.\CONST~n+1)~\MEMORYCOPY~x~y \quad\stepto \\ \qquad S; F; \begin{array}[t]{@{}l@{}} - (\I32.\CONST~d+n) \\ - (\I32.\CONST~s+n)~(\I32\K{.}\LOAD\K{8\_u}~y~\{ \OFFSET~0, \ALIGN~0 \}) \\ + (\X{at}_x.\CONST~d+n) \\ + (\X{at}_y.\CONST~s+n)~(\I32\K{.}\LOAD\K{8\_u}~y~\{ \OFFSET~0, \ALIGN~0 \}) \\ (\I32\K{.}\STORE\K{8}~x~\{ \OFFSET~0, \ALIGN~0 \}) \\ - (\I32.\CONST~d)~(\I32.\CONST~s)~(\I32.\CONST~n)~\MEMORYCOPY~x~y \\ + (\X{at}_x.\CONST~d)~(\X{at}_y.\CONST~s)~(\X{at}_n.\CONST~n)~\MEMORYCOPY~x~y \\ \end{array} \\ \qquad (\otherwise, \iff d > s) \\ @@ -4001,9 +4011,9 @@ Memory Instructions 13. Pop the value :math:`\I32.\CONST~s` from the stack. -14. Assert: due to :ref:`validation `, a value of :ref:`value type ` |I32| is on the top of the stack. +14. Assert: due to :ref:`validation `, a value of some :ref:`address type ` :math:`\X{at}` is on the top of the stack. -15. Pop the value :math:`\I32.\CONST~d` from the stack. +15. Pop the value :math:`\X{at}.\CONST~d` from the stack. 16. If :math:`s + n` is larger than the length of :math:`\X{data}.\DIDATA` or :math:`d + n` is larger than the length of :math:`\X{mem}.\MIDATA`, then: @@ -4015,7 +4025,7 @@ Memory Instructions 18. Let :math:`b` be the byte :math:`\X{data}.\DIDATA[s]`. -19. Push the value :math:`\I32.\CONST~d` to the stack. +19. Push the value :math:`\X{at}.\CONST~d` to the stack. 20. Push the value :math:`\I32.\CONST~b` to the stack. @@ -4023,7 +4033,7 @@ Memory Instructions 22. Assert: due to the earlier check against the memory size, :math:`d+1 < 2^{32}`. -23. Push the value :math:`\I32.\CONST~(d+1)` to the stack. +23. Push the value :math:`\X{at}.\CONST~(d+1)` to the stack. 24. Assert: due to the earlier check against the memory size, :math:`s+1 < 2^{32}`. @@ -4036,7 +4046,7 @@ Memory Instructions .. math:: ~\\[-1ex] \begin{array}{l} - S; F; (\I32.\CONST~d)~(\I32.\CONST~s)~(\I32.\CONST~n)~(\MEMORYINIT~x~y) + S; F; (\X{at}.\CONST~d)~(\I32.\CONST~s)~(\I32.\CONST~n)~(\MEMORYINIT~x~y) \quad\stepto\quad S; F; \TRAP \\ \qquad \begin{array}[t]{@{}r@{~}l@{}} @@ -4044,17 +4054,17 @@ Memory Instructions \vee & s + n > |S.\SDATAS[F.\AMODULE.\MIDATAS[y]].\MIDATA|) \\[1ex] \end{array} \\[1ex] - S; F; (\I32.\CONST~d)~(\I32.\CONST~s)~(\I32.\CONST~0)~(\MEMORYINIT~x~y) + S; F; (\X{at}.\CONST~d)~(\I32.\CONST~s)~(\I32.\CONST~0)~(\MEMORYINIT~x~y) \quad\stepto\quad S; F; \epsilon \\ \qquad (\otherwise) \\[1ex] - S; F; (\I32.\CONST~d)~(\I32.\CONST~s)~(\I32.\CONST~n+1)~(\MEMORYINIT~x~y) + S; F; (\X{at}.\CONST~d)~(\I32.\CONST~s)~(\I32.\CONST~n+1)~(\MEMORYINIT~x~y) \quad\stepto \\ \qquad S; F; \begin{array}[t]{@{}l@{}} - (\I32.\CONST~d)~(\I32.\CONST~b)~(\I32\K{.}\STORE\K{8}~x~\{ \OFFSET~0, \ALIGN~0 \}) \\ - (\I32.\CONST~d+1)~(\I32.\CONST~s+1)~(\I32.\CONST~n)~(\MEMORYINIT~x~y) \\ + (\X{at}.\CONST~d)~(\I32.\CONST~b)~(\I32\K{.}\STORE\K{8}~x~\{ \OFFSET~0, \ALIGN~0 \}) \\ + (\X{at}.\CONST~d+1)~(\I32.\CONST~s+1)~(\I32.\CONST~n)~(\MEMORYINIT~x~y) \\ \end{array} \\ \qquad (\otherwise, \iff b = S.\SDATAS[F.\AMODULE.\MIDATAS[y]].\DIDATA[s]) \\ @@ -4216,11 +4226,11 @@ Control Instructions 2. Assert: due to :ref:`validation `, :math:`F.\AMODULE.\MITAGS[x]` exists. -3. Let :math:`ta` be the :ref:`tag address ` :math:`F.\AMODULE.\MITAGS[x]`. +3. Let :math:`\X{ta}` be the :ref:`tag address ` :math:`F.\AMODULE.\MITAGS[x]`. -4. Assert: due to :ref:`validation `, :math:`S.\STAGS[ta]` exists. +4. Assert: due to :ref:`validation `, :math:`S.\STAGS[\X{ta}]` exists. -5. Let :math:`\X{ti}` be the :ref:`tag instance ` :math:`S.\STAGS[ta]`. +5. Let :math:`\X{ti}` be the :ref:`tag instance ` :math:`S.\STAGS[\X{ta}]`. 6. Let :math:`[t^n] \toF [{t'}^\ast]` be the :ref:`tag type ` :math:`\X{ti}.\TAGITYPE`. @@ -4228,13 +4238,15 @@ Control Instructions 8. Pop the :math:`n` values :math:`\val^n` from the stack. -9. Let :math:`\X{ea}` be the :ref:`exception address ` resulting from :ref:`allocating ` an exception instance with tag address :math:`ta` and initializer values :math:`\val^n`. +9. Let :math:`\X{exn}` be the :ref:`exception instance ` :math:`\{\EITAG~\X{ta}, \EIFIELDS~\val^n\}`. + +10. Let :math:`\X{ea}` be the length of :math:`S.\SEXNS`. -10. Let :math:`\X{exn}` be :math:`S.\SEXNS[ea]` +11. Append :math:`\X{exn}` to :math:`S.\SEXNS`. -11. Push the value :math:`\REFEXNADDR~\X{ea}` to the stack. +12. Push the value :math:`\REFEXNADDR~\X{ea}` to the stack. -12. Execute the instruction |THROWREF|. +13. Execute the instruction |THROWREF|. .. math:: ~\\[-1ex] diff --git a/document/core/exec/modules.rst b/document/core/exec/modules.rst index eef15836d0..be2b62b952 100644 --- a/document/core/exec/modules.rst +++ b/document/core/exec/modules.rst @@ -94,11 +94,11 @@ are *allocated* in a :ref:`store ` :math:`S`, as defined by the fo 1. Let :math:`\tabletype` be the :ref:`table type ` of the table to allocate and :math:`\reff` the initialization value. -2. Let :math:`(\{\LMIN~n, \LMAX~m^?\}~\reftype)` be the structure of :ref:`table type ` :math:`\tabletype`. +2. Let :math:`(\addrtype~\{\LMIN~n, \LMAX~m^?\}~\reftype)` be the structure of :ref:`table type ` :math:`\tabletype`. 3. Let :math:`a` be the first free :ref:`table address ` in :math:`S`. -4. Let :math:`\tableinst` be the :ref:`table instance ` :math:`\{ \TITYPE~\tabletype', \TIELEM~\reff^n \}` with :math:`n` elements set to :math:`\reff`. +4. Let :math:`\tableinst` be the :ref:`table instance ` :math:`\{ \TITYPE~\tabletype, \TIELEM~\reff^n \}` with :math:`n` elements set to :math:`\reff`. 5. Append :math:`\tableinst` to the |STABLES| of :math:`S`. @@ -108,7 +108,7 @@ are *allocated* in a :ref:`store ` :math:`S`, as defined by the fo \begin{array}{rlll} \alloctable(S, \tabletype, \reff) &=& S', \tableaddr \\[1ex] \mbox{where:} \hfill \\ - \tabletype &=& \{\LMIN~n, \LMAX~m^?\}~\reftype \\ + \tabletype &=& \addrtype~\{\LMIN~n, \LMAX~m^?\}~\reftype \\ \tableaddr &=& |S.\STABLES| \\ \tableinst &=& \{ \TITYPE~\tabletype, \TIELEM~\reff^n \} \\ S' &=& S \compose \{\STABLES~\tableinst\} \\ @@ -123,7 +123,7 @@ are *allocated* in a :ref:`store ` :math:`S`, as defined by the fo 1. Let :math:`\memtype` be the :ref:`memory type ` of the memory to allocate. -2. Let :math:`\{\LMIN~n, \LMAX~m^?\}` be the structure of :ref:`memory type ` :math:`\memtype`. +2. Let :math:`(\addrtype~\{\LMIN~n, \LMAX~m^?\})` be the structure of :ref:`memory type ` :math:`\memtype`. 3. Let :math:`a` be the first free :ref:`memory address ` in :math:`S`. @@ -137,7 +137,7 @@ are *allocated* in a :ref:`store ` :math:`S`, as defined by the fo \begin{array}{rlll} \allocmem(S, \memtype) &=& S', \memaddr \\[1ex] \mbox{where:} \hfill \\ - \memtype &=& \{\LMIN~n, \LMAX~m^?\} \\ + \memtype &=& \addrtype~\{\LMIN~n, \LMAX~m^?\} \\ \memaddr &=& |S.\SMEMS| \\ \meminst &=& \{ \MITYPE~\memtype, \MIDATA~(\hex{00})^{n \cdot 64\,\F{Ki}} \} \\ S' &=& S \compose \{\SMEMS~\meminst\} \\ @@ -170,32 +170,6 @@ are *allocated* in a :ref:`store ` :math:`S`, as defined by the fo \end{array} -.. index:: exception, exception instance, exception address, tag address -.. _alloc-exception: - -:ref:`Exceptions ` -.................................. - -1. Let :math:`ta` be the :ref:`tag address ` associated with the exception to allocate and :math:`\EIFIELDS~\val^\ast` be the values to initialize the exception with. - -2. Let :math:`a` be the first free :ref:`exception address ` in :math:`S`. - -3. Let :math:`\exninst` be the :ref:`exception instance ` :math:`\{ \EITAG~ta, \EIFIELDS~\val^\ast \}`. - -4. Append :math:`\exninst` to the |SEXNS| of :math:`S`. - -5. Return :math:`a`. - -.. math:: - \begin{array}{rlll} - \allocexn(S, \tagaddr, \val^\ast) &=& S', \exnaddr \\[1ex] - \mbox{where:} \hfill \\ - \exnaddr &=& |S.\SEXNS| \\ - \exninst &=& \{ \EITAG~\tagaddr, \EIFIELDS~\val^\ast \} \\ - S' &=& S \compose \{\SEXNS~\exninst\} \\ - \end{array} - - .. index:: global, global instance, global address, global type, value type, mutability, value .. _alloc-global: @@ -284,28 +258,25 @@ Growing :ref:`tables ` 2. Let :math:`\X{len}` be :math:`n` added to the length of :math:`\tableinst.\TIELEM`. -3. If :math:`\X{len}` is larger than or equal to :math:`2^{32}`, then fail. +3. Let :math:`(\addrtype~\limits~\reftype)` be the structure of :ref:`table type ` :math:`\tableinst.\TITYPE`. -4. Let :math:`\limits~t` be the structure of :ref:`table type ` :math:`\tableinst.\TITYPE`. +4. Let :math:`\limits'` be :math:`\limits` with :math:`\LMIN` updated to :math:`\X{len}`. -5. Let :math:`\limits'` be :math:`\limits` with :math:`\LMIN` updated to :math:`\X{len}`. - -6. If :math:`\limits'` is not :ref:`valid `, then fail. +5. If the :ref:`table type ` :math:`(\addrtype~\limits'~\reftype)` is not :ref:`valid `, then fail. -7. Append :math:`\reff^n` to :math:`\tableinst.\TIELEM`. +6. Append :math:`\reff^n` to :math:`\tableinst.\TIELEM`. -8. Set :math:`\tableinst.\TITYPE` to the :ref:`table type ` :math:`\limits'~t`. +7. Set :math:`\tableinst.\TITYPE` to the :ref:`table type ` :math:`(\addrtype~\limits'~\reftype)`. .. math:: \begin{array}{rllll} - \growtable(\tableinst, n, \reff) &=& \tableinst \with \TITYPE = \limits'~t \with \TIELEM = \tableinst.\TIELEM~\reff^n \\ + \growtable(\tableinst, n, \reff) &=& \tableinst \with \TITYPE = \addrtype~\limits'~\reftype \with \TIELEM = \tableinst.\TIELEM~\reff^n \\ && ( \begin{array}[t]{@{}r@{~}l@{}} \iff & \X{len} = n + |\tableinst.\TIELEM| \\ - \wedge & \X{len} < 2^{32} \\ - \wedge & \limits~t = \tableinst.\TITYPE \\ + \wedge & \addrtype~\limits~\reftype = \tableinst.\TITYPE \\ \wedge & \limits' = \limits \with \LMIN = \X{len} \\ - \wedge & \vdashlimits \limits' \ok) \\ + \wedge & \vdashtabletype \addrtype~\limits'~\reftype \ok) \\ \end{array} \\ \end{array} @@ -322,28 +293,25 @@ Growing :ref:`memories ` 3. Let :math:`\X{len}` be :math:`n` added to the length of :math:`\meminst.\MIDATA` divided by the :ref:`page size ` :math:`64\,\F{Ki}`. -4. If :math:`\X{len}` is larger than :math:`2^{16}`, then fail. +4. Let :math:`(\addrtype~\limits)` be the structure of :ref:`memory type ` :math:`\meminst.\MITYPE`. -5. Let :math:`\limits` be the structure of :ref:`memory type ` :math:`\meminst.\MITYPE`. - -6. Let :math:`\limits'` be :math:`\limits` with :math:`\LMIN` updated to :math:`\X{len}`. +5. Let :math:`\limits'` be :math:`\limits` with :math:`\LMIN` updated to :math:`\X{len}`. -7. If :math:`\limits'` is not :ref:`valid `, then fail. +6. If the :ref:`memory type ` :math:`(\addrtype~\limits')` is not :ref:`valid `, then fail. -8. Append :math:`n` times :math:`64\,\F{Ki}` :ref:`bytes ` with value :math:`\hex{00}` to :math:`\meminst.\MIDATA`. +7. Append :math:`n` times :math:`64\,\F{Ki}` :ref:`bytes ` with value :math:`\hex{00}` to :math:`\meminst.\MIDATA`. -9. Set :math:`\meminst.\MITYPE` to the :ref:`memory type ` :math:`\limits'`. +8. Set :math:`\meminst.\MITYPE` to the :ref:`memory type ` :math:`(\addrtype~\limits')`. .. math:: \begin{array}{rllll} - \growmem(\meminst, n) &=& \meminst \with \MITYPE = \limits' \with \MIDATA = \meminst.\MIDATA~(\hex{00})^{n \cdot 64\,\F{Ki}} \\ + \growmem(\meminst, n) &=& \meminst \with \MITYPE = \addrtype~\limits' \with \MIDATA = \meminst.\MIDATA~(\hex{00})^{n \cdot 64\,\F{Ki}} \\ && ( \begin{array}[t]{@{}r@{~}l@{}} \iff & \X{len} = n + |\meminst.\MIDATA| / 64\,\F{Ki} \\ - \wedge & \X{len} \leq 2^{16} \\ - \wedge & \limits = \meminst.\MITYPE \\ + \wedge & \addrtype~\limits = \meminst.\MITYPE \\ \wedge & \limits' = \limits \with \LMIN = \X{len} \\ - \wedge & \vdashlimits \limits' \ok) \\ + \wedge & \vdashmemtype \addrtype~\limits' \ok) \\ \end{array} \\ \end{array} @@ -447,7 +415,7 @@ and list of :ref:`reference ` vectors for the module's :ref:`element 24. Let :math:`\exportinst^\ast` be the concatenation of the :ref:`export instances ` :math:`\exportinst_i` in index order. -25. Let :math:`\moduleinst` be the :ref:`module instance ` :math:`\{\MITYPES~\deftype^\ast,` :math:`\MIFUNCS~\funcaddr_{\F{mod}}^\ast,` :math:`\MITABLES~\tableaddr_{\F{mod}}^\ast,` :math:`\MIMEMS~\memaddr_{\F{mod}}^\ast,` :math:`\MIGLOBALS~\globaladdr_{\F{mod}}^\ast,` :math:`\MITAGS~\tagaddr_{\F{mod}}^\ast`, :math:`\MIEXPORTS~\exportinst^\ast\}`. +25. Let :math:`\moduleinst` be the :ref:`module instance ` :math:`\{\MITYPES~\deftype^\ast,` :math:`\MIFUNCS~\funcaddr_{\F{mod}}^\ast,` :math:`\MITABLES~\tableaddr_{\F{mod}}^\ast,` :math:`\MIMEMS~\memaddr_{\F{mod}}^\ast,` :math:`\MIGLOBALS~\globaladdr_{\F{mod}}^\ast,` :math:`\MITAGS~\tagaddr_{\F{mod}}^\ast`, :math:`\MIELEMS~\elemaddr^\ast,` :math:`\MIDATAS~\dataaddr^\ast,` :math:`\MIEXPORTS~\exportinst^\ast\}`. 26. Return :math:`\moduleinst`. diff --git a/document/core/exec/runtime.rst b/document/core/exec/runtime.rst index 3f251c2554..a335ad1215 100644 --- a/document/core/exec/runtime.rst +++ b/document/core/exec/runtime.rst @@ -356,18 +356,18 @@ Table Instances ~~~~~~~~~~~~~~~ A *table instance* is the runtime representation of a :ref:`table `. -It records its :ref:`type ` and holds a vector of :ref:`reference values `. +It records its :ref:`type ` and holds a sequence of :ref:`reference values `. .. math:: \begin{array}{llll} \production{table instance} & \tableinst &::=& - \{ \TITYPE~\tabletype, \TIELEM~\vec(\reff) \} \\ + \{ \TITYPE~\tabletype, \TIELEM~\reff^\ast \} \\ \end{array} Table elements can be mutated through :ref:`table instructions `, the execution of an active :ref:`element segment `, or by external means provided by the :ref:`embedder `. It is an invariant of the semantics that all table elements have a type :ref:`matching ` the element type of :math:`\tabletype`. -It also is an invariant that the length of the element vector never exceeds the maximum size of :math:`\tabletype`, if present. +It also is an invariant that the length of the element sequence never exceeds the maximum size of :math:`\tabletype`, if present. .. index:: ! memory instance, memory, byte, ! page size, memory type, embedder, data segment, instruction @@ -380,15 +380,15 @@ Memory Instances ~~~~~~~~~~~~~~~~ A *memory instance* is the runtime representation of a linear :ref:`memory `. -It records its :ref:`type ` and holds a vector of :ref:`bytes `. +It records its :ref:`type ` and holds a sequence of :ref:`bytes `. .. math:: \begin{array}{llll} \production{memory instance} & \meminst &::=& - \{ \MITYPE~\memtype, \MIDATA~\vec(\byte) \} \\ + \{ \MITYPE~\memtype, \MIDATA~\byte^\ast \} \\ \end{array} -The length of the vector always is a multiple of the WebAssembly *page size*, which is defined to be the constant :math:`65536` -- abbreviated :math:`64\,\F{Ki}`. +The length of the sequence always is a multiple of the WebAssembly *page size*, which is defined to be the constant :math:`65536` -- abbreviated :math:`64\,\F{Ki}`. The bytes can be mutated through :ref:`memory instructions `, the execution of an active :ref:`data segment `, or by external means provided by the :ref:`embedder `. diff --git a/document/core/index.rst b/document/core/index.rst index 0179df7be6..7f39215f22 100644 --- a/document/core/index.rst +++ b/document/core/index.rst @@ -3,7 +3,7 @@ WebAssembly Specification .. only:: html - | Release |release| + | Release |release| (Draft, |today|) | Editor: Andreas Rossberg diff --git a/document/core/static/custom.css b/document/core/static/custom.css index 950236af0f..bd17eb028d 100644 --- a/document/core/static/custom.css +++ b/document/core/static/custom.css @@ -82,3 +82,9 @@ div.sphinxsidebar a { div.sphinxsidebar a:hover { border-bottom: 1px dotted; } + +@media screen and (max-width: 875px) { + div.bodywrapper { + margin: 0; + } +} diff --git a/document/core/syntax/instructions.rst b/document/core/syntax/instructions.rst index 31c80d64e7..615c1c6b99 100644 --- a/document/core/syntax/instructions.rst +++ b/document/core/syntax/instructions.rst @@ -674,7 +674,7 @@ Instructions in this group are concerned with linear :ref:`memory `. .. math:: \begin{array}{llrl} \production{memory immediate} & \memarg &::=& - \{ \OFFSET~\u32, \ALIGN~\u32 \} \\ + \{ \OFFSET~\u64, \ALIGN~\u32 \} \\ \production{lane width} & \X{ww} &::=& 8 ~|~ 16 ~|~ 32 ~|~ 64 \\ \production{instruction} & \instr &::=& @@ -707,7 +707,7 @@ Instructions in this group are concerned with linear :ref:`memory `. \DATADROP~\dataidx \\ \end{array} -Memory is accessed with |LOAD| and |STORE| instructions for the different :ref:`number types ` and `vector types `. +Memory is accessed with |LOAD| and |STORE| instructions for the different :ref:`number types ` and :ref:`vector types `. They all take a :ref:`memory index ` and a *memory immediate* |memarg| that contains an address *offset* and the expected *alignment* (expressed as the exponent of a power of 2). Integer loads and stores can optionally specify a *storage size* that is smaller than the :ref:`bit width ` of the respective value type. @@ -716,13 +716,10 @@ In the case of loads, a sign extension mode |sx| is then required to select appr Vector loads can specify a shape that is half the :ref:`bit width ` of |V128|. Each lane is half its usual size, and the sign extension mode |sx| then specifies how the smaller lane is extended to the larger lane. Alternatively, vector loads can perform a *splat*, such that only a single lane of the specified storage size is loaded, and the result is duplicated to all lanes. -The static address offset is added to the dynamic address operand, yielding a 33 bit *effective address* that is the zero-based index at which the memory is accessed. +The static address offset is added to the dynamic address operand, yielding a 33-bit or 65-bit *effective address* that is the zero-based index at which the memory is accessed. All values are read and written in |LittleEndian|_ byte order. A :ref:`trap ` results if any of the accessed memory bytes lies outside the address range implied by the memory's current size. -.. note:: - Future versions of WebAssembly might provide memory instructions with 64 bit address ranges. - The |MEMORYSIZE| instruction returns the current size of a memory. The |MEMORYGROW| instruction grows a memory by a given delta and returns the previous size, or :math:`-1` if enough memory cannot be allocated. Both instructions operate in units of :ref:`page size `. diff --git a/document/core/syntax/types.rst b/document/core/syntax/types.rst index 883dfa330d..450db2bae6 100644 --- a/document/core/syntax/types.rst +++ b/document/core/syntax/types.rst @@ -357,6 +357,38 @@ In a :ref:`module `, each member of a recursive type is assigned The syntax of sub types is :ref:`generalized ` for the purpose of specifying :ref:`validation ` and :ref:`execution `. +.. _index:: ! address type + pair: abstract syntax; address type + single: memory; address type + single: table; address type +.. _syntax-addrtype: + +Address Type +~~~~~~~~~~~~ + +*Address types* are a subset of :ref:`number types ` that classify the values that can be used as offsets into +:ref:`memories ` and :ref:`tables `. + +.. math:: + \begin{array}{llll} + \production{address type} & \addrtype &::=& + \I32 ~|~ \I64 \\ + \end{array} + +.. _aux-addrtype-min: + +Conventions +........... + +The *minimum* of two address types is defined as the address type whose :ref:`bit width ` is the minimum of the two. + +.. math:: + \begin{array}{llll} + \addrtypemin(\X{at}_1, \X{at}_2) &=& \X{at}_1 & (\iff |\X{at}_1| \leq |\X{at}_2|) \\ + \addrtypemin(\X{at}_1, \X{at}_2) &=& \X{at}_2 & (\otherwise) \\ + \end{array} + + .. index:: ! limits, memory type, table type pair: abstract syntax; limits single: memory; limits @@ -371,7 +403,7 @@ Limits .. math:: \begin{array}{llrl} \production{limits} & \limits &::=& - \{ \LMIN~\u32, \LMAX~\u32^? \} \\ + \{ \LMIN~\u64, \LMAX~\u64^? \} \\ \end{array} If no maximum is given, the respective storage can grow to any size. @@ -391,7 +423,7 @@ Memory Types .. math:: \begin{array}{llrl} \production{memory type} & \memtype &::=& - \limits \\ + \addrtype~\limits \\ \end{array} The limits constrain the minimum and optionally the maximum size of a memory. @@ -412,7 +444,7 @@ Table Types .. math:: \begin{array}{llrl} \production{table type} & \tabletype &::=& - \limits~\reftype \\ + \addrtype~\limits~\reftype \\ \end{array} Like memories, tables are constrained by limits for their minimum and optionally maximum size. diff --git a/document/core/text/modules.rst b/document/core/text/modules.rst index 34e4e924f4..0ce3583bd2 100644 --- a/document/core/text/modules.rst +++ b/document/core/text/modules.rst @@ -307,21 +307,23 @@ An :ref:`element segment ` can be given inline with a table definitio .. math:: \begin{array}{llclll} \production{module field} & - \text{(}~\text{table}~~\Tid^?~~\Treftype~~\text{(}~\text{elem}~~\expr^n{:}\Tvec(\Telemexpr)~\text{)}~\text{)} \quad\equiv \\ & \qquad - \text{(}~\text{table}~~\Tid'~~n~~n~~\Treftype~\text{)} \\ & \qquad - \text{(}~\text{elem}~~\text{(}~\text{table}~~\Tid'~\text{)}~~\text{(}~\text{i32.const}~~\text{0}~\text{)}~~\Treftype~~\Tvec(\Telemexpr)~\text{)} + \text{(}~\text{table}~~\Tid^?~~\Taddrtype^?~~\Treftype~~\text{(}~\text{elem}~~\expr^n{:}\Tvec(\Telemexpr)~\text{)}~\text{)} \quad\equiv \\ & \qquad + \text{(}~\text{table}~~\Tid'~~\Taddrtype^?~~n~~n~~\Treftype~\text{)} \\ & \qquad + \text{(}~\text{elem}~~\text{(}~\text{table}~~\Tid'~\text{)}~~\text{(}~\Taddrtype'\text{.const}~~\text{0}~\text{)}~~\Treftype~~\Tvec(\Telemexpr)~\text{)} \\ & \qquad\qquad - (\iff \Tid^? \neq \epsilon \wedge \Tid' = \Tid^? \vee \Tid^? = \epsilon \wedge \Tid' \idfresh) \\ + (\iff \Tid^? \neq \epsilon \wedge \Tid' = \Tid^? \vee \Tid^? = \epsilon \wedge \Tid' \idfresh, \\ & \qquad\qquad + \iff \Taddrtype? \neq \epsilon \wedge \Taddrtype' = \Taddrtype^? \vee \Taddrtype^? = \epsilon \wedge \Taddrtype' = \text{i32}) \\ \end{array} .. math:: \begin{array}{llclll} \production{module field} & - \text{(}~\text{table}~~\Tid^?~~\Treftype~~\text{(}~\text{elem}~~x^n{:}\Tvec(\Tfuncidx)~\text{)}~\text{)} \quad\equiv \\ & \qquad - \text{(}~\text{table}~~\Tid'~~n~~n~~\Treftype~\text{)} \\ & \qquad - \text{(}~\text{elem}~~\text{(}~\text{table}~~\Tid'~\text{)}~~\text{(}~\text{i32.const}~~\text{0}~\text{)}~~\Treftype~~\Tvec(\text{(}~\text{ref.func}~~\Tfuncidx~\text{)})~\text{)} + \text{(}~\text{table}~~\Tid^?~~\Taddrtype^?~~\Treftype~~\text{(}~\text{elem}~~x^n{:}\Tvec(\Tfuncidx)~\text{)}~\text{)} \quad\equiv \\ & \qquad + \text{(}~\text{table}~~\Tid'~~\Taddrtype^?~~n~~n~~\Treftype~\text{)} \\ & \qquad + \text{(}~\text{elem}~~\text{(}~\text{table}~~\Tid'~\text{)}~~\text{(}~\Taddrtype'\text{.const}~~\text{0}~\text{)}~~\Treftype~~\Tvec(\text{(}~\text{ref.func}~~\Tfuncidx~\text{)})~\text{)} \\ & \qquad\qquad - (\iff \Tid^? \neq \epsilon \wedge \Tid' = \Tid^? \vee \Tid^? = \epsilon \wedge \Tid' \idfresh) \\ + (\iff \Tid^? \neq \epsilon \wedge \Tid' = \Tid^? \vee \Tid^? = \epsilon \wedge \Tid' \idfresh, \\ & \qquad\qquad + \iff \Taddrtype? \neq \epsilon \wedge \Taddrtype' = \Taddrtype^? \vee \Taddrtype^? = \epsilon \wedge \Taddrtype' = \text{i32}) \\ \end{array} Tables can be defined as :ref:`imports ` or :ref:`exports ` inline: @@ -378,11 +380,13 @@ A :ref:`data segment ` can be given inline with a memory definition, .. math:: \begin{array}{llclll} \production{module field} & - \text{(}~\text{memory}~~\Tid^?~~\text{(}~\text{data}~~b^n{:}\Tdatastring~\text{)}~~\text{)} \quad\equiv \\ & \qquad - \text{(}~\text{memory}~~\Tid'~~m~~m~\text{)} \\ & \qquad - \text{(}~\text{data}~~\text{(}~\text{memory}~~\Tid'~\text{)}~~\text{(}~\text{i32.const}~~\text{0}~\text{)}~~\Tdatastring~\text{)} + \text{(}~\text{memory}~~\Tid^?~~\Taddrtype^?~~\text{(}~\text{data}~~b^n{:}\Tdatastring~\text{)}~~\text{)} \quad\equiv \\ & \qquad + \text{(}~\text{memory}~~\Tid'~~\Taddrtype^?~~m~~m~\text{)} \\ & \qquad + \text{(}~\text{data}~~\text{(}~\text{memory}~~\Tid'~\text{)}~~\text{(}~\Taddrtype'\text{.const}~~\text{0}~\text{)}~~\Tdatastring~\text{)} \\ & \qquad\qquad - (\iff \Tid^? \neq \epsilon \wedge \Tid' = \Tid^? \vee \Tid^? = \epsilon \wedge \Tid' \idfresh, m = \F{ceil}(n / 64\,\F{Ki})) \\ + (\iff \Tid^? \neq \epsilon \wedge \Tid' = \Tid^? \vee \Tid^? = \epsilon \wedge \Tid' \idfresh, \\ & \qquad\qquad + \iff \Taddrtype? \neq \epsilon \wedge \Taddrtype' = \Taddrtype^? \vee \Taddrtype^? = \epsilon \wedge \Taddrtype' = \text{i32}, \\ & \qquad\qquad + m = \F{ceil}(n / 64\,\F{Ki})) \\ \end{array} Memories can be defined as :ref:`imports ` or :ref:`exports ` inline: diff --git a/document/core/text/types.rst b/document/core/text/types.rst index 8618f3608c..5c7e7386b8 100644 --- a/document/core/text/types.rst +++ b/document/core/text/types.rst @@ -286,6 +286,32 @@ Similarly, final sub types with no super-types can omit the |Tsub| keyword and a \end{array} +.. index:: address type + pair: text format; address type +.. _text-addrtype: + +Address Types +~~~~~~~~~~~~~ + +.. math:: + \begin{array}{llclll} + \production{address type} & \Taddrtype &::=& + \text{i32} &\Rightarrow& \I32 \\ &&|& + \text{i64} &\Rightarrow& \I64 \\ + \end{array} + +Abbreviations +............. + +The address type can be omited, in which case it defaults :math:`\I32`: + +.. math:: + \begin{array}{llclll} + \production{address type} & + \text{} &\equiv& \text{i32} + \end{array} + + .. index:: limits pair: text format; limits .. _text-limits: @@ -311,7 +337,7 @@ Memory Types .. math:: \begin{array}{llclll@{\qquad\qquad}l} \production{memory type} & \Tmemtype_I &::=& - \X{lim}{:}\Tlimits &\Rightarrow& \X{lim} \\ + \X{at}{:}\Taddrtype~~\X{lim}{:}\Tlimits &\Rightarrow& \X{at}~\X{lim} \\ \end{array} @@ -325,7 +351,7 @@ Table Types .. math:: \begin{array}{llclll} \production{table type} & \Ttabletype_I &::=& - \X{lim}{:}\Tlimits~~\X{et}{:}\Treftype_I &\Rightarrow& \X{lim}~\X{et} \\ + \X{at}{:}\Taddrtype~~\X{lim}{:}\Tlimits~~\X{et}{:}\Treftype_I &\Rightarrow& \X{at}~\X{lim}~\X{et} \\ \end{array} diff --git a/document/core/util/bikeshed_fixup.py b/document/core/util/bikeshed_fixup.py index 01dac14aa1..af9a029d42 100755 --- a/document/core/util/bikeshed_fixup.py +++ b/document/core/util/bikeshed_fixup.py @@ -30,6 +30,7 @@ def Main(): 'Validation Algorithm', 'Custom Sections', 'Soundness', + 'Type System Properties', 'Change History', 'Index of Types', 'Index of Instructions', diff --git a/document/core/util/macros.def b/document/core/util/macros.def index 82d731fbf7..92f4e5490d 100644 --- a/document/core/util/macros.def +++ b/document/core/util/macros.def @@ -286,6 +286,7 @@ .. |globaltype| mathdef:: \xref{syntax/types}{syntax-globaltype}{\X{globaltype}} .. |tabletype| mathdef:: \xref{syntax/types}{syntax-tabletype}{\X{tabletype}} +.. |addrtype| mathdef:: \xref{syntax/types}{syntax-addrtype}{\X{addrtype}} .. |memtype| mathdef:: \xref{syntax/types}{syntax-memtype}{\X{memtype}} .. |tagtype| mathdef:: \xref{syntax/types}{syntax-tagtype}{\X{tagtype}} @@ -300,6 +301,7 @@ .. Types, meta functions +.. |addrtypemin| mathdef:: \xref{syntax/types}{aux-addrtype-min}{\F{min}} .. |reftypediff| mathdef:: \xref{valid/conventions}{aux-reftypediff}{\setminus} .. |rollrt| mathdef:: \xref{valid/conventions}{aux-roll-rectype}{\F{roll}} @@ -970,6 +972,7 @@ .. |Tglobaltype| mathdef:: \xref{text/types}{text-globaltype}{\T{globaltype}} .. |Ttabletype| mathdef:: \xref{text/types}{text-tabletype}{\T{tabletype}} +.. |Taddrtype| mathdef:: \xref{text/types}{text-addrtype}{\T{addrtype}} .. |Tmemtype| mathdef:: \xref{text/types}{text-memtype}{\T{memtype}} .. |Tlimits| mathdef:: \xref{text/types}{text-limits}{\T{limits}} @@ -1226,8 +1229,6 @@ .. |allocdata| mathdef:: \xref{exec/modules}{alloc-data}{\F{allocdata}} .. |allocmodule| mathdef:: \xref{exec/modules}{alloc-module}{\F{allocmodule}} -.. |allocexn| mathdef:: \xref{exec/modules}{alloc-exception}{\F{allocexn}} - .. |growtable| mathdef:: \xref{exec/modules}{grow-table}{\F{growtable}} .. |growmem| mathdef:: \xref{exec/modules}{grow-mem}{\F{growmem}} diff --git a/document/core/valid/instructions.rst b/document/core/valid/instructions.rst index 40d1bfeec3..8eeaeb094c 100644 --- a/document/core/valid/instructions.rst +++ b/document/core/valid/instructions.rst @@ -1395,15 +1395,15 @@ Table Instructions * The table :math:`C.\CTABLES[x]` must be defined in the context. -* Let :math:`\limits~t` be the :ref:`table type ` :math:`C.\CTABLES[x]`. +* Let :math:`\X{at}~\limits~t` be the :ref:`table type ` :math:`C.\CTABLES[x]`. -* Then the instruction is valid with type :math:`[\I32] \to [t]`. +* Then the instruction is valid with type :math:`[\X{at}] \to [t]`. .. math:: \frac{ - C.\CTABLES[x] = \limits~t + C.\CTABLES[x] = \X{at}~\limits~t }{ - C \vdashinstr \TABLEGET~x : [\I32] \to [t] + C \vdashinstr \TABLEGET~x : [\X{at}] \to [t] } @@ -1414,15 +1414,15 @@ Table Instructions * The table :math:`C.\CTABLES[x]` must be defined in the context. -* Let :math:`\limits~t` be the :ref:`table type ` :math:`C.\CTABLES[x]`. +* Let :math:`\X{at}~\limits~t` be the :ref:`table type ` :math:`C.\CTABLES[x]`. -* Then the instruction is valid with type :math:`[\I32~t] \to []`. +* Then the instruction is valid with type :math:`[\X{at}~t] \to []`. .. math:: \frac{ - C.\CTABLES[x] = \limits~t + C.\CTABLES[x] = \X{at}~\limits~t }{ - C \vdashinstr \TABLESET~x : [\I32~t] \to [] + C \vdashinstr \TABLESET~x : [\X{at}~t] \to [] } @@ -1433,13 +1433,15 @@ Table Instructions * The table :math:`C.\CTABLES[x]` must be defined in the context. -* Then the instruction is valid with type :math:`[] \to [\I32]`. +* Let :math:`\X{at}~\limits~t` be the :ref:`table type ` :math:`C.\CTABLES[x]`. + +* Then the instruction is valid with type :math:`[] \to [\X{at}]`. .. math:: \frac{ - C.\CTABLES[x] = \tabletype + C.\CTABLES[x] = \X{at}~\limits~t }{ - C \vdashinstr \TABLESIZE~x : [] \to [\I32] + C \vdashinstr \TABLESIZE~x : [] \to [\X{at}] } @@ -1450,15 +1452,15 @@ Table Instructions * The table :math:`C.\CTABLES[x]` must be defined in the context. -* Let :math:`\limits~t` be the :ref:`table type ` :math:`C.\CTABLES[x]`. +* Let :math:`\X{at}~\limits~t` be the :ref:`table type ` :math:`C.\CTABLES[x]`. -* Then the instruction is valid with type :math:`[t~\I32] \to [\I32]`. +* Then the instruction is valid with type :math:`[t~\X{at}] \to [\X{at}]`. .. math:: \frac{ - C.\CTABLES[x] = \limits~t + C.\CTABLES[x] = \X{at}~\limits~t }{ - C \vdashinstr \TABLEGROW~x : [t~\I32] \to [\I32] + C \vdashinstr \TABLEGROW~x : [t~\X{at}] \to [\X{at}] } @@ -1469,15 +1471,15 @@ Table Instructions * The table :math:`C.\CTABLES[x]` must be defined in the context. -* Let :math:`\limits~t` be the :ref:`table type ` :math:`C.\CTABLES[x]`. +* Let :math:`\X{at}~\limits~t` be the :ref:`table type ` :math:`C.\CTABLES[x]`. -* Then the instruction is valid with type :math:`[\I32~t~\I32] \to []`. +* Then the instruction is valid with type :math:`[\X{at}~t~\X{at}] \to []`. .. math:: \frac{ - C.\CTABLES[x] = \limits~t + C.\CTABLES[x] = \X{at}~\limits~t }{ - C \vdashinstr \TABLEFILL~x : [\I32~t~\I32] \to [] + C \vdashinstr \TABLEFILL~x : [\X{at}~t~\X{at}] \to [] } @@ -1488,25 +1490,27 @@ Table Instructions * The table :math:`C.\CTABLES[x]` must be defined in the context. -* Let :math:`\limits_1~t_1` be the :ref:`table type ` :math:`C.\CTABLES[x]`. +* Let :math:`\X{at}_1~\limits_1~t_1` be the :ref:`table type ` :math:`C.\CTABLES[x]`. * The table :math:`C.\CTABLES[y]` must be defined in the context. -* Let :math:`\limits_2~t_2` be the :ref:`table type ` :math:`C.\CTABLES[y]`. +* Let :math:`\X{at}_2~\limits_2~t_2` be the :ref:`table type ` :math:`C.\CTABLES[y]`. * The :ref:`reference type ` :math:`t_2` must :ref:`match ` :math:`t_1`. -* Then the instruction is valid with type :math:`[\I32~\I32~\I32] \to []`. +* Let :math:`\X{at}` be the :ref:`minimum ` of :math:`\X{at}_1` and :math:`\X{at}_2` + +* Then the instruction is valid with type :math:`[\X{at}_1~\X{at}_2~\X{at}] \to []`. .. math:: \frac{ - C.\CTABLES[x] = \limits_1~t_1 + C.\CTABLES[x] = \X{at}~\limits_1~t_1 \qquad - C.\CTABLES[y] = \limits_2~t_2 + C.\CTABLES[y] = \X{at}~\limits_2~t_2 \qquad C \vdashreftypematch t_2 \matchesvaltype t_1 }{ - C \vdashinstr \TABLECOPY~x~y : [\I32~\I32~\I32] \to [] + C \vdashinstr \TABLECOPY~x~y : [\X{at}_1~\X{at}_2~\addrtypemin(\X{at}_1, \X{at}_2)] \to [] } @@ -1517,7 +1521,7 @@ Table Instructions * The table :math:`C.\CTABLES[x]` must be defined in the context. -* Let :math:`\limits~t_1` be the :ref:`table type ` :math:`C.\CTABLES[x]`. +* Let :math:`\X{at}~\limits~t_1` be the :ref:`table type ` :math:`C.\CTABLES[x]`. * The element segment :math:`C.\CELEMS[y]` must be defined in the context. @@ -1525,17 +1529,17 @@ Table Instructions * The :ref:`reference type ` :math:`t_2` must :ref:`match ` :math:`t_1`. -* Then the instruction is valid with type :math:`[\I32~\I32~\I32] \to []`. +* Then the instruction is valid with type :math:`[\X{at}~\I32~\I32] \to []`. .. math:: \frac{ - C.\CTABLES[x] = \limits~t_1 + C.\CTABLES[x] = \X{at}~\limits~t_1 \qquad C.\CELEMS[y] = t_2 \qquad C \vdashreftypematch t_2 \matchesvaltype t_1 }{ - C \vdashinstr \TABLEINIT~x~y : [\I32~\I32~\I32] \to [] + C \vdashinstr \TABLEINIT~x~y : [\X{at}~\I32~\I32] \to [] } @@ -1572,17 +1576,23 @@ Memory Instructions * The memory :math:`C.\CMEMS[x]` must be defined in the context. +* Let :math:`\X{at}~\limits` be the :ref:`memory type ` :math:`C.\CMEMS[x]`. + +* The offset :math:`\memarg.\OFFSET` must be less than :math:`2^{|\X{at}|}`. + * The alignment :math:`2^{\memarg.\ALIGN}` must not be larger than the :ref:`bit width ` of :math:`t` divided by :math:`8`. -* Then the instruction is valid with type :math:`[\I32] \to [t]`. +* Then the instruction is valid with type :math:`[\X{at}] \to [t]`. .. math:: \frac{ - C.\CMEMS[x] = \memtype + C.\CMEMS[x] = \X{at}~\limits + \qquad + \memarg.\OFFSET < 2^{|\X{at}|} \qquad 2^{\memarg.\ALIGN} \leq |t|/8 }{ - C \vdashinstr t\K{.load}~x~\memarg : [\I32] \to [t] + C \vdashinstr t\K{.load}~x~\memarg : [\X{at}] \to [t] } @@ -1593,17 +1603,23 @@ Memory Instructions * The memory :math:`C.\CMEMS[x]` must be defined in the context. +* Let :math:`\X{at}~\limits` be the :ref:`memory type ` :math:`C.\CMEMS[x]`. + +* The offset :math:`\memarg.\OFFSET` must be less than :math:`2^{|\X{at}|}`. + * The alignment :math:`2^{\memarg.\ALIGN}` must not be larger than :math:`N/8`. -* Then the instruction is valid with type :math:`[\I32] \to [t]`. +* Then the instruction is valid with type :math:`[\X{at}] \to [t]`. .. math:: \frac{ - C.\CMEMS[x] = \memtype + C.\CMEMS[x] = \X{at}~\limits + \qquad + \memarg.\OFFSET < 2^{|\X{at}|} \qquad 2^{\memarg.\ALIGN} \leq N/8 }{ - C \vdashinstr t\K{.load}N\K{\_}\sx~x~\memarg : [\I32] \to [t] + C \vdashinstr t\K{.load}N\K{\_}\sx~x~\memarg : [\X{at}] \to [t] } @@ -1612,17 +1628,23 @@ Memory Instructions * The memory :math:`C.\CMEMS[x]` must be defined in the context. +* Let :math:`\X{at}~\limits` be the :ref:`memory type ` :math:`C.\CMEMS[x]`. + +* The offset :math:`\memarg.\OFFSET` must be less than :math:`2^{|\X{at}|}`. + * The alignment :math:`2^{\memarg.\ALIGN}` must not be larger than the :ref:`bit width ` of :math:`t` divided by :math:`8`. -* Then the instruction is valid with type :math:`[\I32~t] \to []`. +* Then the instruction is valid with type :math:`[\X{at}~t] \to []`. .. math:: \frac{ - C.\CMEMS[x] = \memtype + C.\CMEMS[x] = \X{at}~\limits + \qquad + \memarg.\OFFSET < 2^{|\X{at}|} \qquad 2^{\memarg.\ALIGN} \leq |t|/8 }{ - C \vdashinstr t\K{.store}~x~\memarg : [\I32~t] \to [] + C \vdashinstr t\K{.store}~x~\memarg : [\X{at}~t] \to [] } @@ -1633,17 +1655,23 @@ Memory Instructions * The memory :math:`C.\CMEMS[x]` must be defined in the context. +* Let :math:`\X{at}~\limits` be the :ref:`memory type ` :math:`C.\CMEMS[x]`. + +* The offset :math:`\memarg.\OFFSET` must be less than :math:`2^{|\X{at}|}`. + * The alignment :math:`2^{\memarg.\ALIGN}` must not be larger than :math:`N/8`. -* Then the instruction is valid with type :math:`[\I32~t] \to []`. +* Then the instruction is valid with type :math:`[\X{at}~t] \to []`. .. math:: \frac{ - C.\CMEMS[x] = \memtype + C.\CMEMS[x] = \X{at}~\limits + \qquad + \memarg.\OFFSET < 2^{|\X{at}|} \qquad 2^{\memarg.\ALIGN} \leq N/8 }{ - C \vdashinstr t\K{.store}N~x~\memarg : [\I32~t] \to [] + C \vdashinstr t\K{.store}N~x~\memarg : [\X{at}~t] \to [] } @@ -1654,17 +1682,23 @@ Memory Instructions * The memory :math:`C.\CMEMS[x]` must be defined in the context. +* Let :math:`\X{at}~\limits` be the :ref:`memory type ` :math:`C.\CMEMS[x]`. + +* The offset :math:`\memarg.\OFFSET` must be less than :math:`2^{|\X{at}|}`. + * The alignment :math:`2^{\memarg.\ALIGN}` must not be larger than :math:`N/8 \cdot M`. -* Then the instruction is valid with type :math:`[\I32] \to [\V128]`. +* Then the instruction is valid with type :math:`[\X{at}] \to [\V128]`. .. math:: \frac{ - C.\CMEMS[x] = \memtype + C.\CMEMS[x] = \X{at}~\limits + \qquad + \memarg.\OFFSET < 2^{|\X{at}|} \qquad 2^{\memarg.\ALIGN} \leq N/8 \cdot M }{ - C \vdashinstr \K{v128.}\LOAD{N}\K{x}M\_\sx~x~\memarg : [\I32] \to [\V128] + C \vdashinstr \K{v128.}\LOAD{N}\K{x}M\_\sx~x~\memarg : [\X{at}] \to [\V128] } @@ -1675,17 +1709,23 @@ Memory Instructions * The memory :math:`C.\CMEMS[x]` must be defined in the context. +* Let :math:`\X{at}~\limits` be the :ref:`memory type ` :math:`C.\CMEMS[x]`. + +* The offset :math:`\memarg.\OFFSET` must be less than :math:`2^{|\X{at}|}`. + * The alignment :math:`2^{\memarg.\ALIGN}` must not be larger than :math:`N/8`. -* Then the instruction is valid with type :math:`[\I32] \to [\V128]`. +* Then the instruction is valid with type :math:`[\X{at}] \to [\V128]`. .. math:: \frac{ - C.\CMEMS[x] = \memtype + C.\CMEMS[x] = \X{at}~\limits + \qquad + \memarg.\OFFSET < 2^{|\X{at}|} \qquad 2^{\memarg.\ALIGN} \leq N/8 }{ - C \vdashinstr \K{v128.}\LOAD{N}\K{\_splat}~x~\memarg : [\I32] \to [\V128] + C \vdashinstr \K{v128.}\LOAD{N}\K{\_splat}~x~\memarg : [\X{at}] \to [\V128] } @@ -1696,17 +1736,23 @@ Memory Instructions * The memory :math:`C.\CMEMS[x]` must be defined in the context. +* Let :math:`\X{at}~\limits` be the :ref:`memory type ` :math:`C.\CMEMS[x]`. + +* The offset :math:`\memarg.\OFFSET` must be less than :math:`2^{|\X{at}|}`. + * The alignment :math:`2^{\memarg.\ALIGN}` must not be larger than :math:`N/8`. -* Then the instruction is valid with type :math:`[\I32] \to [\V128]`. +* Then the instruction is valid with type :math:`[\X{at}] \to [\V128]`. .. math:: \frac{ - C.\CMEMS[x] = \memtype + C.\CMEMS[x] = \X{at}~\limits + \qquad + \memarg.\OFFSET < 2^{|\X{at}|} \qquad 2^{\memarg.\ALIGN} \leq N/8 }{ - C \vdashinstr \K{v128.}\LOAD{N}\K{\_zero}~x~\memarg : [\I32] \to [\V128] + C \vdashinstr \K{v128.}\LOAD{N}\K{\_zero}~x~\memarg : [\X{at}] \to [\V128] } @@ -1717,21 +1763,27 @@ Memory Instructions * The memory :math:`C.\CMEMS[x]` must be defined in the context. +* Let :math:`\X{at}~\limits` be the :ref:`memory type ` :math:`C.\CMEMS[x]`. + +* The offset :math:`\memarg.\OFFSET` must be less than :math:`2^{|\X{at}|}`. + * The alignment :math:`2^{\memarg.\ALIGN}` must not be larger than :math:`N/8`. * The lane index :math:`\laneidx` must be smaller than :math:`128/N`. -* Then the instruction is valid with type :math:`[\I32~\V128] \to [\V128]`. +* Then the instruction is valid with type :math:`[\X{at}~\V128] \to [\V128]`. .. math:: \frac{ - C.\CMEMS[x] = \memtype + C.\CMEMS[x] = \X{at}~\limits + \qquad + \memarg.\OFFSET < 2^{|\X{at}|} \qquad 2^{\memarg.\ALIGN} \leq N/8 \qquad \laneidx < 128/N }{ - C \vdashinstr \K{v128.}\LOAD{N}\K{\_lane}~x~\memarg~\laneidx : [\I32~\V128] \to [\V128] + C \vdashinstr \K{v128.}\LOAD{N}\K{\_lane}~x~\memarg~\laneidx : [\X{at}~\V128] \to [\V128] } @@ -1742,21 +1794,27 @@ Memory Instructions * The memory :math:`C.\CMEMS[x]` must be defined in the context. +* Let :math:`\X{at}~\limits` be the :ref:`memory type ` :math:`C.\CMEMS[x]`. + +* The offset :math:`\memarg.\OFFSET` must be less than :math:`2^{|\X{at}|}`. + * The alignment :math:`2^{\memarg.\ALIGN}` must not be larger than :math:`N/8`. * The lane index :math:`\laneidx` must be smaller than :math:`128/N`. -* Then the instruction is valid with type :math:`[\I32~\V128] \to [\V128]`. +* Then the instruction is valid with type :math:`[\X{at}~\V128] \to [\V128]`. .. math:: \frac{ - C.\CMEMS[x] = \memtype + C.\CMEMS[x] = \X{at}~\limits + \qquad + \memarg.\OFFSET < 2^{|\X{at}|} \qquad 2^{\memarg.\ALIGN} \leq N/8 \qquad \laneidx < 128/N }{ - C \vdashinstr \K{v128.}\STORE{N}\K{\_lane}~x~\memarg~\laneidx : [\I32~\V128] \to [] + C \vdashinstr \K{v128.}\STORE{N}\K{\_lane}~x~\memarg~\laneidx : [\X{at}~\V128] \to [] } @@ -1767,13 +1825,15 @@ Memory Instructions * The memory :math:`C.\CMEMS[x]` must be defined in the context. -* Then the instruction is valid with type :math:`[] \to [\I32]`. +* Let :math:`\X{at}~\limits` be the :ref:`memory type ` :math:`C.\CMEMS[x]`. + +* Then the instruction is valid with type :math:`[] \to [\X{at}]`. .. math:: \frac{ - C.\CMEMS[x] = \memtype + C.\CMEMS[x] = \X{at}~\limits }{ - C \vdashinstr \MEMORYSIZE~x : [] \to [\I32] + C \vdashinstr \MEMORYSIZE~x : [] \to [\X{at}] } @@ -1784,13 +1844,15 @@ Memory Instructions * The memory :math:`C.\CMEMS[x]` must be defined in the context. -* Then the instruction is valid with type :math:`[\I32] \to [\I32]`. +* Let :math:`\X{at}~\limits` be the :ref:`memory type ` :math:`C.\CMEMS[x]`. + +* Then the instruction is valid with type :math:`[\X{at}] \to [\X{at}]`. .. math:: \frac{ - C.\CMEMS[x] = \memtype + C.\CMEMS[x] = \X{at}~\limits }{ - C \vdashinstr \MEMORYGROW~x : [\I32] \to [\I32] + C \vdashinstr \MEMORYGROW~x : [\X{at}] \to [\X{at}] } @@ -1801,13 +1863,15 @@ Memory Instructions * The memory :math:`C.\CMEMS[x]` must be defined in the context. -* Then the instruction is valid with type :math:`[\I32~\I32~\I32] \to []`. +* Let :math:`\X{at}~\limits` be the :ref:`memory type ` :math:`C.\CMEMS[x]`. + +* Then the instruction is valid with type :math:`[\X{at}~\I32~\X{at}] \to []`. .. math:: \frac{ - C.\CMEMS[x] = \memtype + C.\CMEMS[x] = \X{at}~\limits }{ - C \vdashinstr \MEMORYFILL~x : [\I32~\I32~\I32] \to [] + C \vdashinstr \MEMORYFILL~x : [\X{at}~\I32~\X{at}] \to [] } @@ -1820,15 +1884,21 @@ Memory Instructions * The memory :math:`C.\CMEMS[y]` must be defined in the context. -* Then the instruction is valid with type :math:`[\I32~\I32~\I32] \to []`. +* Let :math:`\X{at}_x~\limits_x` be the :ref:`memory type ` :math:`C.\CMEMS[x]`. + +* Let :math:`\X{at}_y~\limits_y` be the :ref:`memory type ` :math:`C.\CMEMS[y]`. + +* Let :math:`\X{at}` be the :ref:`minimum ` of :math:`\X{at}_x` and :math:`\X{at}_y` + +* Then the instruction is valid with type :math:`[\X{at}_x~\X{at}_y~\X{at}] \to []`. .. math:: \frac{ - C.\CMEMS[x] = \memtype + C.\CMEMS[x] = \X{at}_x~\limits_y \qquad - C.\CMEMS[x] = \memtype + C.\CMEMS[y] = \X{at}_y~\limits_y }{ - C \vdashinstr \MEMORYCOPY~x~y : [\I32~\I32~\I32] \to [] + C \vdashinstr \MEMORYCOPY~x~y : [\X{at}_x~\X{at}_y~\addrtypemin(\X{at}_x, \X{at}_y)] \to [] } @@ -1839,17 +1909,19 @@ Memory Instructions * The memory :math:`C.\CMEMS[x]` must be defined in the context. +* Let :math:`\X{at}~\limits` be the :ref:`memory type ` :math:`C.\CMEMS[x]`. + * The data segment :math:`C.\CDATAS[y]` must be defined in the context. -* Then the instruction is valid with type :math:`[\I32~\I32~\I32] \to []`. +* Then the instruction is valid with type :math:`[\X{at}~\I32~\I32] \to []`. .. math:: \frac{ - C.\CMEMS[x] = \memtype + C.\CMEMS[x] = \X{at}~\limits \qquad C.\CDATAS[y] = {\ok} }{ - C \vdashinstr \MEMORYINIT~x~y : [\I32~\I32~\I32] \to [] + C \vdashinstr \MEMORYINIT~x~y : [\X{at}~\I32~\I32] \to [] } @@ -2402,7 +2474,7 @@ Control Instructions * The table :math:`C.\CTABLES[x]` must be defined in the context. -* Let :math:`\limits~t` be the :ref:`table type ` :math:`C.\CTABLES[x]`. +* Let :math:`\X{at}~\limits~t` be the :ref:`table type ` :math:`C.\CTABLES[x]`. * The :ref:`reference type ` :math:`t` must :ref:`match ` type :math:`\REF~\NULL~\FUNC`. @@ -2410,17 +2482,17 @@ Control Instructions * The :ref:`expansion ` of :math:`C.\CTYPES[y]` must be a :ref:`function type ` :math:`\TFUNC~[t_1^\ast] \toF [t_2^\ast]`. -* Then the instruction is valid with type :math:`[t_1^\ast~\I32] \to [t_2^\ast]`. +* Then the instruction is valid with type :math:`[t_1^\ast~\X{at}] \to [t_2^\ast]`. .. math:: \frac{ - C.\CTABLES[x] = \limits~t + C.\CTABLES[x] = \X{at}~\limits~t \qquad C \vdashvaltypematch t \matchesreftype \REF~\NULL~\FUNC \qquad \expanddt(C.\CTYPES[y]) = \TFUNC~[t_1^\ast] \toF [t_2^\ast] }{ - C \vdashinstr \CALLINDIRECT~x~y : [t_1^\ast~\I32] \to [t_2^\ast] + C \vdashinstr \CALLINDIRECT~x~y : [t_1^\ast~\X{at}] \to [t_2^\ast] } @@ -2491,7 +2563,7 @@ Control Instructions * The table :math:`C.\CTABLES[x]` must be defined in the context. -* Let :math:`\limits~t` be the :ref:`table type ` :math:`C.\CTABLES[x]`. +* Let :math:`\X{at}~\limits~t` be the :ref:`table type ` :math:`C.\CTABLES[x]`. * The :ref:`reference type ` :math:`t` must :ref:`match ` type :math:`\REF~\NULL~\FUNC`. @@ -2501,11 +2573,11 @@ Control Instructions * The :ref:`result type ` :math:`[t_2^\ast]` must :ref:`match ` :math:`C.\CRETURN`. -* Then the instruction is valid with type :math:`[t_3^\ast~t_1^\ast~\I32] \to [t_4^\ast]`, for any sequences of :ref:`value types ` :math:`t_3^\ast` and :math:`t_4^\ast`. +* Then the instruction is valid with type :math:`[t_3^\ast~t_1^\ast~\X{at}] \to [t_4^\ast]`, for any sequences of :ref:`value types ` :math:`t_3^\ast` and :math:`t_4^\ast`. .. math:: \frac{ - C.\CTABLES[x] = \limits~t + C.\CTABLES[x] = \X{at}~\limits~t \qquad C \vdashvaltypematch t \matchesreftype \REF~\NULL~\FUNC \qquad @@ -2515,7 +2587,7 @@ Control Instructions \qquad C \vdashinstrtype [t_3^\ast~t_1^\ast~\I32] \to [t_4^\ast] \ok }{ - C \vdashinstr \RETURNCALLINDIRECT~x~y : [t_3^\ast~t_1^\ast~\I32] \to [t_4^\ast] + C \vdashinstr \RETURNCALLINDIRECT~x~y : [t_3^\ast~t_1^\ast~\X{at}] \to [t_4^\ast] } .. note:: diff --git a/document/core/valid/matching.rst b/document/core/valid/matching.rst index af9c161edf..12457adf82 100644 --- a/document/core/valid/matching.rst +++ b/document/core/valid/matching.rst @@ -502,7 +502,9 @@ Limits Table Types ~~~~~~~~~~~ -A :ref:`table type ` :math:`(\limits_1~\reftype_1)` matches :math:`(\limits_2~\reftype_2)` if and only if: +A :ref:`table type ` :math:`(\addrtype_1~\limits_1~\reftype_1)` matches :math:`(\addrtype_2~\limits_2~\reftype_2)` if and only if: + +* Address types :math:`\addrtype_1` and :math:`\addrtype_2` are the same. * Limits :math:`\limits_1` :ref:`match ` :math:`\limits_2`. @@ -517,7 +519,7 @@ A :ref:`table type ` :math:`(\limits_1~\reftype_1)` matches :m \qquad C \vdashreftypematch \reftype_2 \matchesreftype \reftype_1 }{ - C \vdashtabletypematch \limits_1~\reftype_1 \matchestabletype \limits_2~\reftype_2 + C \vdashtabletypematch \addrtype~\limits_1~\reftype_1 \matchestabletype \addrtype~\limits_2~\reftype_2 } @@ -527,7 +529,9 @@ A :ref:`table type ` :math:`(\limits_1~\reftype_1)` matches :m Memory Types ~~~~~~~~~~~~ -A :ref:`memory type ` :math:`\limits_1` matches :math:`\limits_2` if and only if: +A :ref:`memory type ` :math:`(\addrtype_1~\limits_1)` matches :math:`(\addrtype_2~\limits_2)` if and only if: + +* Address types :math:`\addrtype_1` and :math:`\addrtype_2` are the same. * Limits :math:`\limits_1` :ref:`match ` :math:`\limits_2`. @@ -537,7 +541,7 @@ A :ref:`memory type ` :math:`\limits_1` matches :math:`\limits_2 \frac{ C \vdashlimitsmatch \limits_1 \matcheslimits \limits_2 }{ - C \vdashmemtypematch \limits_1 \matchesmemtype \limits_2 + C \vdashmemtypematch \addrtype~\limits_1 \matchesmemtype \addrtype~\limits_2 } diff --git a/document/core/valid/modules.rst b/document/core/valid/modules.rst index 04388145ad..e110d0b6f0 100644 --- a/document/core/valid/modules.rst +++ b/document/core/valid/modules.rst @@ -841,8 +841,6 @@ The :ref:`external types ` classifying a module may contain f * Let :math:`\X{et}^\ast` be the concatenation of :ref:`external types ` :math:`\X{et}_i` of the exports, in index order. -* The length of :math:`C.\CMEMS` must not be larger than :math:`1`. - * All export names :math:`\export_i.\ENAME` must be different. * Then the module is valid with :ref:`external types ` :math:`\X{it}^\ast \to \X{et}^\ast`. diff --git a/document/core/valid/types.rst b/document/core/valid/types.rst index d4324f72bb..c1a97cb073 100644 --- a/document/core/valid/types.rst +++ b/document/core/valid/types.rst @@ -501,10 +501,10 @@ Limits Table Types ~~~~~~~~~~~ -:math:`\limits~\reftype` -........................ +:math:`\addrtype~\limits~\reftype` +.................................. -* The limits :math:`\limits` must be :ref:`valid ` within range :math:`2^{32}-1`. +* The limits :math:`\limits` must be :ref:`valid ` within range :math:`2^{|\addrtype|}-1`. * The reference type :math:`\reftype` must be :ref:`valid `. @@ -512,11 +512,11 @@ Table Types .. math:: \frac{ - C \vdashlimits \limits : 2^{32} - 1 + C \vdashlimits \limits : 2^{|\addrtype|}-1 \qquad C \vdashreftype \reftype \ok }{ - C \vdashtabletype \limits~\reftype \ok + C \vdashtabletype \addrtype~\limits~\reftype \ok } @@ -528,16 +528,16 @@ Table Types Memory Types ~~~~~~~~~~~~ -:math:`\limits` -............... +:math:`\addrtype~\limits` +......................... -* The limits :math:`\limits` must be :ref:`valid ` within range :math:`2^{16}`. +* The limits :math:`\limits` must be :ref:`valid ` within range :math:`2^{|\addrtype|-16}`. * Then the memory type is valid. .. math:: \frac{ - C \vdashlimits \limits : 2^{16} + C \vdashlimits \limits : 2^{|\addrtype|-16} }{ C \vdashmemtype \limits \ok } diff --git a/document/js-api/index.bs b/document/js-api/index.bs index f2db0bc6ca..7a6f9562aa 100644 --- a/document/js-api/index.bs +++ b/document/js-api/index.bs @@ -46,7 +46,24 @@ urlPrefix: https://tc39.github.io/ecma262/; spec: ECMASCRIPT url: sec-returnifabrupt-shorthands text: ! text: ? - text: Type; url: sec-ecmascript-data-types-and-values + url: sec-ecmascript-language-types-bigint-type + text: is a BigInt + text: is not a BigInt + url: sec-ecmascript-language-types-boolean-type + text: is a Boolean + text: is not a Boolean + url: sec-ecmascript-language-types-number-type + text: is a Number + text: is not a Number + url: sec-ecmascript-language-types-string-type + text: is a String + text: is not a String + url: sec-ecmascript-language-types-symbol-type + text: is a Symbol + text: is not a Symbol + url: sec-object-type + text: is an Object + text: is not an Object text: current Realm; url: current-realm text: ObjectCreate; url: sec-objectcreate text: CreateBuiltinFunction; url: sec-createbuiltinfunction @@ -54,6 +71,7 @@ urlPrefix: https://tc39.github.io/ecma262/; spec: ECMASCRIPT text: SetFunctionLength; url: sec-setfunctionlength text: the Number value; url: sec-ecmascript-language-types-number-type text: is a Number; url: sec-ecmascript-language-types-number-type + text: is a BigInt; url: sec-ecmascript-language-types-bigint-type text: NumberToRawBytes; url: sec-numbertorawbytes text: Built-in Function Objects; url: sec-built-in-function-objects text: NativeError Object Structure; url: sec-nativeerror-object-structure @@ -68,6 +86,7 @@ urlPrefix: https://tc39.github.io/ecma262/; spec: ECMASCRIPT text: NativeError Object Structure; url: sec-nativeerror-object-structure text: 𝔽; url: #𝔽 text: ℤ; url: #ℤ + text: mathematical value; url: #mathematical-value text: SameValue; url: sec-samevalue text: Array; url: sec-array-exotic-objects text: BigInt; url: sec-ecmascript-language-types-bigint-type @@ -135,6 +154,7 @@ urlPrefix: https://webassembly.github.io/spec/core/; spec: WebAssembly; type: df text: match_valtype; url: appendix/embedding.html#embed-match-valtype text: error; url: appendix/embedding.html#embed-error text: store; url: exec/runtime.html#syntax-store + text: address type; url: syntax/types.html#syntax-addrtype text: limits; url: syntax/types.html#syntax-limits text: table type; url: syntax/types.html#syntax-tabletype text: table address; url: exec/runtime.html#syntax-tableaddr @@ -155,6 +175,9 @@ urlPrefix: https://webassembly.github.io/spec/core/; spec: WebAssembly; type: df text: exn_alloc; url: appendix/embedding.html#embed-exn-alloc text: exn_tag; url: appendix/embedding.html#embed-exn-tag text: exn_read; url: appendix/embedding.html#embed-exn-read + url: syntax/values.html#syntax-int + text: u32 + text: u64 url: syntax/types.html#syntax-numtype text: i32 text: i64 @@ -216,6 +239,9 @@ urlPrefix: https://webassembly.github.io/spec/core/; spec: WebAssembly; type: df urlPrefix: https://heycam.github.io/webidl/; spec: WebIDL type: dfn text: create a namespace object; url: create-a-namespace-object + text: [EnforceRange]; url: #EnforceRange + text: unsigned long; url: #idl-unsigned-long + text: js-unsigned-long; url: #js-unsigned-long urlPrefix: https://webassembly.github.io/js-types/js-api/; spec: WebAssembly JS API (JS Type Reflection) type: abstract-op; text: FromValueType; url: abstract-opdef-fromvaluetype urlPrefix: https://tc39.es/proposal-resizablearraybuffer/; spec: ResizableArrayBuffer proposal @@ -405,7 +431,7 @@ A {{Module}} object represents a single WebAssembly module. Each {{Module}} obje 1. Let |imports| be « ». 1. [=list/iterate|For each=] (|moduleName|, |componentName|, |externtype|) of [=module_imports=](|module|), 1. Let |o| be [=?=] [$Get$](|importObject|, |moduleName|). - 1. If [=Type=](|o|) is not Object, throw a {{TypeError}} exception. + 1. If |o| [=is not an Object=], throw a {{TypeError}} exception. 1. Let |v| be [=?=] [$Get$](|o|, |componentName|). 1. If |externtype| is of the form [=external-type/func=] |functype|, 1. If [$IsCallable$](|v|) is false, throw a {{LinkError}} exception. @@ -579,6 +605,13 @@ enum ImportExportKind { "tag" }; +enum AddressType { + "i32", + "i64", +}; + +typedef any AddressValue; + dictionary ModuleExportDescriptor { required USVString name; required ImportExportKind kind; @@ -683,14 +716,15 @@ Note: The use of this synchronous API is discouraged, as some implementations so
 dictionary MemoryDescriptor {
-  required [EnforceRange] unsigned long initial;
-  [EnforceRange] unsigned long maximum;
+  required AddressValue initial;
+  AddressValue maximum;
+  AddressType address;
 };
 
 [LegacyNamespace=WebAssembly, Exposed=*]
 interface Memory {
   constructor(MemoryDescriptor descriptor);
-  unsigned long grow([EnforceRange] unsigned long delta);
+  AddressValue grow(AddressValue delta);
   ArrayBuffer toFixedLengthBuffer();
   ArrayBuffer toResizableBuffer();
   readonly attribute ArrayBuffer buffer;
@@ -753,9 +787,10 @@ which can be simultaneously referenced by multiple {{Instance}} objects. Each
 
 
The Memory(|descriptor|) constructor, when invoked, performs the following steps: - 1. Let |initial| be |descriptor|["initial"]. - 1. If |descriptor|["maximum"] [=map/exists=], let |maximum| be |descriptor|["maximum"]; otherwise, let |maximum| be empty. - 1. Let |memtype| be the [=memory type=] { [=limits|min=] |initial|, [=limits|max=] |maximum| }. + 1. If |descriptor|["address"] [=map/exists=], let |addrtype| be |descriptor|["address"]; otherwise, let |addrtype| be "i32". + 1. Let |initial| be [=?=] [=AddressValueToU64=](|descriptor|["initial"], |addrtype|). + 1. If |descriptor|["maximum"] [=map/exists=], let |maximum| be [=?=] [=AddressValueToU64=](|descriptor|["maximum"], |addrtype|); otherwise, let |maximum| be empty. + 1. Let |memtype| be [=memory type=] |addrtype| { **min** |initial|, **max** |maximum| }. 1. If |memtype| is not [=valid memtype|valid=], throw a {{RangeError}} exception. 1. Let |store| be the [=surrounding agent=]'s [=associated store=]. 1. Let (|store|, |memaddr|) be [=mem_alloc=](|store|, |memtype|). If allocation fails, throw a {{RangeError}} exception. @@ -795,7 +830,11 @@ which can be simultaneously referenced by multiple {{Instance}} objects. Each
The grow(|delta|) method, when invoked, performs the following steps: 1. Let |memaddr| be **this**.\[[Memory]]. - 1. Return the result of [=grow the memory buffer|growing the memory buffer=] associated with |memaddr| by |delta|. + 1. Let |store| be the [=surrounding agent=]'s [=associated store=]. + 1. Let |addrtype| be the [=address type=] in [=mem_type=](|store|, |memaddr|). + 1. Let |delta64| be [=?=] [=AddressValueToU64=](|delta|, |addrtype|). + 1. Let |ret| be the result of [=grow the memory buffer|growing the memory buffer=] associated with |memaddr| by |delta64|. + 1. Return [=U64ToAddressValue=](|ret|, |addrtype|).
Immediately after a WebAssembly [=memory.grow=] instruction executes, perform the following steps: @@ -873,17 +912,18 @@ enum TableKind { dictionary TableDescriptor { required TableKind element; - required [EnforceRange] unsigned long initial; - [EnforceRange] unsigned long maximum; + required AddressValue initial; + AddressValue maximum; + AddressType address; }; [LegacyNamespace=WebAssembly, Exposed=*] interface Table { constructor(TableDescriptor descriptor, optional any value); - unsigned long grow([EnforceRange] unsigned long delta, optional any value); - any get([EnforceRange] unsigned long index); - undefined set([EnforceRange] unsigned long index, optional any value); - readonly attribute unsigned long length; + AddressValue grow(AddressValue delta, optional any value); + any get(AddressValue index); + undefined set(AddressValue index, optional any value); + readonly attribute AddressValue length; };
@@ -911,17 +951,16 @@ Each {{Table}} object has a \[[Table]] internal slot, which is a [=table address
The Table(|descriptor|, |value|) constructor, when invoked, performs the following steps: - 1. Let |elementType| be [=ToValueType=](|descriptor|["element"]). - 1. If |elementType| is not a [=reftype=], - 1. Throw a {{TypeError}} exception. - 1. Let |initial| be |descriptor|["initial"]. - 1. If |descriptor|["maximum"] [=map/exists=], let |maximum| be |descriptor|["maximum"]; otherwise, let |maximum| be empty. - 1. Let |type| be the [=table type=] { [=limits|min=] |initial|, [=limits|max=] |maximum| } |elementType|. + 1. Let |elementtype| be [=ToValueType=](|descriptor|["element"]). + 1. If |elementtype| is not a [=reftype=], + 1. [=Throw=] a {{TypeError}} exception. + 1. If |descriptor|["address"] [=map/exists=], let |addrtype| be |descriptor|["address"]; otherwise, let |addrtype| be "i32". + 1. Let |initial| be [=?=] [=AddressValueToU64=](|descriptor|["initial"], |addrtype|). + 1. If |descriptor|["maximum"] [=map/exists=], let |maximum| be [=?=] [=AddressValueToU64=](|descriptor|["maximum"], |addrtype|); otherwise, let |maximum| be empty. + 1. Let |type| be the [=table type=] |addrtype| { [=limits|min=] |initial|, [=limits|max=] |maximum| } |elementType|. 1. If |type| is not [=valid tabletype|valid=], throw a {{RangeError}} exception. - - Note: Because tables may have up to 232 - 1 elements in validation, the checks for [=limits|min=] ≤ 232 - 1 and [=limits|max=] ≤ 232 - 1 in [=valid limits|limits validation=] cannot fail. 1. If |value| is missing, - 1. Let |ref| be [=DefaultValue=](|elementType|). + 1. Let |ref| be [=DefaultValue=](|elementtype|). 1. Assert: |ref| is not [=error=]. 1. Otherwise, 1. Let |ref| be [=?=] [=ToWebAssemblyValue=](|value|, |elementType|). @@ -936,13 +975,14 @@ Each {{Table}} object has a \[[Table]] internal slot, which is a [=table address 1. Let |tableaddr| be **this**.\[[Table]]. 1. Let |store| be the [=surrounding agent=]'s [=associated store=]. 1. Let |initialSize| be [=table_size=](|store|, |tableaddr|). - 1. Let (limits, |elementType|) be [=table_type=](|tableaddr|). + 1. Let (|addrtype|, limits, |elementtype|) be [=table_type=](|store|, |tableaddr|). + 1. Let |delta64| be [=?=] [=AddressValueToU64=](|delta|, |addrtype|). 1. If |value| is missing, - 1. Let |ref| be [=DefaultValue=](|elementType|). + 1. Let |ref| be [=DefaultValue=](|elementtype|). 1. If |ref| is [=error=], throw a {{TypeError}} exception. 1. Otherwise, - 1. Let |ref| be [=?=] [=ToWebAssemblyValue=](|value|, |elementType|). - 1. Let |result| be [=table_grow=](|store|, |tableaddr|, |delta|, |ref|). + 1. Let |ref| be [=?=] [=ToWebAssemblyValue=](|value|, |elementtype|). + 1. Let |result| be [=table_grow=](|store|, |tableaddr|, |delta64|, |ref|). 1. If |result| is [=error=], throw a {{RangeError}} exception. Note: The above exception can happen due to either insufficient memory or an invalid size parameter. @@ -955,17 +995,20 @@ Each {{Table}} object has a \[[Table]] internal slot, which is a [=table address The getter of the length attribute of {{Table}}, when invoked, performs the following steps: 1. Let |tableaddr| be **this**.\[[Table]]. 1. Let |store| be the [=surrounding agent=]'s [=associated store=]. - 1. Return [=table_size=](|store|, |tableaddr|). + 1. Let |addrtype| be the [=address type=] in [=table_type=](|store|, |tableaddr|). + 1. Let |length64| be [=table_size=](|store|, |tableaddr|). + 1. Return [=U64ToAddressValue=](|length64|, |addrtype|).
The get(|index|) method, when invoked, performs the following steps: 1. Let |tableaddr| be **this**.\[[Table]]. 1. Let |store| be the [=surrounding agent=]'s [=associated store=]. - 1. Let (limits, |elementType|) be [=table_type=](|store|, |tableaddr|). - 1. If |elementType| is [=exnref=], + 1. Let (|addrtype|, limits, |elementtype|) be [=table_type=](|store|, |tableaddr|). + 1. If |elementtype| is [=exnref=], 1. Throw a {{TypeError}} exception. - 1. Let |result| be [=table_read=](|store|, |tableaddr|, |index|). + 1. Let |index64| be [=?=] [=AddressValueToU64=](|index|, |addrtype|). + 1. Let |result| be [=table_read=](|store|, |tableaddr|, |index64|). 1. If |result| is [=error=], throw a {{RangeError}} exception. 1. Return [=ToJSValue=](|result|).
@@ -974,16 +1017,16 @@ Each {{Table}} object has a \[[Table]] internal slot, which is a [=table address The set(|index|, |value|) method, when invoked, performs the following steps: 1. Let |tableaddr| be **this**.\[[Table]]. 1. Let |store| be the [=surrounding agent=]'s [=associated store=]. - 1. Let (limits, |elementType|) be [=table_type=](|store|, |tableaddr|). - 1. If |elementType| is [=exnref=], + 1. Let (|addrtype|, limits, |elementtype|) be [=table_type=](|store|, |tableaddr|). + 1. If |elementtype| is [=exnref=], 1. Throw a {{TypeError}} exception. + 1. Let |index64| be [=?=] [=AddressValueToU64=](|index|, |addrtype|). 1. If |value| is missing, - 1. Let |ref| be [=DefaultValue=](|elementType|). + 1. Let |ref| be [=DefaultValue=](|elementtype|). 1. If |ref| is [=error=], throw a {{TypeError}} exception. 1. Otherwise, - 1. Let |ref| be [=?=] [=ToWebAssemblyValue=](|value|, |elementType|). - 1. Let |store| be the [=surrounding agent=]'s [=associated store=]. - 1. Let |store| be [=table_write=](|store|, |tableaddr|, |index|, |ref|). + 1. Let |ref| be [=?=] [=ToWebAssemblyValue=](|value|, |elementtype|). + 1. Let |store| be [=table_write=](|store|, |tableaddr|, |index64|, |ref|). 1. If |store| is [=error=], throw a {{RangeError}} exception. 1. Set the [=surrounding agent=]'s [=associated store=] to |store|. @@ -1252,18 +1295,18 @@ The algorithm ToJSValue(|w|) coerces a [=WebAssembly value=] to a Jav 1. Assert: |w| is not of the form [=ref.exn=] exnaddr. 1. If |w| is of the form [=i64.const=] |u64|, 1. Let |i64| be [=signed_64=](|u64|). - 1. Return [=ℤ=](|i64| interpreted as a mathematical value). -1. If |w| is of the form [=i32.const=] |i32|, - 1. Let |i32| be [=signed_32=](|i32|). - 2. Return [=𝔽=](|i32| interpreted as a mathematical value). + 1. Return [=ℤ=](|i64| interpreted as a [=mathematical value=]). +1. If |w| is of the form [=i32.const=] |u32|, + 1. Let |i32| be [=signed_32=](|u32|). + 2. Return [=𝔽=](|i32| interpreted as a [=mathematical value=]). 1. If |w| is of the form [=f32.const=] |f32|, 1. If |f32| is [=+∞=] or [=−∞=], return **+∞**𝔽 or **-∞**𝔽, respectively. 1. If |f32| is [=nan=], return **NaN**. - 1. Return [=𝔽=](|f32| interpreted as a mathematical value). + 1. Return [=𝔽=](|f32| interpreted as a [=mathematical value=]). 1. If |w| is of the form [=f64.const=] |f64|, 1. If |f64| is [=+∞=] or [=−∞=], return **+∞**𝔽 or **-∞**𝔽, respectively. 1. If |f64| is [=nan=], return **NaN**. - 1. Return [=𝔽=](|f64| interpreted as a mathematical value). + 1. Return [=𝔽=](|f64| interpreted as a [=mathematical value=]). 1. If |w| is of the form [=ref.null=] t, return null. 1. If |w| is of the form [=ref.i31=] |u31|, 1. Let |i31| be [=signed_31=](|u31|). @@ -1304,7 +1347,7 @@ The algorithm ToWebAssemblyValue(|v|, |type|) coerces a JavaScript va 1. If |type| is [=f32=], 1. Let |number| be [=?=] [$ToNumber$](|v|). 1. If |number| is **NaN**, - 1. Let |n| be an implementation-defined integer such that [=canon=]32 ≤ |n| < 2[=signif=](32). + 1. Let |n| be an implementation-defined integer such that [=canon=]32 ≤ |n| < 2[=signif=](32). 1. Let |f32| be [=nan=](n). 1. Otherwise, 1. Let |f32| be |number| rounded to the nearest representable value using IEEE 754-2008 round to nearest, ties to even mode. [[IEEE-754]] @@ -1312,7 +1355,7 @@ The algorithm ToWebAssemblyValue(|v|, |type|) coerces a JavaScript va 1. If |type| is [=f64=], 1. Let |number| be [=?=] [$ToNumber$](|v|). 1. If |number| is **NaN**, - 1. Let |n| be an implementation-defined integer such that [=canon=]64 ≤ |n| < 2[=signif=](64). + 1. Let |n| be an implementation-defined integer such that [=canon=]64 ≤ |n| < 2[=signif=](64). 1. Let |f64| be [=nan=](n). 1. Otherwise, 1. Let |f64| be |number|. @@ -1353,6 +1396,32 @@ The algorithm ToWebAssemblyValue(|v|, |type|) coerces a JavaScript va +
+The algorithm AddressValueToU64(|v|, |addrtype|) converts a JavaScript value to a WebAssembly [=u64=] for use in embedding operations. It is designed to act like [=[EnforceRange]=] [=unsigned long=] for {{AddressType}} "i32", and to extend these semantics to {{AddressType}} "i64", by performing the following steps: + +1. If |addrtype| is "i32", + 1. Let |n| be [=?=] [$ConvertToInt$](|v|, 32, "unsigned"), where the destination type is associated with [=[EnforceRange]=]. + + Note: This is equivalent to the [=js-unsigned-long|JS conversion rules=] for [=[EnforceRange]=] [=unsigned long=]. + 1. Return [=ℝ=](|n|) as a WebAssembly [=u64=]. +1. If |addrtype| is "i64", + 1. Let |n| be [=?=] [$ToBigInt$](|v|). + 1. If |n| < 0 or |n| > 264 − 1, [=throw=] a {{TypeError}}. + + Note: This operation is designed to emulate [=[EnforceRange]=]. + 1. Return [=ℝ=](|n|) as a WebAssembly [=u64=]. +1. Assert: This step is not reached. + +
+ +
+The algorithm U64ToAddressValue(|v|, |addrtype|) converts a [=u64=] value from a WebAssembly embedding operation to the correct variant of {{AddressValue}} for an {{AddressType}}, by performing the following steps: + +1. If |addrtype| is "i32", return [=𝔽=](|v| interpreted as a [=mathematical value=]). +1. Else if |addrtype| is "i64", return [=ℤ=](|v| interpreted as a [=mathematical value=]). +1. Assert: This step is not reached. + +

Tags

@@ -1385,7 +1454,6 @@ To initialize a Tag object |tag| from a [=tag address=] |tagAddress|,
- To create a Tag object from a [=tag address=] |tagAddress|, perform the following steps: 1. Let |map| be the [=surrounding agent=]'s associated [=Tag object cache=]. @@ -1771,11 +1839,18 @@ The following sections provide an overview of what has changed.

Release 2.0

Multiple Values

-Multiple values can be returned from WebAssembly functions into JavaScript as an [=Array=] object. +Multiple values can be returned to and from JavaScript functions as an [=Array=] object.

BigInt Integration

WebAssembly [=i64=] values can be passed to and from JavaScript (via imported or exported globals, table get or set operations, function return values or arguments) as [=BigInt=] objects. -

Reference types

+

Reference Types

JavaScript values can be passed to and from WebAssembly (via imported or exported globals, table set or get operations, and function arguments or return values) as [=externref=] values. + +

Multiple Tables

Multiple tables can be exported and imported to and from JavaScript. + +

Release 3.0

+ +

Multiple Memories

+Multiple memories can be exported and imported to and from JavaScript. diff --git a/document/versions/core/WebAssembly-3.0-draft.pdf b/document/versions/core/WebAssembly-3.0-draft.pdf index 9f31531594..1909a6257f 100644 Binary files a/document/versions/core/WebAssembly-3.0-draft.pdf and b/document/versions/core/WebAssembly-3.0-draft.pdf differ diff --git a/interpreter/README.md b/interpreter/README.md index f95f4b6bb7..7d143f6c4e 100644 --- a/interpreter/README.md +++ b/interpreter/README.md @@ -487,6 +487,9 @@ Commands are executed in sequence. Commands taking an optional module name refer After a module is _registered_ under a string name it is available for importing in other modules. +The failure string in assertions exists for documentation purposes. +The reference interpreter itself checks that the string is a prefix of the actual error message it generates. + The script format supports additional syntax for defining modules. A module of the form `(module binary *)` is given in binary form and will be decoded from the (concatenation of the) strings. A module of the form `(module quote *)` is given in textual form and will be parsed from the (concatenation of the) strings. In both cases, decoding/parsing happens when the command is executed, not when the script is parsed, so that meta commands like `assert_malformed` can be used to check expected errors. @@ -511,14 +514,14 @@ In that mode, execution may fail with a "crash" error message. When running scripts, the interpreter predefines a simple host module named `"spectest"` that has the following module type: ``` (module - (global (export "global_i32") i32) - (global (export "global_i64") i64) - (global (export "global_f32") f32) - (global (export "global_f64") f64) + (global (export "global_i32") i32) ;; value 666 + (global (export "global_i64") i64) ;; value 666 + (global (export "global_f32") f32) ;; value 666.6 + (global (export "global_f64") f64) ;; value 666.6 - (table (export "table") 10 20 funcref) + (table (export "table") 10 20 funcref) ;; null-initialized - (memory (export "memory") 1 2) + (memory (export "memory") 1 2) ;; zero-initialized (func (export "print")) (func (export "print_i32") (param i32)) diff --git a/interpreter/binary/decode.ml b/interpreter/binary/decode.ml index 2f7736c066..6ef9501d78 100644 --- a/interpreter/binary/decode.ml +++ b/interpreter/binary/decode.ml @@ -100,8 +100,8 @@ let rec sN n s = then (if b land 0x40 = 0 then x else Int64.(logor x (logxor (-1L) 0x7fL))) else Int64.(logor x (shift_left (sN (n - 7) s) 7)) -let u1 s = Int64.to_int (uN 1 s) let u32 s = Int64.to_int32 (uN 32 s) +let u64 s = uN 64 s let s7 s = Int64.to_int (sN 7 s) let s32 s = Int64.to_int32 (sN 32 s) let s33 s = I32_convert.wrap_i64 (sN 33 s) @@ -116,7 +116,6 @@ let len32 s = if I32.le_u n (Int32.of_int (len s - pos)) then Int32.to_int n else error s pos "length out of bounds" -let bool s = (u1 s = 1) let string s = let n = len32 s in get_string n s 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 @@ -287,19 +286,22 @@ let rec_type s = let limits uN s = - let has_max = bool s in + let flags = byte s in + require (flags land 0xfa = 0) s (pos s - 1) "malformed limits flags"; + let has_max = (flags land 1 = 1) in + let at = if flags land 4 = 4 then I64AT else I32AT in let min = uN s in let max = opt uN has_max s in - {min; max} + at, {min; max} let table_type s = let t = ref_type s in - let lim = limits u32 s in - TableT (lim, t) + let at, lim = limits u64 s in + TableT (at, lim, t) let memory_type s = - let lim = limits u32 s in - MemoryT lim + let at, lim = limits u64 s in + MemoryT (at, lim) let tag_type s = zero s; @@ -326,7 +328,7 @@ let memop s = let has_var = Int32.logand flags 0x40l <> 0l in let x = if has_var then at var s else Source.(0l @@ no_region) in let align = Int32.(to_int (logand flags 0x3fl)) in - let offset = u32 s in + let offset = u64 s in x, align, offset let block_type s = @@ -1107,7 +1109,7 @@ let import_desc s = | 0x01 -> TableImport (table_type s) | 0x02 -> MemoryImport (memory_type s) | 0x03 -> GlobalImport (global_type s) - | 0x04 -> TagImport (at var s) + | 0x04 -> TagImport (tag_type s) | _ -> error s (pos s - 1) "malformed import kind" let import s = @@ -1139,7 +1141,7 @@ let table s = ); (fun s -> let at = region s (pos s) (pos s) in - let TableT (_, (_, ht)) as ttype = table_type s in + let TableT (_, _at, (_, ht)) as ttype = table_type s in {ttype; tinit = [RefNull ht @@ at] @@ at} ); ] s diff --git a/interpreter/binary/encode.ml b/interpreter/binary/encode.ml index 97ec384b65..8924dd57d2 100644 --- a/interpreter/binary/encode.ml +++ b/interpreter/binary/encode.ml @@ -61,7 +61,6 @@ struct if -64L <= i && i < 64L then byte b else (byte (b lor 0x80); s64 (Int64.shift_right i 7)) - let u1 i = u64 Int64.(logand (of_int i) 1L) let u32 i = u64 Int64.(logand (of_int32 i) 0xffffffffL) let s7 i = s64 (Int64.of_int i) let s32 i = s64 (Int64.of_int32 i) @@ -70,12 +69,13 @@ struct let f64 x = word64 (F64.to_bits x) let v128 v = String.iter (put s) (V128.to_bits v) + let flag b i = if b then 1 lsl i else 0 + let len i = if Int32.to_int (Int32.of_int i) <> i then Code.error Source.no_region "length out of bounds"; u32 (Int32.of_int i) - let bool b = u1 (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 @@ -205,14 +205,15 @@ struct | RecT [st] -> sub_type st | RecT sts -> s7 (-0x32); vec sub_type sts - let limits uN {min; max} = - bool (max <> None); uN min; opt uN max + let limits at {min; max} = + let flags = flag (max <> None) 0 + flag (at = I64AT) 2 in + byte flags; u64 min; opt u64 max let table_type = function - | TableT (lim, t) -> ref_type t; limits u32 lim + | TableT (at, lim, t) -> ref_type t; limits at lim let memory_type = function - | MemoryT lim -> limits u32 lim + | MemoryT (at, lim) -> limits at lim let global_type = function | GlobalT (mut, t) -> val_type t; mutability mut @@ -238,7 +239,7 @@ struct Int32.(logor (of_int align) (if has_var then 0x40l else 0x00l)) in u32 flags; if has_var then var x; - u32 offset + u64 offset let block_type = function | VarBlockType x -> var_type s33 (StatX x.it) @@ -974,7 +975,7 @@ struct | TableImport t -> byte 0x01; table_type t | MemoryImport t -> byte 0x02; memory_type t | GlobalImport t -> byte 0x03; global_type t - | TagImport t -> byte 0x04; var t + | TagImport t -> byte 0x04; tag_type t let import im = let {module_name; item_name; idesc} = im.it in @@ -997,7 +998,7 @@ struct let table tab = let {ttype; tinit} = tab.it in match ttype, tinit.it with - | TableT (_, (_, ht1)), [{it = RefNull ht2; _}] when ht1 = ht2 -> + | TableT (_, _at, (_, ht1)), [{it = RefNull ht2; _}] when ht1 = ht2 -> table_type ttype | _ -> op 0x40; op 0x00; table_type ttype; const tinit @@ -1025,8 +1026,8 @@ struct section 6 (vec global) gs (gs <> []) (* Tag section *) - let tag tag = - tag_type tag.it.tgtype + let tag (t : tag) = + byte 0x00; var t.it.tgtype let tag_section ts = section 13 (vec tag) ts (ts <> []) diff --git a/interpreter/exec/eval.ml b/interpreter/exec/eval.ml index 9b9ae07e1c..086694efd6 100644 --- a/interpreter/exec/eval.ml +++ b/interpreter/exec/eval.ml @@ -151,13 +151,13 @@ let subst_of (inst : module_inst) = function let any_ref (inst : module_inst) x i at = try Table.load (table inst x) i with Table.Bounds -> - Trap.error at ("undefined element " ^ Int32.to_string i) + Trap.error at ("undefined element " ^ Int64.to_string i) let func_ref (inst : module_inst) x i at = match any_ref inst x i at with | FuncRef f -> f - | NullRef _ -> Trap.error at ("uninitialized element " ^ Int32.to_string i) - | _ -> Crash.error at ("type mismatch for element " ^ Int32.to_string i) + | NullRef _ -> Trap.error at ("uninitialized element " ^ Int64.to_string i) + | _ -> Crash.error at ("type mismatch for element " ^ Int64.to_string i) let block_type (inst : module_inst) bt at = match bt with @@ -205,20 +205,21 @@ let func_type_of_tag_type (_inst : module_inst) (TagT dt) : func_type = *) let mem_oob frame x i n = - I64.gt_u (I64.add (I64_convert.extend_i32_u i) (I64_convert.extend_i32_u n)) - (Memory.bound (memory frame.inst x)) + let mem = (memory frame.inst x) in + I64.gt_u (I64.add (addr_of_num i) (addr_of_num n)) + (Memory.bound mem) let data_oob frame x i n = - I64.gt_u (I64.add (I64_convert.extend_i32_u i) (I64_convert.extend_i32_u n)) + I64.gt_u (I64.add (addr_of_num i) (addr_of_num n)) (Data.size (data frame.inst x)) let table_oob frame x i n = - I64.gt_u (I64.add (I64_convert.extend_i32_u i) (I64_convert.extend_i32_u n)) - (I64_convert.extend_i32_u (Table.size (table frame.inst x))) + I64.gt_u (I64.add (addr_of_num i) (addr_of_num n)) + (Table.size (table frame.inst x)) let elem_oob frame x i n = - I64.gt_u (I64.add (I64_convert.extend_i32_u i) (I64_convert.extend_i32_u n)) - (I64_convert.extend_i32_u (Elem.size (elem frame.inst x))) + I64.gt_u (I64.add (addr_of_num i) (addr_of_num n)) + (Elem.size (elem frame.inst x)) let array_oob a i n = I64.gt_u (I64.add (I64_convert.extend_i32_u i) (I64_convert.extend_i32_u n)) @@ -328,8 +329,9 @@ let rec step (c : config) : config = | CallRef _x, Ref (FuncRef f) :: vs -> vs, [Invoke f @@ e.at] - | CallIndirect (x, y), Num (I32 i) :: vs -> - let f = func_ref c.frame.inst x i e.at in + | CallIndirect (x, y), Num i :: vs -> + let i_64 = addr_of_num i in + let f = func_ref c.frame.inst x i_64 e.at in if Match.match_def_type [] (Func.type_of f) (type_ c.frame.inst y) then vs, [Invoke f @@ e.at] else @@ -484,85 +486,96 @@ let rec step (c : config) : config = with Global.NotMutable -> Crash.error e.at "write to immutable global" | Global.Type -> Crash.error e.at "type mismatch at global write") - | TableGet x, Num (I32 i) :: vs' -> - (try Ref (Table.load (table c.frame.inst x) i) :: vs', [] + | TableGet x, Num i :: vs' -> + let i_64 = addr_of_num i in + (try Ref (Table.load (table c.frame.inst x) i_64) :: vs', [] with exn -> vs', [Trapping (table_error e.at exn) @@ e.at]) - | TableSet x, Ref r :: Num (I32 i) :: vs' -> - (try Table.store (table c.frame.inst x) i r; vs', [] + | TableSet x, Ref r :: Num i :: vs' -> + let i_64 = addr_of_num i in + (try Table.store (table c.frame.inst x) i_64 r; vs', [] with exn -> vs', [Trapping (table_error e.at exn) @@ e.at]) | TableSize x, vs -> - Num (I32 (Table.size (table c.frame.inst x))) :: vs, [] + let tab = table c.frame.inst x in + Num (num_of_addr (Table.addr_type_of tab) (Table.size tab)) :: vs, [] - | TableGrow x, Num (I32 delta) :: Ref r :: vs' -> + | TableGrow x, Num n :: Ref r :: vs' -> + let n_64 = addr_of_num n in let tab = table c.frame.inst x in let old_size = Table.size tab in let result = - try Table.grow tab delta r; old_size - with Table.SizeOverflow | Table.SizeLimit | Table.OutOfMemory -> -1l - in Num (I32 result) :: vs', [] + try Table.grow tab n_64 r; old_size + with Table.SizeOverflow | Table.SizeLimit | Table.OutOfMemory -> -1L + in Num (num_of_addr (Table.addr_type_of tab) result) :: vs', [] - | TableFill x, Num (I32 n) :: Ref r :: Num (I32 i) :: vs' -> + | TableFill x, Num n :: Ref r :: Num i :: vs' -> + let n_64 = addr_of_num n in + let i_64 = addr_of_num i in if table_oob c.frame x i n then vs', [Trapping (table_error e.at Table.Bounds) @@ e.at] - else if n = 0l then + else if n_64 = 0L then vs', [] else - let _ = assert (I32.lt_u i 0xffff_ffffl) in + let _ = assert (I64.lt_u i_64 0xffff_ffff_ffff_ffffL) in vs', List.map (Lib.Fun.flip (@@) e.at) [ - Plain (Const (I32 i @@ e.at)); + Plain (Const (i @@ e.at)); Refer r; Plain (TableSet x); - Plain (Const (I32 (I32.add i 1l) @@ e.at)); + Plain (Const (addr_add i 1L @@ e.at)); Refer r; - Plain (Const (I32 (I32.sub n 1l) @@ e.at)); + Plain (Const (addr_sub n 1L @@ e.at)); Plain (TableFill x); ] - | TableCopy (x, y), Num (I32 n) :: Num (I32 s) :: Num (I32 d) :: vs' -> + | TableCopy (x, y), Num n :: Num s :: Num d :: vs' -> + let n_64 = addr_of_num n in + let s_64 = addr_of_num s in + let d_64 = addr_of_num d in if table_oob c.frame x d n || table_oob c.frame y s n then vs', [Trapping (table_error e.at Table.Bounds) @@ e.at] - else if n = 0l then + else if n_64 = 0L then vs', [] - else if I32.le_u d s then + else if I64.le_u d_64 s_64 then vs', List.map (Lib.Fun.flip (@@) e.at) [ - Plain (Const (I32 d @@ e.at)); - Plain (Const (I32 s @@ e.at)); + Plain (Const (d @@ e.at)); + Plain (Const (s @@ e.at)); Plain (TableGet y); Plain (TableSet x); - Plain (Const (I32 (I32.add d 1l) @@ e.at)); - Plain (Const (I32 (I32.add s 1l) @@ e.at)); - Plain (Const (I32 (I32.sub n 1l) @@ e.at)); + Plain (Const (addr_add d 1L @@ e.at)); + Plain (Const (addr_add s 1L @@ e.at)); + Plain (Const (addr_sub n 1L @@ e.at)); Plain (TableCopy (x, y)); ] else (* d > s *) - let n' = I32.sub n 1l in + let n' = I64.sub n_64 1L in vs', List.map (Lib.Fun.flip (@@) e.at) [ - Plain (Const (I32 (I32.add d n') @@ e.at)); - Plain (Const (I32 (I32.add s n') @@ e.at)); + Plain (Const (addr_add d n' @@ e.at)); + Plain (Const (addr_add s n' @@ e.at)); Plain (TableGet y); Plain (TableSet x); - Plain (Const (I32 d @@ e.at)); - Plain (Const (I32 s @@ e.at)); - Plain (Const (I32 n' @@ e.at)); + Plain (Const (d @@ e.at)); + Plain (Const (s @@ e.at)); + Plain (Const (addr_sub n 1L @@ e.at)); Plain (TableCopy (x, y)); ] - | TableInit (x, y), Num (I32 n) :: Num (I32 s) :: Num (I32 d) :: vs' -> + | TableInit (x, y), Num n :: Num s :: Num d :: vs' -> + let n_64 = addr_of_num n in + let s_64 = addr_of_num s in if table_oob c.frame x d n || elem_oob c.frame y s n then vs', [Trapping (table_error e.at Table.Bounds) @@ e.at] - else if n = 0l then + else if n_64 = 0L then vs', [] else let seg = elem c.frame.inst y in vs', List.map (Lib.Fun.flip (@@) e.at) [ - Plain (Const (I32 d @@ e.at)); - Refer (Elem.load seg s); + Plain (Const (d @@ e.at)); + Refer (Elem.load seg s_64); Plain (TableSet x); - Plain (Const (I32 (I32.add d 1l) @@ e.at)); - Plain (Const (I32 (I32.add s 1l) @@ e.at)); - Plain (Const (I32 (I32.sub n 1l) @@ e.at)); + Plain (Const (addr_add d 1L @@ e.at)); + Plain (Const (addr_add s 1L @@ e.at)); + Plain (Const (addr_sub n 1L @@ e.at)); Plain (TableInit (x, y)); ] @@ -571,164 +584,170 @@ let rec step (c : config) : config = Elem.drop seg; vs, [] - | Load (x, {offset; ty; pack; _}), Num (I32 i) :: vs' -> + | Load (x, {offset; ty; pack; _}), Num i :: vs' -> + let i_64 = addr_of_num i in let mem = memory c.frame.inst x in - let a = I64_convert.extend_i32_u i in (try let n = match pack with - | None -> Memory.load_num mem a offset ty - | Some (sz, ext) -> Memory.load_num_packed sz ext mem a offset ty + | None -> Memory.load_num mem i_64 offset ty + | Some (sz, ext) -> Memory.load_num_packed sz ext mem i_64 offset ty in Num n :: vs', [] with exn -> vs', [Trapping (memory_error e.at exn) @@ e.at]) - | Store (x, {offset; pack; _}), Num n :: Num (I32 i) :: vs' -> + | Store (x, {offset; pack; _}), Num n :: Num i :: vs' -> + let i_64 = addr_of_num i in let mem = memory c.frame.inst x in - let a = I64_convert.extend_i32_u i in (try (match pack with - | None -> Memory.store_num mem a offset n - | Some sz -> Memory.store_num_packed sz mem a offset n + | None -> Memory.store_num mem i_64 offset n + | Some sz -> Memory.store_num_packed sz mem i_64 offset n ); vs', [] with exn -> vs', [Trapping (memory_error e.at exn) @@ e.at]); - | VecLoad (x, {offset; ty; pack; _}), Num (I32 i) :: vs' -> + | VecLoad (x, {offset; ty; pack; _}), Num i :: vs' -> + let i_64 = addr_of_num i in let mem = memory c.frame.inst x in - let a = I64_convert.extend_i32_u i in (try let v = match pack with - | None -> Memory.load_vec mem a offset ty - | Some (sz, ext) -> Memory.load_vec_packed sz ext mem a offset ty + | None -> Memory.load_vec mem i_64 offset ty + | Some (sz, ext) -> Memory.load_vec_packed sz ext mem i_64 offset ty in Vec v :: vs', [] with exn -> vs', [Trapping (memory_error e.at exn) @@ e.at]) - | VecStore (x, {offset; _}), Vec v :: Num (I32 i) :: vs' -> + | VecStore (x, {offset; _}), Vec v :: Num i :: vs' -> + let i_64 = addr_of_num i in let mem = memory c.frame.inst x in - let addr = I64_convert.extend_i32_u i in (try - Memory.store_vec mem addr offset v; + Memory.store_vec mem i_64 offset v; vs', [] with exn -> vs', [Trapping (memory_error e.at exn) @@ e.at]); - | VecLoadLane (x, {offset; ty; pack; _}, j), Vec (V128 v) :: Num (I32 i) :: vs' -> + | VecLoadLane (x, {offset; ty; pack; _}, j), Vec (V128 v) :: Num i :: vs' -> + let i_64 = addr_of_num i in let mem = memory c.frame.inst x in - let addr = I64_convert.extend_i32_u i in (try let v = match pack with | Pack8 -> V128.I8x16.replace_lane j v - (I32Num.of_num 0 (Memory.load_num_packed Pack8 SX mem addr offset I32T)) + (I32Num.of_num 0 (Memory.load_num_packed Pack8 SX mem i_64 offset I32T)) | Pack16 -> V128.I16x8.replace_lane j v - (I32Num.of_num 0 (Memory.load_num_packed Pack16 SX mem addr offset I32T)) + (I32Num.of_num 0 (Memory.load_num_packed Pack16 SX mem i_64 offset I32T)) | Pack32 -> V128.I32x4.replace_lane j v - (I32Num.of_num 0 (Memory.load_num mem addr offset I32T)) + (I32Num.of_num 0 (Memory.load_num mem i_64 offset I32T)) | Pack64 -> V128.I64x2.replace_lane j v - (I64Num.of_num 0 (Memory.load_num mem addr offset I64T)) + (I64Num.of_num 0 (Memory.load_num mem i_64 offset I64T)) in Vec (V128 v) :: vs', [] with exn -> vs', [Trapping (memory_error e.at exn) @@ e.at]) - | VecStoreLane (x, {offset; ty; pack; _}, j), Vec (V128 v) :: Num (I32 i) :: vs' -> + | VecStoreLane (x, {offset; ty; pack; _}, j), Vec (V128 v) :: Num i :: vs' -> + let i_64 = addr_of_num i in let mem = memory c.frame.inst x in - let addr = I64_convert.extend_i32_u i in (try (match pack with | Pack8 -> - Memory.store_num_packed Pack8 mem addr offset (I32 (V128.I8x16.extract_lane_s j v)) + Memory.store_num_packed Pack8 mem i_64 offset (I32 (V128.I8x16.extract_lane_s j v)) | Pack16 -> - Memory.store_num_packed Pack16 mem addr offset (I32 (V128.I16x8.extract_lane_s j v)) + Memory.store_num_packed Pack16 mem i_64 offset (I32 (V128.I16x8.extract_lane_s j v)) | Pack32 -> - Memory.store_num mem addr offset (I32 (V128.I32x4.extract_lane_s j v)) + Memory.store_num mem i_64 offset (I32 (V128.I32x4.extract_lane_s j v)) | Pack64 -> - Memory.store_num mem addr offset (I64 (V128.I64x2.extract_lane_s j v)) + Memory.store_num mem i_64 offset (I64 (V128.I64x2.extract_lane_s j v)) ); vs', [] with exn -> vs', [Trapping (memory_error e.at exn) @@ e.at]) | MemorySize x, vs -> let mem = memory c.frame.inst x in - Num (I32 (Memory.size mem)) :: vs, [] + Num (num_of_addr (Memory.addr_type_of mem) (Memory.size mem)) :: vs, [] - | MemoryGrow x, Num (I32 delta) :: vs' -> + | MemoryGrow x, Num n :: vs' -> + let n_64 = addr_of_num n in let mem = memory c.frame.inst x in let old_size = Memory.size mem in let result = - try Memory.grow mem delta; old_size - with Memory.SizeOverflow | Memory.SizeLimit | Memory.OutOfMemory -> -1l - in Num (I32 result) :: vs', [] + try Memory.grow mem n_64; old_size + with Memory.SizeOverflow | Memory.SizeLimit | Memory.OutOfMemory -> -1L + in Num (num_of_addr (Memory.addr_type_of mem) result) :: vs', [] - | MemoryFill x, Num (I32 n) :: Num k :: Num (I32 i) :: vs' -> + | MemoryFill x, Num n :: Num k :: Num i :: vs' -> + let n_64 = addr_of_num n in if mem_oob c.frame x i n then vs', [Trapping (memory_error e.at Memory.Bounds) @@ e.at] - else if n = 0l then + else if n_64 = 0L then vs', [] else vs', List.map (Lib.Fun.flip (@@) e.at) [ - Plain (Const (I32 i @@ e.at)); + Plain (Const (i @@ e.at)); Plain (Const (k @@ e.at)); Plain (Store - (x, {ty = I32T; align = 0; offset = 0l; pack = Some Pack8})); - Plain (Const (I32 (I32.add i 1l) @@ e.at)); + (x, {ty = I32T; align = 0; offset = 0L; pack = Some Pack8})); + Plain (Const (addr_add i 1L @@ e.at)); Plain (Const (k @@ e.at)); - Plain (Const (I32 (I32.sub n 1l) @@ e.at)); + Plain (Const (addr_sub n 1L @@ e.at)); Plain (MemoryFill x); ] - | MemoryCopy (x, y), Num (I32 n) :: Num (I32 s) :: Num (I32 d) :: vs' -> + | MemoryCopy (x, y), Num n :: Num s :: Num d :: vs' -> + let n_64 = addr_of_num n in + let s_64 = addr_of_num s in + let d_64 = addr_of_num d in if mem_oob c.frame x d n || mem_oob c.frame y s n then vs', [Trapping (memory_error e.at Memory.Bounds) @@ e.at] - else if n = 0l then + else if n_64 = 0L then vs', [] - else if I32.le_u d s then + else if I64.le_u d_64 s_64 then vs', List.map (Lib.Fun.flip (@@) e.at) [ - Plain (Const (I32 d @@ e.at)); - Plain (Const (I32 s @@ e.at)); + Plain (Const (d @@ e.at)); + Plain (Const (s @@ e.at)); Plain (Load - (y, {ty = I32T; align = 0; offset = 0l; pack = Some (Pack8, ZX)})); + (y, {ty = I32T; align = 0; offset = 0L; pack = Some (Pack8, ZX)})); Plain (Store - (x, {ty = I32T; align = 0; offset = 0l; pack = Some Pack8})); - Plain (Const (I32 (I32.add d 1l) @@ e.at)); - Plain (Const (I32 (I32.add s 1l) @@ e.at)); - Plain (Const (I32 (I32.sub n 1l) @@ e.at)); + (x, {ty = I32T; align = 0; offset = 0L; pack = Some Pack8})); + Plain (Const (addr_add d 1L @@ e.at)); + Plain (Const (addr_add s 1L @@ e.at)); + Plain (Const (addr_sub n 1L @@ e.at)); Plain (MemoryCopy (x, y)); ] else (* d > s *) - let n' = I32.sub n 1l in + let n' = I64.sub n_64 1L in vs', List.map (Lib.Fun.flip (@@) e.at) [ - Plain (Const (I32 (I32.add d n') @@ e.at)); - Plain (Const (I32 (I32.add s n') @@ e.at)); + Plain (Const (addr_add d n' @@ e.at)); + Plain (Const (addr_add s n' @@ e.at)); Plain (Load - (y, {ty = I32T; align = 0; offset = 0l; pack = Some (Pack8, ZX)})); + (y, {ty = I32T; align = 0; offset = 0L; pack = Some (Pack8, ZX)})); Plain (Store - (x, {ty = I32T; align = 0; offset = 0l; pack = Some Pack8})); - Plain (Const (I32 d @@ e.at)); - Plain (Const (I32 s @@ e.at)); - Plain (Const (I32 n' @@ e.at)); + (x, {ty = I32T; align = 0; offset = 0L; pack = Some Pack8})); + Plain (Const (d @@ e.at)); + Plain (Const (s @@ e.at)); + Plain (Const (addr_sub n 1L @@ e.at)); Plain (MemoryCopy (x, y)); ] - | MemoryInit (x, y), Num (I32 n) :: Num (I32 s) :: Num (I32 d) :: vs' -> + | MemoryInit (x, y), Num n :: Num s :: Num d :: vs' -> + let n_64 = addr_of_num n in + let s_64 = addr_of_num s in if mem_oob c.frame x d n || data_oob c.frame y s n then vs', [Trapping (memory_error e.at Memory.Bounds) @@ e.at] - else if n = 0l then + else if n_64 = 0L then vs', [] else let seg = data c.frame.inst y in - let a = I64_convert.extend_i32_u s in - let b = Data.load_byte seg a in + let b = Data.load_byte seg s_64 in vs', List.map (Lib.Fun.flip (@@) e.at) [ - Plain (Const (I32 d @@ e.at)); + Plain (Const (d @@ e.at)); Plain (Const (I32 (I32.of_int_u (Char.code b)) @@ e.at)); Plain (Store - (x, {ty = I32T; align = 0; offset = 0l; pack = Some Pack8})); - Plain (Const (I32 (I32.add d 1l) @@ e.at)); - Plain (Const (I32 (I32.add s 1l) @@ e.at)); - Plain (Const (I32 (I32.sub n 1l) @@ e.at)); + (x, {ty = I64T; align = 0; offset = 0L; pack = Some Pack8})); + Plain (Const (addr_add d 1L @@ e.at)); + Plain (Const (addr_add s 1L @@ e.at)); + Plain (Const (addr_sub n 1L @@ e.at)); Plain (MemoryInit (x, y)); ] @@ -841,28 +860,33 @@ let rec step (c : config) : config = with Failure _ -> Crash.error e.at "type mismatch packing value" in Ref (Aggr.ArrayRef array) :: vs'', [] - | ArrayNewElem (x, y), Num (I32 n) :: Num (I32 s) :: vs' -> + | ArrayNewElem (x, y), Num n :: Num s :: vs' -> + let n_64 = addr_of_num n in + let s_64 = addr_of_num s in if elem_oob c.frame y s n then vs', [Trapping (table_error e.at Table.Bounds) @@ e.at] else let seg = elem c.frame.inst y in - let rs = Lib.List32.init n (fun i -> Elem.load seg (Int32.add s i)) in + let rs = Lib.List64.init n_64 + (fun i -> Elem.load seg (Int64.add s_64 i)) in let args = List.map (fun r -> Ref r) rs in let array = try Aggr.alloc_array (type_ c.frame.inst x) args with Failure _ -> Crash.error e.at "type mismatch packing value" in Ref (Aggr.ArrayRef array) :: vs', [] - | ArrayNewData (x, y), Num (I32 n) :: Num (I32 s) :: vs' -> + | ArrayNewData (x, y), Num n :: Num s :: vs' -> + let n_64 = addr_of_num n in + let s_64 = addr_of_num s in if data_oob c.frame y s n then vs', [Trapping (memory_error e.at Memory.Bounds) @@ e.at] else let ArrayT (FieldT (_mut, st)) = array_type c.frame.inst x in let seg = data c.frame.inst y in - let args = Lib.List32.init n + let args = Lib.List64.init n_64 (fun i -> - let a = I32.(add s (mul i (I32.of_int_u (storage_size st)))) in - Data.load_val_storage seg (I64_convert.extend_i32_u a) st + let a = I64.(add s_64 (mul i (I64.of_int_u (storage_size st)))) in + Data.load_val_storage seg a st ) in let array = @@ -977,17 +1001,18 @@ let rec step (c : config) : config = vs', [Trapping "null array reference" @@ e.at] | ArrayInitData (x, y), - Num (I32 n) :: Num (I32 s) :: Num (I32 d) :: Ref (Aggr.ArrayRef a) :: vs' -> + Num (I32 n) :: Num s :: Num (I32 d) :: Ref (Aggr.ArrayRef a) :: vs' -> + let s_64 = addr_of_num s in if array_oob a d n then vs', [Trapping "out of bounds array access" @@ e.at] - else if data_oob c.frame y s n then + else if data_oob c.frame y s (I64 (I64_convert.extend_i32_u n)) then vs', [Trapping (memory_error e.at Memory.Bounds) @@ e.at] else if n = 0l then vs', [] else let ArrayT (FieldT (_mut, st)) = array_type c.frame.inst x in let seg = data c.frame.inst y in - let v = Data.load_val_storage seg (I64_convert.extend_i32_u s) st in + let v = Data.load_val_storage seg s_64 st in vs', List.map (Lib.Fun.flip (@@) e.at) [ Refer (Aggr.ArrayRef a); Plain (Const (I32 d @@ e.at)); @@ -995,7 +1020,7 @@ let rec step (c : config) : config = Plain (ArraySet x); Refer (Aggr.ArrayRef a); Plain (Const (I32 (I32.add d 1l) @@ e.at)); - Plain (Const (I32 (I32.add s (I32.of_int_u (storage_size st))) @@ e.at)); + Plain (Const (addr_add s (I64.of_int_u (storage_size st)) @@ e.at)); Plain (Const (I32 (I32.sub n 1l) @@ e.at)); Plain (ArrayInitData (x, y)); ] @@ -1005,16 +1030,17 @@ let rec step (c : config) : config = vs', [Trapping "null array reference" @@ e.at] | ArrayInitElem (x, y), - Num (I32 n) :: Num (I32 s) :: Num (I32 d) :: Ref (Aggr.ArrayRef a) :: vs' -> + Num (I32 n) :: Num s :: Num (I32 d) :: Ref (Aggr.ArrayRef a) :: vs' -> + let s_64 = addr_of_num s in if array_oob a d n then vs', [Trapping "out of bounds array access" @@ e.at] - else if elem_oob c.frame y s n then + else if elem_oob c.frame y s (I64 (I64_convert.extend_i32_u n)) then vs', [Trapping (table_error e.at Table.Bounds) @@ e.at] else if n = 0l then vs', [] else let seg = elem c.frame.inst y in - let v = Ref (Elem.load seg s) in + let v = Ref (Elem.load seg s_64) in vs', List.map (Lib.Fun.flip (@@) e.at) [ Refer (Aggr.ArrayRef a); Plain (Const (I32 d @@ e.at)); @@ -1022,7 +1048,7 @@ let rec step (c : config) : config = Plain (ArraySet x); Refer (Aggr.ArrayRef a); Plain (Const (I32 (I32.add d 1l) @@ e.at)); - Plain (Const (I32 (I32.add s 1l) @@ e.at)); + Plain (Const (addr_add s 1L @@ e.at)); Plain (Const (I32 (I32.sub n 1l) @@ e.at)); Plain (ArrayInitElem (x, y)); ] @@ -1337,7 +1363,6 @@ let eval_const (inst : module_inst) (const : const) : value = | [v] -> v | vs -> Crash.error const.at "wrong number of results on stack" - (* Modules *) let init_type (inst : module_inst) (type_ : type_) : module_inst = diff --git a/interpreter/host/spectest.ml b/interpreter/host/spectest.ml index a9a0f8446f..8d6c039bf4 100644 --- a/interpreter/host/spectest.ml +++ b/interpreter/host/spectest.ml @@ -20,11 +20,15 @@ let global (GlobalT (_, t) as gt) = in ExternGlobal (Global.alloc gt v) let table = - let tt = TableT ({min = 10l; max = Some 20l}, (Null, FuncHT)) in + let tt = TableT (I32AT, {min = 10L; max = Some 20L}, (Null, FuncHT)) in + ExternTable (Table.alloc tt (NullRef FuncHT)) + +let table64 = + let tt = TableT (I64AT, {min = 10L; max = Some 20L}, (Null, FuncHT)) in ExternTable (Table.alloc tt (NullRef FuncHT)) let memory = - let mt = MemoryT {min = 1l; max = Some 2l} in + let mt = MemoryT (I32AT, {min = 1L; max = Some 2L}) in ExternMemory (Memory.alloc mt) let func f ft = @@ -55,5 +59,6 @@ let lookup name t = | "global_f32", _ -> global (GlobalT (Cons, NumT F32T)) | "global_f64", _ -> global (GlobalT (Cons, NumT F64T)) | "table", _ -> table + | "table64", _ -> table64 | "memory", _ -> memory | _ -> raise Not_found diff --git a/interpreter/runtime/data.ml b/interpreter/runtime/data.ml index 785dcc6081..66c2ad58db 100644 --- a/interpreter/runtime/data.ml +++ b/interpreter/runtime/data.ml @@ -1,6 +1,5 @@ type data = string ref type t = data -type address = Memory.address exception Bounds diff --git a/interpreter/runtime/data.mli b/interpreter/runtime/data.mli index f0074e366c..86741d5c0e 100644 --- a/interpreter/runtime/data.mli +++ b/interpreter/runtime/data.mli @@ -1,6 +1,7 @@ +open Value + type data type t = data -type address = Memory.address exception Bounds diff --git a/interpreter/runtime/elem.ml b/interpreter/runtime/elem.ml index 7a26055c94..101474f978 100644 --- a/interpreter/runtime/elem.ml +++ b/interpreter/runtime/elem.ml @@ -4,10 +4,10 @@ type t = elem exception Bounds let alloc rs = ref rs -let size seg = Lib.List32.length !seg +let size seg = Lib.List64.length !seg let load seg i = - if i < 0l || i >= Lib.List32.length !seg then raise Bounds; - Lib.List32.nth !seg i + if i < 0L || i >= Lib.List64.length !seg then raise Bounds; + Lib.List64.nth !seg i let drop seg = seg := [] diff --git a/interpreter/runtime/elem.mli b/interpreter/runtime/elem.mli index b9b35a11dd..d614429077 100644 --- a/interpreter/runtime/elem.mli +++ b/interpreter/runtime/elem.mli @@ -7,5 +7,5 @@ exception Bounds val alloc : ref_ list -> elem val size : elem -> Table.size -val load : elem -> Table.index -> ref_ (* raises Bounds *) +val load : elem -> address -> ref_ (* raises Bounds *) val drop : elem -> unit diff --git a/interpreter/runtime/memory.ml b/interpreter/runtime/memory.ml index cf909691d9..3c3742d94d 100644 --- a/interpreter/runtime/memory.ml +++ b/interpreter/runtime/memory.ml @@ -1,10 +1,10 @@ open Types +open Value open Bigarray open Lib.Bigarray -type size = int32 (* number of pages *) -type address = int64 -type offset = int32 +type size = int64 (* number of pages *) +type offset = address type count = int32 type memory' = (int, int8_unsigned_elt, c_layout) Array1.t @@ -22,19 +22,24 @@ let page_size = 0x10000L (* 64 KiB *) let valid_limits {min; max} = match max with | None -> true - | Some m -> I32.le_u min m + | Some m -> I64.le_u min m + +let valid_size at i = + match at with + | I32AT -> I64.le_u i 0xffffL + | I64AT -> true let create n = - if I32.gt_u n 0x10000l then raise SizeOverflow else try - let size = Int64.(mul (of_int32 n) page_size) in + let size = Int64.(mul n page_size) in let mem = Array1_64.create Int8_unsigned C_layout size in Array1.fill mem 0; mem with Out_of_memory -> raise OutOfMemory -let alloc (MemoryT lim as ty) = +let alloc (MemoryT (at, lim) as ty) = assert Free.((memory_type ty).types = Set.empty); + if not (valid_size at lim.min) then raise SizeOverflow; if not (valid_limits lim) then raise Type; {ty; content = create lim.min} @@ -42,23 +47,27 @@ let bound mem = Array1_64.dim mem.content let size mem = - Int64.(to_int32 (div (bound mem) page_size)) + Int64.(div (bound mem) page_size) let type_of mem = mem.ty +let addr_type_of mem = + let MemoryT (at, _) = type_of mem in at + let grow mem delta = - let MemoryT lim = mem.ty in + let MemoryT (at, lim) = mem.ty in assert (lim.min = size mem); let old_size = lim.min in - let new_size = Int32.add old_size delta in - if I32.gt_u old_size new_size then raise SizeOverflow else + let new_size = Int64.add old_size delta in + if I64.gt_u old_size new_size then raise SizeOverflow else let lim' = {lim with min = new_size} in + if not (valid_size at new_size) then raise SizeOverflow else if not (valid_limits lim') then raise SizeLimit else let after = create new_size in let dim = Array1_64.dim mem.content in Array1.blit (Array1_64.sub mem.content 0L dim) (Array1_64.sub after 0L dim); - mem.ty <- MemoryT lim'; + mem.ty <- MemoryT (at, lim'); mem.content <- after let load_byte mem a = @@ -77,6 +86,7 @@ let load_bytes mem a n = Buffer.contents buf let store_bytes mem a bs = + if a < 0L then raise Bounds; for i = String.length bs - 1 downto 0 do store_byte mem Int64.(add a (of_int i)) (Char.code bs.[i]) done @@ -85,7 +95,7 @@ let store_bytes mem a bs = (* Typed accessors *) let effective_address a o = - let ea = Int64.(add a (of_int32 o)) in + let ea = Int64.(add a o) in if I64.lt_u ea a then raise Bounds; ea diff --git a/interpreter/runtime/memory.mli b/interpreter/runtime/memory.mli index 810f229c5c..9f0edc7cd3 100644 --- a/interpreter/runtime/memory.mli +++ b/interpreter/runtime/memory.mli @@ -1,11 +1,11 @@ open Types +open Value type memory type t = memory -type size = int32 (* number of pages *) -type address = int64 -type offset = int32 +type size = int64 (* number of pages *) +type offset = address type count = int32 exception Type @@ -18,6 +18,7 @@ val page_size : int64 val alloc : memory_type -> memory (* raises Type, SizeOverflow, OutOfMemory *) val type_of : memory -> memory_type +val addr_type_of : memory -> addr_type val size : memory -> size val bound : memory -> address val grow : memory -> size -> unit @@ -31,8 +32,6 @@ val store_bytes : memory -> address -> string -> unit (* raises Bounds *) (* Typed accessors *) -open Value - val load_num : memory -> address -> offset -> num_type -> num (* raises Bounds *) val store_num : diff --git a/interpreter/runtime/table.ml b/interpreter/runtime/table.ml index 4547824ede..94a007ecff 100644 --- a/interpreter/runtime/table.ml +++ b/interpreter/runtime/table.ml @@ -1,9 +1,8 @@ open Types open Value -type size = int32 -type index = int32 -type count = int32 +type size = address +type offset = address type table = {mutable ty : table_type; mutable content : ref_ array} type t = table @@ -17,47 +16,63 @@ exception OutOfMemory let valid_limits {min; max} = match max with | None -> true - | Some m -> I32.le_u min m + | Some m -> I64.le_u min m + +let valid_size at i = + match at with + | I32AT -> I64.le_u i 0xffff_ffffL + | I64AT -> true let create size r = - try Lib.Array32.make size r + try Lib.Array64.make size r with Out_of_memory | Invalid_argument _ -> raise OutOfMemory -let alloc (TableT (lim, t) as ty) r = +let alloc (TableT (at, lim, t) as ty) r = assert Free.((ref_type t).types = Set.empty); + if not (valid_size at lim.min) then raise SizeOverflow; if not (valid_limits lim) then raise Type; {ty; content = create lim.min r} let size tab = - Lib.Array32.length tab.content + Lib.Array64.length tab.content let type_of tab = tab.ty +let addr_type_of tab = + let TableT (at, _, _) = type_of tab in at + +let addr_of_num x = + match x with + | I64 i -> i + | I32 i -> I64_convert.extend_i32_u i + | _ -> raise Type + let grow tab delta r = - let TableT (lim, t) = tab.ty in + let TableT (at, lim, t) = tab.ty in assert (lim.min = size tab); let old_size = lim.min in - let new_size = Int32.add old_size delta in - if I32.gt_u old_size new_size then raise SizeOverflow else + let new_size = Int64.add old_size delta in + if I64.gt_u old_size new_size then raise SizeOverflow else let lim' = {lim with min = new_size} in + if not (valid_size at new_size) then raise SizeOverflow else if not (valid_limits lim') then raise SizeLimit else let after = create new_size r in Array.blit tab.content 0 after 0 (Array.length tab.content); - tab.ty <- TableT (lim', t); + tab.ty <- TableT (at, lim', t); tab.content <- after let load tab i = - if i < 0l || i >= Lib.Array32.length tab.content then raise Bounds; - Lib.Array32.get tab.content i + if i < 0L || i >= Lib.Array64.length tab.content then raise Bounds; + Lib.Array64.get tab.content i let store tab i r = - let TableT (lim, t) = tab.ty in - if i < 0l || i >= Lib.Array32.length tab.content then raise Bounds; - Lib.Array32.set tab.content i r + let TableT (_at, _lim, t) = tab.ty in + if i < 0L || i >= Lib.Array64.length tab.content then raise Bounds; + Lib.Array64.set tab.content i r let blit tab offset rs = let data = Array.of_list rs in - let len = Lib.Array32.length data in - if offset < 0l || offset > Int32.sub (Lib.Array32.length tab.content) len then raise Bounds; - Lib.Array32.blit data 0l tab.content offset len + let len = Lib.Array64.length data in + if offset < 0L || offset > Int64.sub (Lib.Array64.length tab.content) len then raise Bounds; + Lib.Array64.blit data 0L tab.content offset len diff --git a/interpreter/runtime/table.mli b/interpreter/runtime/table.mli index 2d95b7411f..53caf5965e 100644 --- a/interpreter/runtime/table.mli +++ b/interpreter/runtime/table.mli @@ -4,9 +4,8 @@ open Value type table type t = table -type size = int32 -type index = int32 -type count = int32 +type size = address +type offset = address exception Type exception Bounds @@ -16,10 +15,12 @@ exception OutOfMemory val alloc : table_type -> ref_ -> table (* raises Type, OutOfMemory *) val type_of : table -> table_type +val addr_type_of : table -> addr_type val size : table -> size +val addr_of_num : num -> address val grow : table -> size -> ref_ -> unit (* raises SizeOverflow, SizeLimit, OutOfMemory *) -val load : table -> index -> ref_ (* raises Bounds *) -val store : table -> index -> ref_ -> unit (* raises Type, Bounds *) -val blit : table -> index -> ref_ list -> unit (* raises Bounds *) +val load : table -> address -> ref_ (* raises Bounds *) +val store : table -> address -> ref_ -> unit (* raises Type, Bounds *) +val blit : table -> address -> ref_ list -> unit (* raises Bounds *) diff --git a/interpreter/runtime/value.ml b/interpreter/runtime/value.ml index a24fbaf281..75c5cd2c97 100644 --- a/interpreter/runtime/value.ml +++ b/interpreter/runtime/value.ml @@ -19,6 +19,8 @@ type t = value type ref_ += NullRef of heap_type +type address = I64.t + (* Injection & projection *) @@ -281,6 +283,23 @@ let storage_bits_of_val st v = let value_of_bool b = Num (I32 (if b then 1l else 0l)) +let num_of_addr at i = + match at with + | I64AT -> I64 i + | I32AT -> I32 (I32_convert.wrap_i64 i) + +let addr_of_num x = + match x with + | I32 i -> I64_convert.extend_i32_u i + | I64 i -> i + | _ -> raise Type + +let addr_add n i = + num_of_addr (addr_type_of_num_type (type_of_num n)) (I64.add (addr_of_num n) i) +let addr_sub n i = + num_of_addr (addr_type_of_num_type (type_of_num n)) (I64.sub (addr_of_num n) i) + + let string_of_num = function | I32 i -> I32.to_string_s i | I64 i -> I64.to_string_s i diff --git a/interpreter/script/js.ml b/interpreter/script/js.ml index 1415222ce1..a125e9a0b9 100644 --- a/interpreter/script/js.ml +++ b/interpreter/script/js.ml @@ -36,7 +36,10 @@ let spectest = { global_f32: 666.6, global_f64: 666.6, table: new WebAssembly.Table({initial: 10, maximum: 20, element: 'anyfunc'}), - memory: new WebAssembly.Memory({initial: 1, maximum: 2}) + table64: new WebAssembly.Table( + {initial: 10n, maximum: 20n, element: 'anyfunc', address: 'i64'}), + memory: new WebAssembly.Memory({initial: 1, maximum: 2}), + memory64: new WebAssembly.Memory({initial: 1n, maximum: 2n, address: 'i64'}) }; let handler = { @@ -317,8 +320,15 @@ let value v = | Num n -> [Const (n @@ v.at) @@ v.at] | Vec s -> [VecConst (s @@ v.at) @@ v.at] | Ref (NullRef ht) -> [RefNull (Match.bot_of_heap_type [] ht) @@ v.at] + | Ref (HostRef n) -> + [ Const (I32 n @@ v.at) @@ v.at; + Call (hostref_idx @@ v.at) @@ v.at; + ] | Ref (Extern.ExternRef (HostRef n)) -> - [Const (I32 n @@ v.at) @@ v.at; Call (hostref_idx @@ v.at) @@ v.at] + [ Const (I32 n @@ v.at) @@ v.at; + Call (hostref_idx @@ v.at) @@ v.at; + ExternConvert Externalize @@ v.at; + ] | Ref _ -> assert false let invoke ft vs at = @@ -365,8 +375,14 @@ let rec type_of_result res = ) (List.hd ts) ts let assert_return ress ts at = + let locals = ref [] in let rec test (res, t) = - if not (Match.match_val_type [] t (type_of_result res)) then + if + not ( + Match.match_val_type [] t (type_of_result res) || + Match.match_val_type [] (type_of_result res) t + ) + then [ Br (0l @@ at) @@ at ] else match res.it with @@ -442,7 +458,14 @@ let assert_return ress ts at = | RefResult (RefPat {it = HostRef n; _}) -> [ Const (Value.I32 n @@ at) @@ at; Call (hostref_idx @@ at) @@ at; - Call (eq_ref_idx @@ at) @@ at; + Call (eq_ref_idx @@ at) @@ at; + Test (Value.I32 I32Op.Eqz) @@ at; + BrIf (0l @@ at) @@ at ] + | RefResult (RefPat {it = Extern.ExternRef (HostRef n); _}) -> + [ Const (Value.I32 n @@ at) @@ at; + Call (hostref_idx @@ at) @@ at; + ExternConvert Externalize @@ at; + Call (eq_ref_idx @@ at) @@ at; Test (Value.I32 I32Op.Eqz) @@ at; BrIf (0l @@ at) @@ at ] | RefResult (RefPat _) -> @@ -458,9 +481,13 @@ let assert_return ress ts at = Test (I32 I32Op.Eqz) @@ at; BrIf (0l @@ at) @@ at ] | EitherResult ress -> - [ Block (ValBlockType None, + let idx = Lib.List32.length !locals in + locals := !locals @ [{ltype = t} @@ res.at]; + [ LocalSet (idx @@ res.at) @@ res.at; + Block (ValBlockType None, List.map (fun resI -> Block (ValBlockType None, + [LocalGet (idx @@ resI.at) @@ resI.at] @ test (resI, t) @ [Br (1l @@ resI.at) @@ resI.at] ) @@ resI.at @@ -468,7 +495,7 @@ let assert_return ress ts at = [Br (1l @@ at) @@ at] ) @@ at ] - in [], List.flatten (List.rev_map test (List.combine ress ts)) + in !locals, List.flatten (List.rev_map test (List.combine ress ts)) let i32 = NumT I32T let anyref = RefT (Null, AnyHT) @@ -507,12 +534,20 @@ let wrap item_name wrap_action wrap_assertion at = in let funcs = [{ftype = 0l @@ at; locals; body} @@ at] in let m = {empty_module with types; funcs; imports; exports} @@ at in + (try + Valid.check_module m; (* sanity check *) + with Valid.Invalid _ as exn -> + prerr_endline (string_of_region at ^ + ": internal error in JS converter, invalid wrapper module generated:"); + Sexpr.output stderr 80 (Arrange.module_ m); + raise exn + ); Encode.encode m let is_js_num_type = function - | I32T -> true - | I64T | F32T | F64T -> false + | I32T | I64T -> true + | F32T | F64T -> false let is_js_vec_type = function | _ -> false @@ -572,7 +607,7 @@ let of_num n = let open Value in match n with | I32 i -> I32.to_string_s i - | I64 i -> "int64(\"" ^ I64.to_string_s i ^ "\")" + | I64 i -> I64.to_string_s i ^ "n" | F32 z -> of_float (F32.to_float z) | F64 z -> of_float (F64.to_float z) diff --git a/interpreter/syntax/ast.ml b/interpreter/syntax/ast.ml index 58446a70a3..5ee382fdeb 100644 --- a/interpreter/syntax/ast.ml +++ b/interpreter/syntax/ast.ml @@ -127,7 +127,7 @@ type vec_splatop = (V128Op.splatop) Value.vecop type vec_extractop = (V128Op.extractop) Value.vecop type vec_replaceop = (V128Op.replaceop) Value.vecop -type ('t, 'p) memop = {ty : 't; align : int; offset : int32; pack : 'p} +type ('t, 'p) memop = {ty : 't; align : int; offset : int64; pack : 'p} type loadop = (num_type, (pack_size * extension) option) memop type storeop = (num_type, pack_size option) memop diff --git a/interpreter/syntax/free.ml b/interpreter/syntax/free.ml index d9e5870fb6..8bfb0d4052 100644 --- a/interpreter/syntax/free.ml +++ b/interpreter/syntax/free.ml @@ -126,8 +126,8 @@ let def_type = function | DefT (rt, _i) -> rec_type rt let global_type (GlobalT (_mut, t)) = val_type t -let table_type (TableT (_lim, t)) = ref_type t -let memory_type (MemoryT (_lim)) = empty +let table_type (TableT (_at, _lim, t)) = ref_type t +let memory_type (MemoryT (_at, _lim)) = empty let tag_type (TagT dt) = def_type dt let extern_type = function diff --git a/interpreter/syntax/operators.ml b/interpreter/syntax/operators.ml index 62fe781b8e..e6b39aa313 100644 --- a/interpreter/syntax/operators.ml +++ b/interpreter/syntax/operators.ml @@ -15,6 +15,10 @@ let v128_const n = VecConst (V128 n.it @@ n.at) let ref_null t = RefNull t let ref_func x = RefFunc x +let at_const = function + | I32AT -> fun n -> i32_const (I32_convert.wrap_i64 n.it @@ n.at) + | I64AT -> i64_const + let unreachable = Unreachable let nop = Nop let drop = Drop diff --git a/interpreter/syntax/types.ml b/interpreter/syntax/types.ml index 115e61d81e..be2e05c90e 100644 --- a/interpreter/syntax/types.ml +++ b/interpreter/syntax/types.ml @@ -8,10 +8,11 @@ type null = NoNull | Null type mut = Cons | Var type init = Set | Unset type final = NoFinal | Final -type 'a limits = {min : 'a; max : 'a option} +type limits = {min : int64; max : int64 option} type var = StatX of type_idx | RecX of int32 +type addr_type = I32AT | I64AT type num_type = I32T | I64T | F32T | F64T type vec_type = V128T type heap_type = @@ -47,8 +48,8 @@ and sub_type = SubT of final * heap_type list * str_type and rec_type = RecT of sub_type list and def_type = DefT of rec_type * int32 -type table_type = TableT of Int32.t limits * ref_type -type memory_type = MemoryT of Int32.t limits +type table_type = TableT of addr_type * limits * ref_type +type memory_type = MemoryT of addr_type * limits type global_type = GlobalT of mut * val_type type local_type = LocalT of init * val_type type tag_type = TagT of def_type @@ -113,6 +114,18 @@ let defaultable = function | BotT -> assert false +(* Conversions & Projections *) + +let num_type_of_addr_type = function + | I32AT -> I32T + | I64AT -> I64T + +let addr_type_of_num_type = function + | I32T -> I32AT + | I64T -> I64AT + | _ -> assert false + + (* Filters *) let funcs = List.filter_map (function ExternFuncT ft -> Some ft | _ -> None) @@ -130,6 +143,7 @@ let subst_of dts = function | StatX x -> DefHT (Lib.List32.nth dts x) | RecX i -> VarHT (RecX i) +let subst_addr_type s t = t let subst_num_type s t = t @@ -204,10 +218,10 @@ let subst_def_type s = function let subst_memory_type s = function - | MemoryT lim -> MemoryT lim + | MemoryT (at, lim) -> MemoryT (subst_addr_type s at, lim) let subst_table_type s = function - | TableT (lim, t) -> TableT (lim, subst_ref_type s t) + | TableT (at, lim, t) -> TableT (subst_addr_type s at, lim, subst_ref_type s t) let subst_global_type s = function | GlobalT (mut, t) -> GlobalT (mut, subst_val_type s t) @@ -343,6 +357,9 @@ let string_of_num_type = function | F32T -> "f32" | F64T -> "f64" +let string_of_addr_type at = + string_of_num_type (num_type_of_addr_type at) + let string_of_vec_type = function | V128T -> "v128" @@ -374,7 +391,6 @@ and string_of_val_type = function | RefT t -> string_of_ref_type t | BotT -> "bot" - and string_of_result_type = function | ts -> "[" ^ String.concat " " (List.map string_of_val_type ts) ^ "]" @@ -427,17 +443,16 @@ and string_of_def_type = function | DefT (RecT [st], 0l) -> string_of_sub_type st | DefT (rt, i) -> "(" ^ string_of_rec_type rt ^ ")." ^ I32.to_string_u i - let string_of_limits = function | {min; max} -> - I32.to_string_u min ^ - (match max with None -> "" | Some n -> " " ^ I32.to_string_u n) + I64.to_string_u min ^ + (match max with None -> "" | Some n -> " " ^ I64.to_string_u n) let string_of_memory_type = function - | MemoryT lim -> string_of_limits lim + | MemoryT (at, lim) -> string_of_addr_type at ^ " " ^ string_of_limits lim let string_of_table_type = function - | TableT (lim, t) -> string_of_limits lim ^ " " ^ string_of_ref_type t + | TableT (at, lim, t) -> string_of_addr_type at ^ " " ^ string_of_limits lim ^ " " ^ string_of_ref_type t let string_of_global_type = function | GlobalT (mut, t) -> string_of_mut (string_of_val_type t) mut diff --git a/interpreter/text/arrange.ml b/interpreter/text/arrange.ml index fb3f06dd02..9599265d89 100644 --- a/interpreter/text/arrange.ml +++ b/interpreter/text/arrange.ml @@ -64,6 +64,7 @@ let mutability node = function | Cons -> node | Var -> Node ("mut", [node]) +let addr_type t = string_of_addr_type t let num_type t = string_of_num_type t let vec_type t = string_of_vec_type t let ref_type t = @@ -460,14 +461,13 @@ let vec_splatop = vec_shape_oper (V128Op.splatop, V128Op.splatop, V128Op.splatop let vec_extractop = vec_shape_oper (V128Op.pextractop, V128Op.extractop, V128Op.extractop) let vec_replaceop = vec_shape_oper (V128Op.replaceop, V128Op.replaceop, V128Op.replaceop) - let var x = nat32 x.it let num v = string_of_num v.it let vec v = string_of_vec v.it let memop name x typ {ty; align; offset; _} sz = typ ty ^ "." ^ name ^ " " ^ var x ^ - (if offset = 0l then "" else " offset=" ^ nat32 offset) ^ + (if offset = 0L then "" else " offset=" ^ nat64 offset) ^ (if 1 lsl align = sz then "" else " align=" ^ nat64 (Int64.shift_left 1L align)) let loadop x op = @@ -679,14 +679,14 @@ let tag off i tag = ) let table off i tab = - let {ttype = TableT (lim, t); tinit} = tab.it in - Node ("table $" ^ nat (off + i) ^ " " ^ limits nat32 lim, + let {ttype = TableT (at, lim, t); tinit} = tab.it in + Node ("table $" ^ nat (off + i) ^ " " ^ addr_type at ^ " " ^ limits nat64 lim, atom ref_type t :: list instr tinit.it ) let memory off i mem = - let {mtype = MemoryT lim} = mem.it in - Node ("memory $" ^ nat (off + i) ^ " " ^ limits nat32 lim, []) + let {mtype = MemoryT (at, lim)} = mem.it in + Node ("memory $" ^ nat (off + i) ^ " " ^ addr_type at ^ " " ^ limits nat64 lim, []) let is_elem_kind = function | (NoNull, FuncHT) -> true diff --git a/interpreter/text/parser.mly b/interpreter/text/parser.mly index b6c1ff5f78..c7f400e2ef 100644 --- a/interpreter/text/parser.mly +++ b/interpreter/text/parser.mly @@ -367,6 +367,14 @@ string_list : /* Types */ +%inline addr_type : + | NUM_TYPE + { match $1 with + | I32T -> I32AT + | I64T -> I64AT + | _ -> error (at $sloc) "malformed address type" } + | /* empty */ { I32AT } /* Sugar */ + null_opt : | /* empty */ { NoNull } | NULL { Null } @@ -504,14 +512,14 @@ sub_type : List.map (fun y -> VarHT (StatX y.it)) ($4 c type_), $5 c x) } table_type : - | limits ref_type { fun c -> TableT ($1, $2 c) } + | addr_type limits ref_type { fun c -> TableT ($1, $2, $3 c) } memory_type : - | limits { fun c -> MemoryT $1 } + | addr_type limits { fun c -> MemoryT ($1, $2) } limits : - | NAT { {min = nat32 $1 $loc($1); max = None} } - | NAT NAT { {min = nat32 $1 $loc($1); max = Some (nat32 $2 $loc($2))} } + | NAT { {min = nat64 $1 $loc($1); max = None} } + | NAT NAT { {min = nat64 $1 $loc($1); max = Some (nat64 $2 $loc($2))} } type_use : | LPAR TYPE var RPAR { fun c -> $3 c type_ } @@ -566,10 +574,10 @@ labeling_end_opt : | bind_var { [$1] } offset_ : - | OFFSET_EQ_NAT { nat32 $1 $sloc } + | OFFSET_EQ_NAT { nat64 $1 $sloc } offset_opt : - | /* empty */ { 0l } + | /* empty */ { 0L } | offset_ { $1 } align : @@ -591,7 +599,7 @@ instr_list : | instr1 instr_list { fun c -> $1 c @ $2 c } | select_instr_instr_list { $1 } | call_instr_instr_list { $1 } - | resume_instr_instr { fun c -> let e, es = $1 c in e :: es } + | resume_instr_instr_list { $1 } instr1 : | plain_instr { fun c -> [$1 c @@ $sloc] } @@ -714,10 +722,10 @@ lane_imms : { fun instr at0 c -> instr (0l @@ at0) $2 $1 (vec_lane_index $3 (at $loc($3))) } | align NAT /* Sugar */ - { fun instr at0 c -> instr (0l @@ at0) $1 0l + { fun instr at0 c -> instr (0l @@ at0) $1 0L (vec_lane_index $2 (at $loc($2))) } | NAT /* Sugar */ - { fun instr at0 c -> instr (0l @@ at0) None 0l + { fun instr at0 c -> instr (0l @@ at0) None 0L (vec_lane_index $1 (at $loc($1))) } @@ -769,25 +777,25 @@ call_instr_results_instr_list : | instr_list { fun c -> [], $1 c } -resume_instr_instr : +resume_instr_instr_list : | RESUME var resume_instr_handler_instr { let loc1 = $loc($1) in fun c -> let x = $2 c type_ in - let hs, es = $3 c in resume x hs @@ loc1, es } + let hs, es = $3 c in (resume x hs @@ loc1) :: es } | RESUME_THROW var var resume_instr_handler_instr { let loc1 = $loc($1) in fun c -> let x = $2 c type_ in let tag = $3 c tag in - let hs, es = $4 c in resume_throw x tag hs @@ loc1, es } + let hs, es = $4 c in (resume_throw x tag hs @@ loc1) :: es } resume_instr_handler_instr : | LPAR ON var var RPAR resume_instr_handler_instr { fun c -> let hs, es = $6 c in ($3 c tag, OnLabel ($4 c label)) :: hs, es } | LPAR ON var SWITCH RPAR resume_instr_handler_instr { fun c -> let hs, es = $6 c in ($3 c tag, OnSwitch) :: hs, es } - | instr1 + | instr_list { fun c -> [], $1 c } block_instr : @@ -1189,7 +1197,7 @@ table_fields : | table_type const_expr1 { fun c x loc -> [{ttype = $1 c; tinit = $2 c} @@ loc], [], [], [] } | table_type /* Sugar */ - { fun c x loc -> let TableT (_, (_, ht)) as ttype = $1 c in + { fun c x loc -> let TableT (_, _, (_, ht)) as ttype = $1 c in [{ttype; tinit = [RefNull ht @@ loc] @@ loc} @@ loc], [], [], [] } | inline_import table_type /* Sugar */ { fun c x loc -> @@ -1199,26 +1207,26 @@ table_fields : | inline_export table_fields /* Sugar */ { fun c x loc -> let tabs, elems, ims, exs = $2 c x loc in tabs, elems, ims, $1 (TableExport x) c :: exs } - | ref_type LPAR ELEM elem_expr elem_expr_list RPAR /* Sugar */ + | addr_type ref_type LPAR ELEM elem_expr elem_expr_list RPAR /* Sugar */ { fun c x loc -> - let offset = [i32_const (0l @@ loc) @@ loc] @@ loc in - let einit = $4 c :: $5 c in - let size = Lib.List32.length einit in + let offset = [at_const $1 (0L @@ loc) @@ loc] @@ loc in + let einit = $5 c :: $6 c in + let size = Lib.List64.length einit in let emode = Active {index = x; offset} @@ loc in - let (_, ht) as etype = $1 c in + let (_, ht) as etype = $2 c in let tinit = [RefNull ht @@ loc] @@ loc in - [{ttype = TableT ({min = size; max = Some size}, etype); tinit} @@ loc], + [{ttype = TableT ($1, {min = size; max = Some size}, etype); tinit} @@ loc], [{etype; einit; emode} @@ loc], [], [] } - | ref_type LPAR ELEM elem_var_list RPAR /* Sugar */ + | addr_type ref_type LPAR ELEM elem_var_list RPAR /* Sugar */ { fun c x loc -> - let offset = [i32_const (0l @@ loc) @@ loc] @@ loc in - let einit = $4 c in - let size = Lib.List32.length einit in - let emode = Active {index = x; offset} @@ loc in - let (_, ht) as etype = $1 c in + let (_, ht) as etype = $2 c in let tinit = [RefNull ht @@ loc] @@ loc in - [{ttype = TableT ({min = size; max = Some size}, etype); tinit} @@ loc], + let offset = [at_const $1 (0L @@ loc) @@ loc] @@ loc in + let einit = $5 c in + let size = Lib.List64.length einit in + let emode = Active {index = x; offset} @@ loc in + [{ttype = TableT ($1, {min = size; max = Some size}, etype); tinit} @@ loc], [{etype; einit; emode} @@ loc], [], [] } @@ -1251,12 +1259,12 @@ memory_fields : | inline_export memory_fields /* Sugar */ { fun c x loc -> let mems, data, ims, exs = $2 c x loc in mems, data, ims, $1 (MemoryExport x) c :: exs } - | LPAR DATA string_list RPAR /* Sugar */ + | addr_type LPAR DATA string_list RPAR /* Sugar */ { fun c x loc -> - let offset = [i32_const (0l @@ loc) @@ loc] @@ loc in - let size = Int32.(div (add (of_int (String.length $3)) 65535l) 65536l) in - [{mtype = MemoryT {min = size; max = Some size}} @@ loc], - [{dinit = $3; dmode = Active {index = x; offset} @@ loc} @@ loc], + let size = Int64.(div (add (of_int (String.length $4)) 65535L) 65536L) in + let offset = [at_const $1 (0L @@ loc) @@ loc] @@ loc in + [{mtype = MemoryT ($1, {min = size; max = Some size})} @@ loc], + [{dinit = $4; dmode = Active {index = x; offset} @@ loc} @@ loc], [], [] } tag : diff --git a/interpreter/util/lib.ml b/interpreter/util/lib.ml index db180230f8..2068e3bc3a 100644 --- a/interpreter/util/lib.ml +++ b/interpreter/util/lib.ml @@ -182,23 +182,64 @@ struct let index_of x = index_where ((=) x) end -module Array32 = +module List64 = +struct + let rec init n f = init' n f [] + and init' n f xs = + if n = 0L then xs else init' (Int64.sub n 1L) f (f (Int64.sub n 1L) :: xs) + + let rec make n x = make' n x [] + and make' n x xs = + if n = 0L then xs else make' (Int64.sub n 1L) x (x::xs) + + let rec length xs = length' xs 0L + and length' xs n = + match xs with + | [] -> n + | _::xs' when n < Int64.max_int -> length' xs' (Int64.add n 1L) + | _ -> failwith "length" + + let rec nth xs n = + match n, xs with + | 0L, x::_ -> x + | n, _::xs' when n > 0L -> nth xs' (Int64.sub n 1L) + | _ -> failwith "nth" + + let rec take n xs = + match n, xs with + | 0L, _ -> [] + | n, x::xs' when n > 0L -> x :: take (Int64.sub n 1L) xs' + | _ -> failwith "take" + + let rec drop n xs = + match n, xs with + | 0L, _ -> xs + | n, _::xs' when n > 0L -> drop (Int64.sub n 1L) xs' + | _ -> failwith "drop" + + let rec mapi f xs = mapi' f 0L xs + and mapi' f i = function + | [] -> [] + | x::xs -> f i x :: mapi' f (Int64.add i 1L) xs +end + +module Array64 = struct let make n x = - if n < 0l || Int64.of_int32 n > Int64.of_int max_int then - invalid_arg "Array32.make"; - Array.make (Int32.to_int n) x + if n < 0L || n > Int64.of_int max_int then + invalid_arg "Array64.make"; + Array.make (Int64.to_int n) x - let length a = Int32.of_int (Array.length a) + let length a = Int64.of_int (Array.length a) - let index_of_int32 i = - if i < 0l || Int64.of_int32 i > Int64.of_int max_int then -1 else - Int32.to_int i + let index_of_int64 i = + if i < 0L || i > Int64.of_int max_int then -1 else + Int64.to_int i - let get a i = Array.get a (index_of_int32 i) - let set a i x = Array.set a (index_of_int32 i) x + let get a i = Array.get a (index_of_int64 i) + let set a i x = Array.set a (index_of_int64 i) x let blit a1 i1 a2 i2 n = - Array.blit a1 (index_of_int32 i1) a2 (index_of_int32 i2) (index_of_int32 n) + Array.blit a1 (index_of_int64 i1) a2 (index_of_int64 i2) (index_of_int64 n) end module Bigarray = diff --git a/interpreter/util/lib.mli b/interpreter/util/lib.mli index e641bdfb40..5044428af7 100644 --- a/interpreter/util/lib.mli +++ b/interpreter/util/lib.mli @@ -47,13 +47,24 @@ sig val index_where : ('a -> bool) -> 'a list -> int32 option end -module Array32 : +module List64 : sig - val make : int32 -> 'a -> 'a array - val length : 'a array -> int32 - val get : 'a array -> int32 -> 'a - val set : 'a array -> int32 -> 'a -> unit - val blit : 'a array -> int32 -> 'a array -> int32 -> int32 -> unit + val init : int64 -> (int64 -> 'a) -> 'a list + val make : int64 -> 'a -> 'a list + val length : 'a list -> int64 + val nth : 'a list -> int64 -> 'a (* raises Failure *) + val take : int64 -> 'a list -> 'a list (* raises Failure *) + val drop : int64 -> 'a list -> 'a list (* raises Failure *) + val mapi : (int64 -> 'a -> 'b) -> 'a list -> 'b list +end + +module Array64 : +sig + val make : int64 -> 'a -> 'a array + val length : 'a array -> int64 + val get : 'a array -> int64 -> 'a + val set : 'a array -> int64 -> 'a -> unit + val blit : 'a array -> int64 -> 'a array -> int64 -> int64 -> unit end module Bigarray : diff --git a/interpreter/valid/match.ml b/interpreter/valid/match.ml index b14820c961..1e8d72e3cc 100644 --- a/interpreter/valid/match.ml +++ b/interpreter/valid/match.ml @@ -56,11 +56,11 @@ let match_null _c nul1 nul2 = | _, _ -> nul1 = nul2 let match_limits _c lim1 lim2 = - I32.ge_u lim1.min lim2.min && + I64.ge_u lim1.min lim2.min && match lim1.max, lim2.max with | _, None -> true | None, Some _ -> false - | Some i, Some j -> I32.le_u i j + | Some i, Some j -> I64.le_u i j let match_num_type _c t1 t2 = @@ -171,11 +171,12 @@ let match_global_type c (GlobalT (mut1, t1)) (GlobalT (mut2, t2)) = let match_tag_type c (TagT dt1) (TagT dt2) = match_def_type c dt1 dt2 -let match_table_type c (TableT (lim1, t1)) (TableT (lim2, t2)) = - match_limits c lim1 lim2 && match_ref_type c t1 t2 && match_ref_type c t2 t1 +let match_table_type c (TableT (at1, lim1, t1)) (TableT (at2, lim2, t2)) = + at1 = at2 && match_limits c lim1 lim2 && + match_ref_type c t1 t2 && match_ref_type c t2 t1 -let match_memory_type c (MemoryT lim1) (MemoryT lim2) = - match_limits c lim1 lim2 +let match_memory_type c (MemoryT (at1, lim1)) (MemoryT (at2, lim2)) = + at1 = at2 && match_limits c lim1 lim2 let match_extern_type c et1 et2 = match et1, et2 with diff --git a/interpreter/valid/valid.ml b/interpreter/valid/valid.ml index fdeef4e59b..90bf74a091 100644 --- a/interpreter/valid/valid.ml +++ b/interpreter/valid/valid.ml @@ -117,12 +117,12 @@ let func_type_of_tag_type (c : context) (TagT dt) at : func_type = (* Types *) let check_limits {min; max} range at msg = - require (I32.le_u min range) at msg; + require (I64.le_u min range) at msg; match max with | None -> () | Some max -> - require (I32.le_u max range) at msg; - require (I32.le_u min max) at + require (I64.le_u max range) at msg; + require (I64.le_u min max) at "size minimum must not be greater than maximum" let check_num_type (c : context) (t : num_type) at = @@ -185,14 +185,23 @@ let check_cont_type (c : context) (ct : cont_type) at = | _ -> assert false let check_table_type (c : context) (tt : table_type) at = - let TableT (lim, t) = tt in - check_limits lim 0xffff_ffffl at "table size must be at most 2^32-1"; - check_ref_type c t at + let TableT (at_, lim, t) = tt in + check_ref_type c t at; + let sz, s = + match at_ with + | I32AT -> 0xffff_ffffL, "2^32-1 for i32" + | I64AT -> 0xffff_ffff_ffff_ffffL, "2^64-1 for i64" + in + check_limits lim sz at ("table size must be at most " ^ s) let check_memory_type (c : context) (mt : memory_type) at = - let MemoryT lim = mt in - check_limits lim 0x1_0000l at - "memory size must be at most 65536 pages (4GiB)" + let MemoryT (at_, lim) = mt in + let sz, s = + match at_ with + | I32AT -> 0x1_0000L, "2^16 pages (4 GiB) for i32" + | I64AT -> 0x1_0000_0000_0000L, "2^48 pages (256 TiB) for i64" + in + check_limits lim sz at ("memory size must be at most " ^ s) let check_tag_type (c : context) (et : tag_type) at = match et with @@ -398,6 +407,10 @@ let check_memop (c : context) (memop : ('t, 's) memop) ty_size get_sz at = in require (1 lsl memop.align >= 1 && 1 lsl memop.align <= size) at "alignment must not be larger than natural"; + let MemoryT (at_, _lim) = memory c (0l @@ at) in + if at_ = I32AT then + require (I64.lt_u memop.offset 0x1_0000_0000L) at + "offset out of range"; memop.ty @@ -569,12 +582,12 @@ let rec check_instr (c : context) (e : instr) (s : infer_result_type) : infer_in (ts1 @ [RefT (Null, DefHT (type_ c x))]) --> ts2, [] | CallIndirect (x, y) -> - let TableT (lim, t) = table c x in + let TableT (at, _lim, t) = table c x in let FuncT (ts1, ts2) = func_type c y in require (match_ref_type c.types t (Null, FuncHT)) x.at ("type mismatch: instruction requires table of function type" ^ " but table has element type " ^ string_of_ref_type t); - (ts1 @ [NumT I32T]) --> ts2, [] + (ts1 @ [NumT (num_type_of_addr_type at)]) --> ts2, [] | ReturnCall x -> let FuncT (ts1, ts2) = as_func_str_type (expand_def_type (func c x)) in @@ -593,13 +606,13 @@ let rec check_instr (c : context) (e : instr) (s : infer_result_type) : infer_in (ts1 @ [RefT (Null, DefHT (type_ c x))]) -->... [], [] | ReturnCallIndirect (x, y) -> - let TableT (_lim, t) = table c x in + let TableT (at, _lim, t) = table c x in let FuncT (ts1, ts2) = func_type c y in require (match_result_type c.types ts2 c.results) e.at ("type mismatch: current function requires result type " ^ string_of_result_type c.results ^ " but callee returns " ^ string_of_result_type ts2); - (ts1 @ [NumT I32T]) -->... [], [] + (ts1 @ [NumT (num_type_of_addr_type at)]) -->... [], [] | ContNew x -> let ContT ht = cont_type c x in @@ -651,14 +664,15 @@ let rec check_instr (c : context) (e : instr) (s : infer_result_type) : infer_in " but the type annotation has " ^ string_of_result_type ts11) in let et = tag c y in - let FuncT (_, t) as ft = func_type_of_tag_type c et y.at in - require (match_func_type c.types (FuncT ([], t)) ft) y.at + let FuncT (ts31, t) = func_type_of_tag_type c et y.at in + require (ts31 = []) y.at "type mismatch in switch tag"; require (match_result_type c.types ts12 t) y.at "type mismatch in continuation types"; require (match_result_type c.types t ts22) y.at "type mismatch in continuation types"; - ts11 --> ts21, [] + let ts11' = Lib.List.lead ts11 in + (ts11' @ [RefT (Null, VarHT (StatX x.it))]) --> ts21, [] | Throw x -> let FuncT (ts1, ts2) = func_type_of_tag_type c (tag c x) x.at in @@ -697,100 +711,105 @@ let rec check_instr (c : context) (e : instr) (s : infer_result_type) : infer_in [t] --> [], [] | TableGet x -> - let TableT (_lim, rt) = table c x in - [NumT I32T] --> [RefT rt], [] + let TableT (at, _lim, rt) = table c x in + [NumT (num_type_of_addr_type at)] --> [RefT rt], [] | TableSet x -> - let TableT (_lim, rt) = table c x in - [NumT I32T; RefT rt] --> [], [] + let TableT (at, _lim, rt) = table c x in + [NumT (num_type_of_addr_type at); RefT rt] --> [], [] | TableSize x -> - let _tt = table c x in - [] --> [NumT I32T], [] + let TableT (at, _lim, _rt) = table c x in + [] --> [NumT (num_type_of_addr_type at)], [] | TableGrow x -> - let TableT (_lim, rt) = table c x in - [RefT rt; NumT I32T] --> [NumT I32T], [] + let TableT (at, _lim, rt) = table c x in + [RefT rt; NumT (num_type_of_addr_type at)] --> + [NumT (num_type_of_addr_type at)], [] | TableFill x -> - let TableT (_lim, rt) = table c x in - [NumT I32T; RefT rt; NumT I32T] --> [], [] + let TableT (at, _lim, rt) = table c x in + [NumT (num_type_of_addr_type at); RefT rt; + NumT (num_type_of_addr_type at)] --> [], [] | TableCopy (x, y) -> - let TableT (_lim1, t1) = table c x in - let TableT (_lim2, t2) = table c y in + let TableT (at1, _lim1, t1) = table c x in + let TableT (at2, _lim2, t2) = table c y in require (match_ref_type c.types t2 t1) x.at ("type mismatch: source element type " ^ string_of_ref_type t1 ^ " does not match destination element type " ^ string_of_ref_type t2); - [NumT I32T; NumT I32T; NumT I32T] --> [], [] + [NumT (num_type_of_addr_type at1); NumT (num_type_of_addr_type at2); + NumT (num_type_of_addr_type (min at1 at2))] --> [], [] | TableInit (x, y) -> - let TableT (_lim1, t1) = table c x in + let TableT (at, _lim1, t1) = table c x in let t2 = elem c y in require (match_ref_type c.types t2 t1) x.at ("type mismatch: element segment's type " ^ string_of_ref_type t1 ^ " does not match table's element type " ^ string_of_ref_type t2); - [NumT I32T; NumT I32T; NumT I32T] --> [], [] + [NumT (num_type_of_addr_type at); NumT I32T; NumT I32T] --> [], [] | ElemDrop x -> ignore (elem c x); [] --> [], [] | Load (x, memop) -> - let _mt = memory c x in + let MemoryT (at, _lim) = memory c x in let t = check_memop c memop num_size (Lib.Option.map fst) e.at in - [NumT I32T] --> [NumT t], [] + [NumT (num_type_of_addr_type at)] --> [NumT t], [] | Store (x, memop) -> - let _mt = memory c x in + let MemoryT (at, _lim) = memory c x in let t = check_memop c memop num_size (fun sz -> sz) e.at in - [NumT I32T; NumT t] --> [], [] + [NumT (num_type_of_addr_type at); NumT t] --> [], [] | VecLoad (x, memop) -> - let _mt = memory c x in + let MemoryT (at, _lim) = memory c x in let t = check_memop c memop vec_size (Lib.Option.map fst) e.at in - [NumT I32T] --> [VecT t], [] + [NumT (num_type_of_addr_type at)] --> [VecT t], [] | VecStore (x, memop) -> - let _mt = memory c x in + let MemoryT (at, _lim) = memory c x in let t = check_memop c memop vec_size (fun _ -> None) e.at in - [NumT I32T; VecT t] --> [], [] + [NumT (num_type_of_addr_type at); VecT t] --> [], [] | VecLoadLane (x, memop, i) -> - let _mt = memory c x in + let MemoryT (at, _lim) = memory c x in let t = check_memop c memop vec_size (fun sz -> Some sz) e.at in require (i < vec_size t / Pack.packed_size memop.pack) e.at "invalid lane index"; - [NumT I32T; VecT t] --> [VecT t], [] + [NumT (num_type_of_addr_type at); VecT t] --> [VecT t], [] | VecStoreLane (x, memop, i) -> - let _mt = memory c x in + let MemoryT (at, _lim) = memory c x in let t = check_memop c memop vec_size (fun sz -> Some sz) e.at in require (i < vec_size t / Pack.packed_size memop.pack) e.at "invalid lane index"; - [NumT I32T; VecT t] --> [], [] + [NumT (num_type_of_addr_type at); VecT t] --> [], [] | MemorySize x -> - let _mt = memory c x in - [] --> [NumT I32T], [] + let MemoryT (at, _lim) = memory c x in + [] --> [NumT (num_type_of_addr_type at)], [] | MemoryGrow x -> - let _mt = memory c x in - [NumT I32T] --> [NumT I32T], [] + let MemoryT (at, _lim) = memory c x in + [NumT (num_type_of_addr_type at)] --> [NumT (num_type_of_addr_type at)], [] | MemoryFill x -> - let _mt = memory c x in - [NumT I32T; NumT I32T; NumT I32T] --> [], [] + let MemoryT (at, _lim) = memory c x in + [NumT (num_type_of_addr_type at); NumT I32T; + NumT (num_type_of_addr_type at)] --> [], [] | MemoryCopy (x, y)-> - let _mt = memory c x in - let _mt = memory c y in - [NumT I32T; NumT I32T; NumT I32T] --> [], [] + let MemoryT (at1, _lib1) = memory c x in + let MemoryT (at2, _lib2) = memory c y in + [NumT (num_type_of_addr_type at1); NumT (num_type_of_addr_type at2); + NumT (num_type_of_addr_type (min at1 at2))] --> [], [] | MemoryInit (x, y) -> - let _mt = memory c x in + let MemoryT (at, _lib) = memory c x in let () = data c y in - [NumT I32T; NumT I32T; NumT I32T] --> [], [] + [NumT (num_type_of_addr_type at); NumT I32T; NumT I32T] --> [], [] | DataDrop x -> let () = data c x in @@ -1135,7 +1154,7 @@ let check_global (c : context) (glob : global) : context = let check_table (c : context) (tab : table) : context = let {ttype; tinit} = tab.it in - let TableT (_lim, rt) = ttype in + let TableT (_at, _lim, rt) = ttype in check_table_type c ttype tab.at; check_const c tinit (RefT rt); {c with tables = c.tables @ [ttype]} @@ -1149,11 +1168,11 @@ let check_elem_mode (c : context) (t : ref_type) (mode : segment_mode) = match mode.it with | Passive -> () | Active {index; offset} -> - let TableT (_lim, et) = table c index in + let TableT (at, _lim, et) = table c index in require (match_ref_type c.types t et) mode.at ("type mismatch: element segment's type " ^ string_of_ref_type t ^ " does not match table's element type " ^ string_of_ref_type et); - check_const c offset (NumT I32T) + check_const c offset (NumT (num_type_of_addr_type at)) | Declarative -> () let check_elem (c : context) (seg : elem_segment) : context = @@ -1167,8 +1186,8 @@ let check_data_mode (c : context) (mode : segment_mode) = match mode.it with | Passive -> () | Active {index; offset} -> - let _mt = memory c index in - check_const c offset (NumT I32T) + let MemoryT (at, _) = memory c index in + check_const c offset (NumT (num_type_of_addr_type at)) | Declarative -> assert false let check_data (c : context) (seg : data_segment) : context = diff --git a/proposals/memory64/Overview.md b/proposals/memory64/Overview.md new file mode 100644 index 0000000000..3e947b5829 --- /dev/null +++ b/proposals/memory64/Overview.md @@ -0,0 +1,402 @@ +# Memory64 + +## Summary + +This page describes a proposal to support linear memory of sizes larger than +232 bits. It provides no new instructions, but instead extends the +currently existing instructions to allow 64-bit indexes. + +In addition, in order to support source languages with 64-bit pointer width, +this proposal also extends tables to allow 64-bit indexes. This addition was +made during phase 3 of the proposal and we refer to this addition as "table64". + +### Implementation Status + +- spec interpreter: Done +- v8/chrome: [Done](https://chromium-review.googlesource.com/c/v8/v8/+/2679683) +- Firefox: Done +- Safari: ? +- wabt: [Done](https://github.com/WebAssembly/wabt/pull/1500) +- binaryen: [Done](https://github.com/WebAssembly/binaryen/pull/3202) +- emscripten: [Done](https://github.com/emscripten-core/emscripten/pull/17803) + +### Implementation Status (table64) + +- spec interpreter: [Done](https://github.com/WebAssembly/table64/53) +- v8/chrome: [WIP](https://issues.chromium.org/issues/338024338) +- Firefox: [WIP](https://bugzilla.mozilla.org/show_bug.cgi?id=1893643) +- Safari: - +- wabt: Done +- binaryen: Done +- emscripten: Done + +## Motivation + +[WebAssembly linear memory objects][memory object] have sizes measured in +[pages][memory page]. Each page is 65536 (216) bytes. In WebAssembly +version 1, a linear memory can have at most 65536 pages, for a total of +232 bytes (4 [gibibytes][gibibyte]). + +In addition to this page limit, all [memory instructions][] currently use the +[`i32` type][i32] as a memory index. This means they can address at most +232 bytes as well. + +For many applications, 4 gibibytes of memory is enough. Using 32-bit memory +indexes is sufficient in this case, and has the additional benefit that +pointers in the producer language are smaller, which can yield memory savings. +However, for applications that need more memory than this, there are no easy +workarounds given the current WebAssembly feature set. Allowing the WebAssembly +module to choose between 32-bit and 64-bit memory indexes addresses both +concerns. + +Similarly, since WebAssembly is a Virtual [Instruction Set Architecture][ISA] +(ISA), some hosts may want to use the WebAssembly binary format as a portable +executable format, in addition to supporting other non-virtual ISAs. Nearly all +ISAs have support for 64-bit memory addresses now, and a host may not want to +have to support 32-bit memory addresses in their ABI. + +## Overview + +### Structure + +* The [limits][syntax limits] structure is changed to use `u64` + - `limits ::= {min u64, max u64?}` + +* A new `addrtype` can be either `i32` or `i64` + - `addrtype ::= i32 | i64` + +* The [memory type][syntax memtype] and [table type][syntax tabletype] + structures are extended to include an address type + - `memtype ::= addrtype limits` + - `tabletype ::= addrtype limits reftype` + +* The [memarg][syntax memarg] immediate is changed to allow a 64-bit offset + - `memarg ::= {offset u64, align u32}` + +### Validation + +* Address types are classified by their value range: + - ``` + ---------------- + ⊦ i32 : 2**16 + ``` + - ``` + ---------------- + ⊦ i64 : 2**48 + ``` + +* [Memory page limits][valid limits] and [Table entry limits][valid limits] are + classified by their respective address types + - ``` + ⊦ it : k n <= k (m <= k)? (n < m)? + ------------------------------------------- + ⊦ { min n, max m? } : it + ``` + +* Memory and Table types are validated accordingly: + - ``` + ⊦ limits : it + -------------- + ⊦ it limits ok + ``` + +* All [memory instructions][valid meminst] are changed to use the address type, + and the offset must also be in range of the address type + - t.load memarg + - ``` + C.mems[0] = at limits 2**memarg.align <= |t|/8 memarg.offset < 2**|at| + -------------------------------------------------------------------------- + C ⊦ t.load memarg : [at] → [t] + ``` + - t.loadN_sx memarg + - ``` + C.mems[0] = at limits 2**memarg.align <= N/8 memarg.offset < 2**|at| + ------------------------------------------------------------------------ + C ⊦ t.loadN_sx memarg : [at] → [t] + ``` + - t.store memarg + - ``` + C.mems[0] = at limits 2**memarg.align <= |t|/8 memarg.offset < 2**|at| + -------------------------------------------------------------------------- + C ⊦ t.store memarg : [at t] → [] + ``` + - t.storeN_sx memarg + - ``` + C.mems[0] = at limits 2**memarg.align <= N/8 memarg.offset < 2**|t| + ------------------------------------------------------------------------ + C ⊦ t.storeN_sx memarg : [at t] → [] + ``` + - memory.size + - ``` + C.mems[0] = at limits + --------------------------- + C ⊦ memory.size : [] → [at] + ``` + - memory.grow + - ``` + C.mems[0] = at limits + ----------------------------- + C ⊦ memory.grow : [at] → [at] + ``` + - memory.fill + - ``` + C.mems[0] = at limits + ----------------------------- + C ⊦ memory.fill : [at i32 at] → [] + ``` + - memory.copy + - ``` + C.mems[0] = at limits + ----------------------------- + C ⊦ memory.copy : [at at at] → [] + ``` + - memory.init x + - ``` + C.mems[0] = at limits C.datas[x] = ok + ------------------------------------------- + C ⊦ memory.init : [at i32 i32] → [] + ``` + - (and similar for memory instructions from other proposals) + +* [Table instructions][valid tableinst] are changed to use the address type + - call_indirect x y + - ``` + C.tables[x] = at limits t C.types[y] = [t1*] → [t2*] + ------------------------------------------------------- + C ⊦ call_indirect x y : [t1* at] → [t2*] + ``` + - table.get x + - ``` + C.tables[x] = at limits t + ------------------------------ + C ⊦ table.get x : [at] → [t] + ``` + - table.set x + - ``` + C.tables[x] = at limits t + ------------------------------ + C ⊦ table.set x : [at t] → [] + ``` + - table.size x + - ``` + C.tables[x] = at limits t + ------------------------------ + C ⊦ table.size x : [] → [at] + ``` + - table.grow x + - ``` + C.tables[x] = at limits t + ------------------------------- + C ⊦ table.grow x : [t at] → [at] + ``` + - table.fill x + - ``` + C.tables[x] = at limits t + ---------------------------------- + C ⊦ tables.fill x : [at t at] → [] + ``` + - table.copy x y + - ``` + C.tables[d] = aN limits t C.tables[s] = aM limits t K = min {aN, AM} + ----------------------------------------------------------------------------- + C ⊦ table.copy d s : [aN aM aK] → [] + ``` + - table.init x y + - ``` + C.tables[x] = at limits t C.elems[y] = ok + ----------------------------------------------- + C ⊦ table.init x y : [at i32 i32] → [] + ``` + +* The [SIMD proposal][simd] extends `t.load memarg` and `t.store memarg` + above such that `t` may now also be `v128`, which accesses a 16-byte quantity + in memory that is also 16-byte aligned. + + In addition to this, it also has these SIMD specific memory operations (see + [SIMD proposal][simd] for full semantics): + - `v128.loadN_zero memarg` (where N = 32/64): + Load a single 32-bit or 64-bit element into the lowest bits of a `v128` + vector, and initialize all other bits of the `v128` vector to zero. + - `v128.loadN_splat memarg` (where N = 8/16/32/64): + Load a single element and splat to all lanes of a `v128` vector. The natural + alignment is the size of the element loaded. + - `v128.loadN_lane memarg v128 immlaneidx` (where N = 8/16/32/64): + Load a single element from `memarg` into the lane of the `v128` specified in + the immediate mode operand `immlaneidx`. The values of all other lanes of + the `v128` are bypassed as is. + - `v128.storeN_lane memarg v128 immlaneidx` (where N = 8/16/32/64): + Store into `memarg` the lane of `v128` specified in the immediate mode + operand `immlaneidx`. + - `v128.loadL_sx memarg` (where L is `8x8`/`16x4`/`32x2`, and sx is `s`/`u`): + Fetch consecutive integers up to 32-bit wide and produce a vector with lanes + up to 64 bits. The natural alignment is 8 bytes. + + All these operations now take 64-bit address operands when used with a + 64-bit memory. + +* The [Threads proposal][threads] has `atomic` versions of `t.load`, `t.store`, + (and `t.loadN_u` / `t.storeN_u`, no sign-extend) specified above, except with + `.` replaced by `.atomic.`, and the guarantee of ordering of accesses being + sequentially consistent. + + In addition to this, it has the following memory operations (see + [Threads proposal][threads] for full semantics): + - `t.atomic.rmwN.op_u memarg` (where t = 32/64, N = 8/16/32 when < t or empty + otherwise, op is `add`/`sub`/`and`/`or`/`xor`/`xchg`/`cmpxchg`, and `_u` + only present when N is not empty): + The first 6 operations atomically read a value from an address, modify the + value, and store the resulting value to the same address. They then return + the value read from memory before the modify operation was performed. + In the case of `cmpxchg`, the operands are an address, an expected value, + and a replacement value. If the loaded value is equal to the expected value, + the replacement value is stored to the same memory address. If the values + are not equal, no value is stored. In either case, the loaded value is + returned. + - `memory.atomic.waitN` (where N = 32/64): + The wait operator take three operands: an address operand, an expected + value, and a relative timeout in nanoseconds as an `i64`. The return value + is `0`, `1`, or `2`, returned as an `i32`. + - `memory.atomic.notify`: + The notify operator takes two operands: an address operand and a count as an + unsigned `i32`. The operation will notify as many waiters as are waiting on + the same effective address, up to the maximum as specified by count. The + operator returns the number of waiters that were woken as an unsigned `i32`. + + All these operations now take 64-bit address operands when used with a + 64-bit memory. + +* The [Multi-memory proposal][multi memory] extends each of these instructions + with one or two memory index immediates. The address type for that memory will + be used. For example, + - memory.size x + - ``` + C.mems[x] = at limits + --------------------------- + C ⊦ memory.size x : [] → [at] + ``` + + `memory.copy` has two memory index immediates, so will have multiple possible + signatures: + - memory.copy d s + - ``` + C.mems[d] = aN limits C.mems[s] = aM limits K = min {aN, aM} + --------------------------------------------------------------- + C ⊦ memory.copy d s : [aN aM aK] → [] + ``` + +* [Data segment validation][valid data] uses the address type + - ``` + C.mems[0] = at limits C ⊦ expr: [at] C ⊦ expr const + ------------------------------------------------------- + C ⊦ {data x, offset expr, init b*} ok + ``` + + +### Execution + +* [Memory instances][exec mem] are extended to have 64-bit vectors and a `u64` + max size + - `meminst ::= { data vec64(byte), max u64? }` + +* [Memory instructions][exec meminst] use the address type instead of `i32` + - `t.load memarg` + - `t.loadN_sx memarg` + - `t.store memarg` + - `t.storeN memarg` + - `memory.size` + - `memory.grow` + - (spec text omitted) + +* [memory.grow][exec memgrow] has behavior that depends on the address type: + - for `i32`: no change + - for `i64`: check for a size greater than 264 - 1, and return + 264 - 1 when `memory.grow` fails. + +* [Memory import matching][exec memmatch] requires that the address type matches + - ``` + at_1 = at_2 ⊦ limits_1 <= limits_2 + ---------------------------------------- + ⊦ mem at_1 limits_1 <= mem at_2 limits_2 + ``` + +* Bounds checking is required to be the same as for 32-bit memories, that is, + the address + offset (a `u65`) of a load or store operation is required to be + checked against the current memory size and trap if out of range. + + It is expected that the cost of this check remains low, if an implementation + can implement the address check with a branch, and the offset separately using a + guard page for all smaller offsets. Repeated accesses over the same address and + different offsets allow simple elimination of subsequent checks. + +### Binary format + +* The [limits][binary limits] structure also encodes an additional value to + indicate the address type + - ``` + limits ::= 0x00 n:u32 ⇒ i32, {min n, max ϵ}, 0 + | 0x01 n:u32 m:u32 ⇒ i32, {min n, max m}, 0 + | 0x02 n:u32 ⇒ i32, {min n, max ϵ}, 1 ;; from threads proposal + | 0x03 n:u32 m:u32 ⇒ i32, {min n, max m}, 1 ;; from threads proposal + | 0x04 n:u64 ⇒ i64, {min n, max ϵ}, 0 + | 0x05 n:u64 m:u64 ⇒ i64, {min n, max m}, 0 + | 0x06 n:u64 ⇒ i64, {min n, max ϵ}, 1 ;; from threads proposal + | 0x07 n:u64 m:u64 ⇒ i64, {min n, max m}, 1 ;; from threads proposal + ``` + +* The [memory type][binary memtype] structure is extended to use this limits + encoding + - ``` + memtype ::= (at, lim, _):limits ⇒ at lim + ``` + +* The [memarg][binary memarg]'s offset is read as `u64` + - `memarg ::= a:u32 o:u64` + +### Text format + +* There is a new address type: + - ``` + addrtype ::= 'i32' ⇒ i32 + | 'i64' ⇒ i64 + ``` + +* The [memory type][text memtype] definition is extended to allow an optional + address type, which must be either `i32` or `i64` + - ``` + memtype ::= lim:limits ⇒ i32 lim + | at:addrtype lim:limits ⇒ at lim + ``` + +* The [memory abbreviation][text memabbrev] definition is extended to allow an + optional address type too, which must be either `i32` or `i64` + - ``` + '(' 'memory' id? address_type? '(' 'data' b_n:datastring ')' ')' === ... + ``` + + +[memory object]: https://webassembly.github.io/spec/core/syntax/modules.html#memories +[memory page]: https://webassembly.github.io/spec/core/exec/runtime.html#page-size +[gibibyte]: https://en.wikipedia.org/wiki/Gibibyte +[i32]: https://webassembly.github.io/spec/core/syntax/types.html#syntax-valtype +[memory instructions]: https://webassembly.github.io/spec/core/syntax/instructions.html#memory-instructions +[ISA]: https://en.wikipedia.org/wiki/Instruction_set_architecture +[syntax limits]: https://webassembly.github.io/spec/core/syntax/types.html#syntax-limits +[syntax tabletype]: https://webassembly.github.io/spec/core/syntax/types.html#table-types +[syntax memtype]: https://webassembly.github.io/spec/core/syntax/types.html#memory-types +[syntax memarg]: https://webassembly.github.io/spec/core/syntax/instructions.html#syntax-memarg +[valid limits]: https://webassembly.github.io/spec/core/valid/types.html#limits +[valid meminst]: https://webassembly.github.io/spec/core/valid/instructions.html#memory-instructions +[valid tableinst]: https://webassembly.github.io/spec/core/valid/instructions.html#table-instructions +[valid data]: https://webassembly.github.io/spec/core/valid/modules.html#data-segments +[exec mem]: https://webassembly.github.io/spec/core/exec/runtime.html#memory-instances +[exec meminst]: https://webassembly.github.io/spec/core/exec/instructions.html#memory-instructions +[exec memgrow]: https://webassembly.github.io/spec/core/exec/instructions.html#exec-memory-grow +[exec memmatch]: https://webassembly.github.io/spec/core/exec/modules.html#memories +[binary limits]: https://webassembly.github.io/spec/core/binary/types.html#limits +[binary memtype]: https://webassembly.github.io/spec/core/binary/types.html#memory-types +[binary memarg]: https://webassembly.github.io/spec/core/binary/instructions.html#binary-memarg +[text memtype]: https://webassembly.github.io/spec/core/text/types.html#text-memtype +[text memabbrev]: https://webassembly.github.io/spec/core/text/modules.html#text-mem-abbrev +[multi memory]: https://github.com/webassembly/multi-memory +[simd]: https://github.com/webassembly/simd +[threads]: https://github.com/webassembly/threads diff --git a/proposals/stack-switching/Explainer.md b/proposals/stack-switching/Explainer.md index 5915ad2b5d..152aef33da 100644 --- a/proposals/stack-switching/Explainer.md +++ b/proposals/stack-switching/Explainer.md @@ -842,7 +842,7 @@ We extend the binary format of composite types, heap types, and instructions. | Opcode | Type | Parameters | Note | | ------ | --------------- | ---------- |------| | -0x20 | `func t1* t2*` | `t1* : vec(valtype)` `t2* : vec(valtype)` | from Wasm 1.0 | -| -0x23 | `cont $ft` | `$ft : typeidx` | new | +| -0x23 | `cont $ft` | `$ft : s33` | new | #### Heap Types diff --git a/proposals/bag-o-stacks/Explainer.md b/proposals/stack-switching/design-notes/bag-o-stacks/Explainer.md similarity index 100% rename from proposals/bag-o-stacks/Explainer.md rename to proposals/stack-switching/design-notes/bag-o-stacks/Explainer.md diff --git a/proposals/continuations/Explainer.md b/proposals/stack-switching/design-notes/continuations/Explainer.md similarity index 100% rename from proposals/continuations/Explainer.md rename to proposals/stack-switching/design-notes/continuations/Explainer.md diff --git a/proposals/continuations/Overview.md b/proposals/stack-switching/design-notes/continuations/Overview.md similarity index 100% rename from proposals/continuations/Overview.md rename to proposals/stack-switching/design-notes/continuations/Overview.md diff --git a/proposals/stack-switching-requirements/requirements.md b/proposals/stack-switching/design-notes/requirements.md similarity index 100% rename from proposals/stack-switching-requirements/requirements.md rename to proposals/stack-switching/design-notes/requirements.md diff --git a/proposals/continuations/examples/actor-lwt.wast b/proposals/stack-switching/examples/actor-lwt.wast similarity index 100% rename from proposals/continuations/examples/actor-lwt.wast rename to proposals/stack-switching/examples/actor-lwt.wast diff --git a/proposals/continuations/examples/actor.wast b/proposals/stack-switching/examples/actor.wast similarity index 100% rename from proposals/continuations/examples/actor.wast rename to proposals/stack-switching/examples/actor.wast diff --git a/proposals/continuations/examples/async-await.wast b/proposals/stack-switching/examples/async-await.wast similarity index 100% rename from proposals/continuations/examples/async-await.wast rename to proposals/stack-switching/examples/async-await.wast diff --git a/proposals/continuations/examples/control-lwt.wast b/proposals/stack-switching/examples/control-lwt.wast similarity index 100% rename from proposals/continuations/examples/control-lwt.wast rename to proposals/stack-switching/examples/control-lwt.wast diff --git a/proposals/continuations/examples/fun-actor-lwt.wast b/proposals/stack-switching/examples/fun-actor-lwt.wast similarity index 100% rename from proposals/continuations/examples/fun-actor-lwt.wast rename to proposals/stack-switching/examples/fun-actor-lwt.wast diff --git a/proposals/continuations/examples/fun-lwt.wast b/proposals/stack-switching/examples/fun-lwt.wast similarity index 100% rename from proposals/continuations/examples/fun-lwt.wast rename to proposals/stack-switching/examples/fun-lwt.wast diff --git a/proposals/continuations/examples/fun-pipes.wast b/proposals/stack-switching/examples/fun-pipes.wast similarity index 100% rename from proposals/continuations/examples/fun-pipes.wast rename to proposals/stack-switching/examples/fun-pipes.wast diff --git a/proposals/continuations/examples/fun-state.wast b/proposals/stack-switching/examples/fun-state.wast similarity index 100% rename from proposals/continuations/examples/fun-state.wast rename to proposals/stack-switching/examples/fun-state.wast diff --git a/proposals/continuations/examples/generators.wast b/proposals/stack-switching/examples/generators.wast similarity index 100% rename from proposals/continuations/examples/generators.wast rename to proposals/stack-switching/examples/generators.wast diff --git a/proposals/continuations/examples/lwt.wast b/proposals/stack-switching/examples/lwt.wast similarity index 100% rename from proposals/continuations/examples/lwt.wast rename to proposals/stack-switching/examples/lwt.wast diff --git a/proposals/continuations/examples/pipes.wast b/proposals/stack-switching/examples/pipes.wast similarity index 100% rename from proposals/continuations/examples/pipes.wast rename to proposals/stack-switching/examples/pipes.wast diff --git a/proposals/continuations/examples/static-lwt.wast b/proposals/stack-switching/examples/static-lwt.wast similarity index 100% rename from proposals/continuations/examples/static-lwt.wast rename to proposals/stack-switching/examples/static-lwt.wast diff --git a/test/build.py b/test/build.py index 69c1b19a26..94e7304dbf 100755 --- a/test/build.py +++ b/test/build.py @@ -13,6 +13,9 @@ WASM_EXEC = os.path.join(INTERPRETER_DIR, 'wasm') WAST_TESTS_DIR = os.path.join(SCRIPT_DIR, 'core') +WAST_TEST_SUBDIRS = [os.path.basename(d) for d in + filter(os.path.isdir, + glob.glob(os.path.join(WAST_TESTS_DIR, '*')))] HARNESS_DIR = os.path.join(SCRIPT_DIR, 'harness') HARNESS_FILES = ['testharness.js', 'testharnessreport.js', 'testharness.css'] @@ -67,13 +70,17 @@ def convert_wast_to_js(out_js_dir): inputs = [] - for wast_file in glob.glob(os.path.join(WAST_TESTS_DIR, '*.wast')): + for wast_file in glob.glob(os.path.join(WAST_TESTS_DIR, '**/*.wast'), + recursive = True): # Don't try to compile tests that are supposed to fail. if '.fail.' in wast_file: continue + js_subdir = os.path.basename(os.path.dirname(wast_file)) + if js_subdir == 'core': + js_subdir = '' js_filename = os.path.basename(wast_file) + '.js' - js_file = os.path.join(out_js_dir, js_filename) + js_file = os.path.join(out_js_dir, js_subdir, js_filename) inputs.append((wast_file, js_file)) pool = mp.Pool(processes=8) @@ -112,9 +119,9 @@ def build_js(out_js_dir): - - - + + +
""" @@ -137,6 +144,8 @@ def wrap_single_test(js_file): def build_html_js(out_dir): ensure_empty_dir(out_dir) + for d in WAST_TEST_SUBDIRS: + ensure_empty_dir(os.path.join(out_dir, d)) copy_harness_files(out_dir, True) tests = convert_wast_to_js(out_dir) @@ -146,19 +155,25 @@ def build_html_js(out_dir): def build_html_from_js(tests, html_dir, use_sync): for js_file in tests: - js_filename = os.path.basename(js_file) - html_filename = js_filename + '.html' - html_file = os.path.join(html_dir, html_filename) + subdir = os.path.basename(os.path.dirname(js_file)) + js_prefix = '../js' + if subdir == 'js': + subdir = '' + js_prefix = './js' + js_filename = os.path.join(js_prefix, subdir, os.path.basename(js_file)) + html_filename = os.path.basename(js_file) + '.html' + html_file = os.path.join(html_dir, subdir, html_filename) js_harness = "sync_index.js" if use_sync else "async_index.js" + harness_dir = os.path.join(js_prefix, 'harness') with open(html_file, 'w+') as f: - content = HTML_HEADER.replace('{PREFIX}', './js/harness') \ - .replace('{WPT_PREFIX}', './js/harness') \ + content = HTML_HEADER.replace('{PREFIX}', harness_dir) \ + .replace('{WPT_PREFIX}', harness_dir) \ .replace('{JS_HARNESS}', js_harness) - content += " ".replace('{SCRIPT}', js_filename) + content += ' ' content += HTML_BOTTOM f.write(content) -def build_html(html_dir, js_dir, use_sync): +def build_html(html_dir, use_sync): print("Building HTML tests...") js_html_dir = os.path.join(html_dir, 'js') @@ -248,11 +263,15 @@ def process_args(): if js_dir is not None: ensure_empty_dir(js_dir) + for d in WAST_TEST_SUBDIRS: + ensure_empty_dir(os.path.join(js_dir, d)) build_js(js_dir) if html_dir is not None: ensure_empty_dir(html_dir) - build_html(html_dir, js_dir, args.use_sync) + for d in WAST_TEST_SUBDIRS: + ensure_empty_dir(os.path.join(html_dir, d)) + build_html(html_dir, args.use_sync) if front_dir is not None: ensure_empty_dir(front_dir) diff --git a/test/core/address.wast b/test/core/address.wast index 320ea36bc0..8e52030ecd 100644 --- a/test/core/address.wast +++ b/test/core/address.wast @@ -210,12 +210,12 @@ (assert_trap (invoke "16s_bad" (i32.const 1)) "out of bounds memory access") (assert_trap (invoke "32_bad" (i32.const 1)) "out of bounds memory access") -(assert_malformed +(assert_invalid (module quote "(memory 1)" "(func (drop (i32.load offset=4294967296 (i32.const 0))))" ) - "i32 constant" + "offset out of range" ) ;; Load i64 data with different offset/align arguments diff --git a/test/core/address64.wast b/test/core/address64.wast new file mode 100644 index 0000000000..29771ae776 --- /dev/null +++ b/test/core/address64.wast @@ -0,0 +1,582 @@ +;; Load i32 data with different offset/align arguments + +(module + (memory i64 1) + (data (i64.const 0) "abcdefghijklmnopqrstuvwxyz") + + (func (export "8u_good1") (param $i i64) (result i32) + (i32.load8_u offset=0 (local.get $i)) ;; 97 'a' + ) + (func (export "8u_good2") (param $i i64) (result i32) + (i32.load8_u align=1 (local.get $i)) ;; 97 'a' + ) + (func (export "8u_good3") (param $i i64) (result i32) + (i32.load8_u offset=1 align=1 (local.get $i)) ;; 98 'b' + ) + (func (export "8u_good4") (param $i i64) (result i32) + (i32.load8_u offset=2 align=1 (local.get $i)) ;; 99 'c' + ) + (func (export "8u_good5") (param $i i64) (result i32) + (i32.load8_u offset=25 align=1 (local.get $i)) ;; 122 'z' + ) + + (func (export "8s_good1") (param $i i64) (result i32) + (i32.load8_s offset=0 (local.get $i)) ;; 97 'a' + ) + (func (export "8s_good2") (param $i i64) (result i32) + (i32.load8_s align=1 (local.get $i)) ;; 97 'a' + ) + (func (export "8s_good3") (param $i i64) (result i32) + (i32.load8_s offset=1 align=1 (local.get $i)) ;; 98 'b' + ) + (func (export "8s_good4") (param $i i64) (result i32) + (i32.load8_s offset=2 align=1 (local.get $i)) ;; 99 'c' + ) + (func (export "8s_good5") (param $i i64) (result i32) + (i32.load8_s offset=25 align=1 (local.get $i)) ;; 122 'z' + ) + + (func (export "16u_good1") (param $i i64) (result i32) + (i32.load16_u offset=0 (local.get $i)) ;; 25185 'ab' + ) + (func (export "16u_good2") (param $i i64) (result i32) + (i32.load16_u align=1 (local.get $i)) ;; 25185 'ab' + ) + (func (export "16u_good3") (param $i i64) (result i32) + (i32.load16_u offset=1 align=1 (local.get $i)) ;; 25442 'bc' + ) + (func (export "16u_good4") (param $i i64) (result i32) + (i32.load16_u offset=2 align=2 (local.get $i)) ;; 25699 'cd' + ) + (func (export "16u_good5") (param $i i64) (result i32) + (i32.load16_u offset=25 align=2 (local.get $i)) ;; 122 'z\0' + ) + + (func (export "16s_good1") (param $i i64) (result i32) + (i32.load16_s offset=0 (local.get $i)) ;; 25185 'ab' + ) + (func (export "16s_good2") (param $i i64) (result i32) + (i32.load16_s align=1 (local.get $i)) ;; 25185 'ab' + ) + (func (export "16s_good3") (param $i i64) (result i32) + (i32.load16_s offset=1 align=1 (local.get $i)) ;; 25442 'bc' + ) + (func (export "16s_good4") (param $i i64) (result i32) + (i32.load16_s offset=2 align=2 (local.get $i)) ;; 25699 'cd' + ) + (func (export "16s_good5") (param $i i64) (result i32) + (i32.load16_s offset=25 align=2 (local.get $i)) ;; 122 'z\0' + ) + + (func (export "32_good1") (param $i i64) (result i32) + (i32.load offset=0 (local.get $i)) ;; 1684234849 'abcd' + ) + (func (export "32_good2") (param $i i64) (result i32) + (i32.load align=1 (local.get $i)) ;; 1684234849 'abcd' + ) + (func (export "32_good3") (param $i i64) (result i32) + (i32.load offset=1 align=1 (local.get $i)) ;; 1701077858 'bcde' + ) + (func (export "32_good4") (param $i i64) (result i32) + (i32.load offset=2 align=2 (local.get $i)) ;; 1717920867 'cdef' + ) + (func (export "32_good5") (param $i i64) (result i32) + (i32.load offset=25 align=4 (local.get $i)) ;; 122 'z\0\0\0' + ) + + (func (export "8u_bad") (param $i i64) + (drop (i32.load8_u offset=4294967295 (local.get $i))) + ) + (func (export "8s_bad") (param $i i64) + (drop (i32.load8_s offset=4294967295 (local.get $i))) + ) + (func (export "16u_bad") (param $i i64) + (drop (i32.load16_u offset=4294967295 (local.get $i))) + ) + (func (export "16s_bad") (param $i i64) + (drop (i32.load16_s offset=4294967295 (local.get $i))) + ) + (func (export "32_bad") (param $i i64) + (drop (i32.load offset=4294967295 (local.get $i))) + ) +) + +(assert_return (invoke "8u_good1" (i64.const 0)) (i32.const 97)) +(assert_return (invoke "8u_good2" (i64.const 0)) (i32.const 97)) +(assert_return (invoke "8u_good3" (i64.const 0)) (i32.const 98)) +(assert_return (invoke "8u_good4" (i64.const 0)) (i32.const 99)) +(assert_return (invoke "8u_good5" (i64.const 0)) (i32.const 122)) + +(assert_return (invoke "8s_good1" (i64.const 0)) (i32.const 97)) +(assert_return (invoke "8s_good2" (i64.const 0)) (i32.const 97)) +(assert_return (invoke "8s_good3" (i64.const 0)) (i32.const 98)) +(assert_return (invoke "8s_good4" (i64.const 0)) (i32.const 99)) +(assert_return (invoke "8s_good5" (i64.const 0)) (i32.const 122)) + +(assert_return (invoke "16u_good1" (i64.const 0)) (i32.const 25185)) +(assert_return (invoke "16u_good2" (i64.const 0)) (i32.const 25185)) +(assert_return (invoke "16u_good3" (i64.const 0)) (i32.const 25442)) +(assert_return (invoke "16u_good4" (i64.const 0)) (i32.const 25699)) +(assert_return (invoke "16u_good5" (i64.const 0)) (i32.const 122)) + +(assert_return (invoke "16s_good1" (i64.const 0)) (i32.const 25185)) +(assert_return (invoke "16s_good2" (i64.const 0)) (i32.const 25185)) +(assert_return (invoke "16s_good3" (i64.const 0)) (i32.const 25442)) +(assert_return (invoke "16s_good4" (i64.const 0)) (i32.const 25699)) +(assert_return (invoke "16s_good5" (i64.const 0)) (i32.const 122)) + +(assert_return (invoke "32_good1" (i64.const 0)) (i32.const 1684234849)) +(assert_return (invoke "32_good2" (i64.const 0)) (i32.const 1684234849)) +(assert_return (invoke "32_good3" (i64.const 0)) (i32.const 1701077858)) +(assert_return (invoke "32_good4" (i64.const 0)) (i32.const 1717920867)) +(assert_return (invoke "32_good5" (i64.const 0)) (i32.const 122)) + +(assert_return (invoke "8u_good1" (i64.const 65507)) (i32.const 0)) +(assert_return (invoke "8u_good2" (i64.const 65507)) (i32.const 0)) +(assert_return (invoke "8u_good3" (i64.const 65507)) (i32.const 0)) +(assert_return (invoke "8u_good4" (i64.const 65507)) (i32.const 0)) +(assert_return (invoke "8u_good5" (i64.const 65507)) (i32.const 0)) + +(assert_return (invoke "8s_good1" (i64.const 65507)) (i32.const 0)) +(assert_return (invoke "8s_good2" (i64.const 65507)) (i32.const 0)) +(assert_return (invoke "8s_good3" (i64.const 65507)) (i32.const 0)) +(assert_return (invoke "8s_good4" (i64.const 65507)) (i32.const 0)) +(assert_return (invoke "8s_good5" (i64.const 65507)) (i32.const 0)) + +(assert_return (invoke "16u_good1" (i64.const 65507)) (i32.const 0)) +(assert_return (invoke "16u_good2" (i64.const 65507)) (i32.const 0)) +(assert_return (invoke "16u_good3" (i64.const 65507)) (i32.const 0)) +(assert_return (invoke "16u_good4" (i64.const 65507)) (i32.const 0)) +(assert_return (invoke "16u_good5" (i64.const 65507)) (i32.const 0)) + +(assert_return (invoke "16s_good1" (i64.const 65507)) (i32.const 0)) +(assert_return (invoke "16s_good2" (i64.const 65507)) (i32.const 0)) +(assert_return (invoke "16s_good3" (i64.const 65507)) (i32.const 0)) +(assert_return (invoke "16s_good4" (i64.const 65507)) (i32.const 0)) +(assert_return (invoke "16s_good5" (i64.const 65507)) (i32.const 0)) + +(assert_return (invoke "32_good1" (i64.const 65507)) (i32.const 0)) +(assert_return (invoke "32_good2" (i64.const 65507)) (i32.const 0)) +(assert_return (invoke "32_good3" (i64.const 65507)) (i32.const 0)) +(assert_return (invoke "32_good4" (i64.const 65507)) (i32.const 0)) +(assert_return (invoke "32_good5" (i64.const 65507)) (i32.const 0)) + +(assert_return (invoke "8u_good1" (i64.const 65508)) (i32.const 0)) +(assert_return (invoke "8u_good2" (i64.const 65508)) (i32.const 0)) +(assert_return (invoke "8u_good3" (i64.const 65508)) (i32.const 0)) +(assert_return (invoke "8u_good4" (i64.const 65508)) (i32.const 0)) +(assert_return (invoke "8u_good5" (i64.const 65508)) (i32.const 0)) + +(assert_return (invoke "8s_good1" (i64.const 65508)) (i32.const 0)) +(assert_return (invoke "8s_good2" (i64.const 65508)) (i32.const 0)) +(assert_return (invoke "8s_good3" (i64.const 65508)) (i32.const 0)) +(assert_return (invoke "8s_good4" (i64.const 65508)) (i32.const 0)) +(assert_return (invoke "8s_good5" (i64.const 65508)) (i32.const 0)) + +(assert_return (invoke "16u_good1" (i64.const 65508)) (i32.const 0)) +(assert_return (invoke "16u_good2" (i64.const 65508)) (i32.const 0)) +(assert_return (invoke "16u_good3" (i64.const 65508)) (i32.const 0)) +(assert_return (invoke "16u_good4" (i64.const 65508)) (i32.const 0)) +(assert_return (invoke "16u_good5" (i64.const 65508)) (i32.const 0)) + +(assert_return (invoke "16s_good1" (i64.const 65508)) (i32.const 0)) +(assert_return (invoke "16s_good2" (i64.const 65508)) (i32.const 0)) +(assert_return (invoke "16s_good3" (i64.const 65508)) (i32.const 0)) +(assert_return (invoke "16s_good4" (i64.const 65508)) (i32.const 0)) +(assert_return (invoke "16s_good5" (i64.const 65508)) (i32.const 0)) + +(assert_return (invoke "32_good1" (i64.const 65508)) (i32.const 0)) +(assert_return (invoke "32_good2" (i64.const 65508)) (i32.const 0)) +(assert_return (invoke "32_good3" (i64.const 65508)) (i32.const 0)) +(assert_return (invoke "32_good4" (i64.const 65508)) (i32.const 0)) +(assert_trap (invoke "32_good5" (i64.const 65508)) "out of bounds memory access") + +(assert_trap (invoke "8u_bad" (i64.const 0)) "out of bounds memory access") +(assert_trap (invoke "8s_bad" (i64.const 0)) "out of bounds memory access") +(assert_trap (invoke "16u_bad" (i64.const 0)) "out of bounds memory access") +(assert_trap (invoke "16s_bad" (i64.const 0)) "out of bounds memory access") +(assert_trap (invoke "32_bad" (i64.const 0)) "out of bounds memory access") + +(assert_trap (invoke "8u_bad" (i64.const 1)) "out of bounds memory access") +(assert_trap (invoke "8s_bad" (i64.const 1)) "out of bounds memory access") +(assert_trap (invoke "16u_bad" (i64.const 1)) "out of bounds memory access") +(assert_trap (invoke "16s_bad" (i64.const 1)) "out of bounds memory access") +(assert_trap (invoke "32_bad" (i64.const 1)) "out of bounds memory access") + + +;; Load i64 data with different offset/align arguments + +(module + (memory i64 1) + (data (i64.const 0) "abcdefghijklmnopqrstuvwxyz") + + (func (export "8u_good1") (param $i i64) (result i64) + (i64.load8_u offset=0 (local.get $i)) ;; 97 'a' + ) + (func (export "8u_good2") (param $i i64) (result i64) + (i64.load8_u align=1 (local.get $i)) ;; 97 'a' + ) + (func (export "8u_good3") (param $i i64) (result i64) + (i64.load8_u offset=1 align=1 (local.get $i)) ;; 98 'b' + ) + (func (export "8u_good4") (param $i i64) (result i64) + (i64.load8_u offset=2 align=1 (local.get $i)) ;; 99 'c' + ) + (func (export "8u_good5") (param $i i64) (result i64) + (i64.load8_u offset=25 align=1 (local.get $i)) ;; 122 'z' + ) + + (func (export "8s_good1") (param $i i64) (result i64) + (i64.load8_s offset=0 (local.get $i)) ;; 97 'a' + ) + (func (export "8s_good2") (param $i i64) (result i64) + (i64.load8_s align=1 (local.get $i)) ;; 97 'a' + ) + (func (export "8s_good3") (param $i i64) (result i64) + (i64.load8_s offset=1 align=1 (local.get $i)) ;; 98 'b' + ) + (func (export "8s_good4") (param $i i64) (result i64) + (i64.load8_s offset=2 align=1 (local.get $i)) ;; 99 'c' + ) + (func (export "8s_good5") (param $i i64) (result i64) + (i64.load8_s offset=25 align=1 (local.get $i)) ;; 122 'z' + ) + + (func (export "16u_good1") (param $i i64) (result i64) + (i64.load16_u offset=0 (local.get $i)) ;; 25185 'ab' + ) + (func (export "16u_good2") (param $i i64) (result i64) + (i64.load16_u align=1 (local.get $i)) ;; 25185 'ab' + ) + (func (export "16u_good3") (param $i i64) (result i64) + (i64.load16_u offset=1 align=1 (local.get $i)) ;; 25442 'bc' + ) + (func (export "16u_good4") (param $i i64) (result i64) + (i64.load16_u offset=2 align=2 (local.get $i)) ;; 25699 'cd' + ) + (func (export "16u_good5") (param $i i64) (result i64) + (i64.load16_u offset=25 align=2 (local.get $i)) ;; 122 'z\0' + ) + + (func (export "16s_good1") (param $i i64) (result i64) + (i64.load16_s offset=0 (local.get $i)) ;; 25185 'ab' + ) + (func (export "16s_good2") (param $i i64) (result i64) + (i64.load16_s align=1 (local.get $i)) ;; 25185 'ab' + ) + (func (export "16s_good3") (param $i i64) (result i64) + (i64.load16_s offset=1 align=1 (local.get $i)) ;; 25442 'bc' + ) + (func (export "16s_good4") (param $i i64) (result i64) + (i64.load16_s offset=2 align=2 (local.get $i)) ;; 25699 'cd' + ) + (func (export "16s_good5") (param $i i64) (result i64) + (i64.load16_s offset=25 align=2 (local.get $i)) ;; 122 'z\0' + ) + + (func (export "32u_good1") (param $i i64) (result i64) + (i64.load32_u offset=0 (local.get $i)) ;; 1684234849 'abcd' + ) + (func (export "32u_good2") (param $i i64) (result i64) + (i64.load32_u align=1 (local.get $i)) ;; 1684234849 'abcd' + ) + (func (export "32u_good3") (param $i i64) (result i64) + (i64.load32_u offset=1 align=1 (local.get $i)) ;; 1701077858 'bcde' + ) + (func (export "32u_good4") (param $i i64) (result i64) + (i64.load32_u offset=2 align=2 (local.get $i)) ;; 1717920867 'cdef' + ) + (func (export "32u_good5") (param $i i64) (result i64) + (i64.load32_u offset=25 align=4 (local.get $i)) ;; 122 'z\0\0\0' + ) + + (func (export "32s_good1") (param $i i64) (result i64) + (i64.load32_s offset=0 (local.get $i)) ;; 1684234849 'abcd' + ) + (func (export "32s_good2") (param $i i64) (result i64) + (i64.load32_s align=1 (local.get $i)) ;; 1684234849 'abcd' + ) + (func (export "32s_good3") (param $i i64) (result i64) + (i64.load32_s offset=1 align=1 (local.get $i)) ;; 1701077858 'bcde' + ) + (func (export "32s_good4") (param $i i64) (result i64) + (i64.load32_s offset=2 align=2 (local.get $i)) ;; 1717920867 'cdef' + ) + (func (export "32s_good5") (param $i i64) (result i64) + (i64.load32_s offset=25 align=4 (local.get $i)) ;; 122 'z\0\0\0' + ) + + (func (export "64_good1") (param $i i64) (result i64) + (i64.load offset=0 (local.get $i)) ;; 0x6867666564636261 'abcdefgh' + ) + (func (export "64_good2") (param $i i64) (result i64) + (i64.load align=1 (local.get $i)) ;; 0x6867666564636261 'abcdefgh' + ) + (func (export "64_good3") (param $i i64) (result i64) + (i64.load offset=1 align=1 (local.get $i)) ;; 0x6968676665646362 'bcdefghi' + ) + (func (export "64_good4") (param $i i64) (result i64) + (i64.load offset=2 align=2 (local.get $i)) ;; 0x6a69686766656463 'cdefghij' + ) + (func (export "64_good5") (param $i i64) (result i64) + (i64.load offset=25 align=8 (local.get $i)) ;; 122 'z\0\0\0\0\0\0\0' + ) + + (func (export "8u_bad") (param $i i64) + (drop (i64.load8_u offset=4294967295 (local.get $i))) + ) + (func (export "8s_bad") (param $i i64) + (drop (i64.load8_s offset=4294967295 (local.get $i))) + ) + (func (export "16u_bad") (param $i i64) + (drop (i64.load16_u offset=4294967295 (local.get $i))) + ) + (func (export "16s_bad") (param $i i64) + (drop (i64.load16_s offset=4294967295 (local.get $i))) + ) + (func (export "32u_bad") (param $i i64) + (drop (i64.load32_u offset=4294967295 (local.get $i))) + ) + (func (export "32s_bad") (param $i i64) + (drop (i64.load32_s offset=4294967295 (local.get $i))) + ) + (func (export "64_bad") (param $i i64) + (drop (i64.load offset=4294967295 (local.get $i))) + ) +) + +(assert_return (invoke "8u_good1" (i64.const 0)) (i64.const 97)) +(assert_return (invoke "8u_good2" (i64.const 0)) (i64.const 97)) +(assert_return (invoke "8u_good3" (i64.const 0)) (i64.const 98)) +(assert_return (invoke "8u_good4" (i64.const 0)) (i64.const 99)) +(assert_return (invoke "8u_good5" (i64.const 0)) (i64.const 122)) + +(assert_return (invoke "8s_good1" (i64.const 0)) (i64.const 97)) +(assert_return (invoke "8s_good2" (i64.const 0)) (i64.const 97)) +(assert_return (invoke "8s_good3" (i64.const 0)) (i64.const 98)) +(assert_return (invoke "8s_good4" (i64.const 0)) (i64.const 99)) +(assert_return (invoke "8s_good5" (i64.const 0)) (i64.const 122)) + +(assert_return (invoke "16u_good1" (i64.const 0)) (i64.const 25185)) +(assert_return (invoke "16u_good2" (i64.const 0)) (i64.const 25185)) +(assert_return (invoke "16u_good3" (i64.const 0)) (i64.const 25442)) +(assert_return (invoke "16u_good4" (i64.const 0)) (i64.const 25699)) +(assert_return (invoke "16u_good5" (i64.const 0)) (i64.const 122)) + +(assert_return (invoke "16s_good1" (i64.const 0)) (i64.const 25185)) +(assert_return (invoke "16s_good2" (i64.const 0)) (i64.const 25185)) +(assert_return (invoke "16s_good3" (i64.const 0)) (i64.const 25442)) +(assert_return (invoke "16s_good4" (i64.const 0)) (i64.const 25699)) +(assert_return (invoke "16s_good5" (i64.const 0)) (i64.const 122)) + +(assert_return (invoke "32u_good1" (i64.const 0)) (i64.const 1684234849)) +(assert_return (invoke "32u_good2" (i64.const 0)) (i64.const 1684234849)) +(assert_return (invoke "32u_good3" (i64.const 0)) (i64.const 1701077858)) +(assert_return (invoke "32u_good4" (i64.const 0)) (i64.const 1717920867)) +(assert_return (invoke "32u_good5" (i64.const 0)) (i64.const 122)) + +(assert_return (invoke "32s_good1" (i64.const 0)) (i64.const 1684234849)) +(assert_return (invoke "32s_good2" (i64.const 0)) (i64.const 1684234849)) +(assert_return (invoke "32s_good3" (i64.const 0)) (i64.const 1701077858)) +(assert_return (invoke "32s_good4" (i64.const 0)) (i64.const 1717920867)) +(assert_return (invoke "32s_good5" (i64.const 0)) (i64.const 122)) + +(assert_return (invoke "64_good1" (i64.const 0)) (i64.const 0x6867666564636261)) +(assert_return (invoke "64_good2" (i64.const 0)) (i64.const 0x6867666564636261)) +(assert_return (invoke "64_good3" (i64.const 0)) (i64.const 0x6968676665646362)) +(assert_return (invoke "64_good4" (i64.const 0)) (i64.const 0x6a69686766656463)) +(assert_return (invoke "64_good5" (i64.const 0)) (i64.const 122)) + +(assert_return (invoke "8u_good1" (i64.const 65503)) (i64.const 0)) +(assert_return (invoke "8u_good2" (i64.const 65503)) (i64.const 0)) +(assert_return (invoke "8u_good3" (i64.const 65503)) (i64.const 0)) +(assert_return (invoke "8u_good4" (i64.const 65503)) (i64.const 0)) +(assert_return (invoke "8u_good5" (i64.const 65503)) (i64.const 0)) + +(assert_return (invoke "8s_good1" (i64.const 65503)) (i64.const 0)) +(assert_return (invoke "8s_good2" (i64.const 65503)) (i64.const 0)) +(assert_return (invoke "8s_good3" (i64.const 65503)) (i64.const 0)) +(assert_return (invoke "8s_good4" (i64.const 65503)) (i64.const 0)) +(assert_return (invoke "8s_good5" (i64.const 65503)) (i64.const 0)) + +(assert_return (invoke "16u_good1" (i64.const 65503)) (i64.const 0)) +(assert_return (invoke "16u_good2" (i64.const 65503)) (i64.const 0)) +(assert_return (invoke "16u_good3" (i64.const 65503)) (i64.const 0)) +(assert_return (invoke "16u_good4" (i64.const 65503)) (i64.const 0)) +(assert_return (invoke "16u_good5" (i64.const 65503)) (i64.const 0)) + +(assert_return (invoke "16s_good1" (i64.const 65503)) (i64.const 0)) +(assert_return (invoke "16s_good2" (i64.const 65503)) (i64.const 0)) +(assert_return (invoke "16s_good3" (i64.const 65503)) (i64.const 0)) +(assert_return (invoke "16s_good4" (i64.const 65503)) (i64.const 0)) +(assert_return (invoke "16s_good5" (i64.const 65503)) (i64.const 0)) + +(assert_return (invoke "32u_good1" (i64.const 65503)) (i64.const 0)) +(assert_return (invoke "32u_good2" (i64.const 65503)) (i64.const 0)) +(assert_return (invoke "32u_good3" (i64.const 65503)) (i64.const 0)) +(assert_return (invoke "32u_good4" (i64.const 65503)) (i64.const 0)) +(assert_return (invoke "32u_good5" (i64.const 65503)) (i64.const 0)) + +(assert_return (invoke "32s_good1" (i64.const 65503)) (i64.const 0)) +(assert_return (invoke "32s_good2" (i64.const 65503)) (i64.const 0)) +(assert_return (invoke "32s_good3" (i64.const 65503)) (i64.const 0)) +(assert_return (invoke "32s_good4" (i64.const 65503)) (i64.const 0)) +(assert_return (invoke "32s_good5" (i64.const 65503)) (i64.const 0)) + +(assert_return (invoke "64_good1" (i64.const 65503)) (i64.const 0)) +(assert_return (invoke "64_good2" (i64.const 65503)) (i64.const 0)) +(assert_return (invoke "64_good3" (i64.const 65503)) (i64.const 0)) +(assert_return (invoke "64_good4" (i64.const 65503)) (i64.const 0)) +(assert_return (invoke "64_good5" (i64.const 65503)) (i64.const 0)) + +(assert_return (invoke "8u_good1" (i64.const 65504)) (i64.const 0)) +(assert_return (invoke "8u_good2" (i64.const 65504)) (i64.const 0)) +(assert_return (invoke "8u_good3" (i64.const 65504)) (i64.const 0)) +(assert_return (invoke "8u_good4" (i64.const 65504)) (i64.const 0)) +(assert_return (invoke "8u_good5" (i64.const 65504)) (i64.const 0)) + +(assert_return (invoke "8s_good1" (i64.const 65504)) (i64.const 0)) +(assert_return (invoke "8s_good2" (i64.const 65504)) (i64.const 0)) +(assert_return (invoke "8s_good3" (i64.const 65504)) (i64.const 0)) +(assert_return (invoke "8s_good4" (i64.const 65504)) (i64.const 0)) +(assert_return (invoke "8s_good5" (i64.const 65504)) (i64.const 0)) + +(assert_return (invoke "16u_good1" (i64.const 65504)) (i64.const 0)) +(assert_return (invoke "16u_good2" (i64.const 65504)) (i64.const 0)) +(assert_return (invoke "16u_good3" (i64.const 65504)) (i64.const 0)) +(assert_return (invoke "16u_good4" (i64.const 65504)) (i64.const 0)) +(assert_return (invoke "16u_good5" (i64.const 65504)) (i64.const 0)) + +(assert_return (invoke "16s_good1" (i64.const 65504)) (i64.const 0)) +(assert_return (invoke "16s_good2" (i64.const 65504)) (i64.const 0)) +(assert_return (invoke "16s_good3" (i64.const 65504)) (i64.const 0)) +(assert_return (invoke "16s_good4" (i64.const 65504)) (i64.const 0)) +(assert_return (invoke "16s_good5" (i64.const 65504)) (i64.const 0)) + +(assert_return (invoke "32u_good1" (i64.const 65504)) (i64.const 0)) +(assert_return (invoke "32u_good2" (i64.const 65504)) (i64.const 0)) +(assert_return (invoke "32u_good3" (i64.const 65504)) (i64.const 0)) +(assert_return (invoke "32u_good4" (i64.const 65504)) (i64.const 0)) +(assert_return (invoke "32u_good5" (i64.const 65504)) (i64.const 0)) + +(assert_return (invoke "32s_good1" (i64.const 65504)) (i64.const 0)) +(assert_return (invoke "32s_good2" (i64.const 65504)) (i64.const 0)) +(assert_return (invoke "32s_good3" (i64.const 65504)) (i64.const 0)) +(assert_return (invoke "32s_good4" (i64.const 65504)) (i64.const 0)) +(assert_return (invoke "32s_good5" (i64.const 65504)) (i64.const 0)) + +(assert_return (invoke "64_good1" (i64.const 65504)) (i64.const 0)) +(assert_return (invoke "64_good2" (i64.const 65504)) (i64.const 0)) +(assert_return (invoke "64_good3" (i64.const 65504)) (i64.const 0)) +(assert_return (invoke "64_good4" (i64.const 65504)) (i64.const 0)) +(assert_trap (invoke "64_good5" (i64.const 65504)) "out of bounds memory access") + +(assert_trap (invoke "8u_bad" (i64.const 0)) "out of bounds memory access") +(assert_trap (invoke "8s_bad" (i64.const 0)) "out of bounds memory access") +(assert_trap (invoke "16u_bad" (i64.const 0)) "out of bounds memory access") +(assert_trap (invoke "16s_bad" (i64.const 0)) "out of bounds memory access") +(assert_trap (invoke "32u_bad" (i64.const 0)) "out of bounds memory access") +(assert_trap (invoke "32s_bad" (i64.const 0)) "out of bounds memory access") +(assert_trap (invoke "64_bad" (i64.const 0)) "out of bounds memory access") + +(assert_trap (invoke "8u_bad" (i64.const 1)) "out of bounds memory access") +(assert_trap (invoke "8s_bad" (i64.const 1)) "out of bounds memory access") +(assert_trap (invoke "16u_bad" (i64.const 1)) "out of bounds memory access") +(assert_trap (invoke "16s_bad" (i64.const 1)) "out of bounds memory access") +(assert_trap (invoke "32u_bad" (i64.const 0)) "out of bounds memory access") +(assert_trap (invoke "32s_bad" (i64.const 0)) "out of bounds memory access") +(assert_trap (invoke "64_bad" (i64.const 1)) "out of bounds memory access") + +;; Load f32 data with different offset/align arguments + +(module + (memory i64 1) + (data (i64.const 0) "\00\00\00\00\00\00\a0\7f\01\00\d0\7f") + + (func (export "32_good1") (param $i i64) (result f32) + (f32.load offset=0 (local.get $i)) ;; 0.0 '\00\00\00\00' + ) + (func (export "32_good2") (param $i i64) (result f32) + (f32.load align=1 (local.get $i)) ;; 0.0 '\00\00\00\00' + ) + (func (export "32_good3") (param $i i64) (result f32) + (f32.load offset=1 align=1 (local.get $i)) ;; 0.0 '\00\00\00\00' + ) + (func (export "32_good4") (param $i i64) (result f32) + (f32.load offset=2 align=2 (local.get $i)) ;; 0.0 '\00\00\00\00' + ) + (func (export "32_good5") (param $i i64) (result f32) + (f32.load offset=8 align=4 (local.get $i)) ;; nan:0x500001 '\01\00\d0\7f' + ) + (func (export "32_bad") (param $i i64) + (drop (f32.load offset=4294967295 (local.get $i))) + ) +) + +(assert_return (invoke "32_good1" (i64.const 0)) (f32.const 0.0)) +(assert_return (invoke "32_good2" (i64.const 0)) (f32.const 0.0)) +(assert_return (invoke "32_good3" (i64.const 0)) (f32.const 0.0)) +(assert_return (invoke "32_good4" (i64.const 0)) (f32.const 0.0)) +(assert_return (invoke "32_good5" (i64.const 0)) (f32.const nan:0x500001)) + +(assert_return (invoke "32_good1" (i64.const 65524)) (f32.const 0.0)) +(assert_return (invoke "32_good2" (i64.const 65524)) (f32.const 0.0)) +(assert_return (invoke "32_good3" (i64.const 65524)) (f32.const 0.0)) +(assert_return (invoke "32_good4" (i64.const 65524)) (f32.const 0.0)) +(assert_return (invoke "32_good5" (i64.const 65524)) (f32.const 0.0)) + +(assert_return (invoke "32_good1" (i64.const 65525)) (f32.const 0.0)) +(assert_return (invoke "32_good2" (i64.const 65525)) (f32.const 0.0)) +(assert_return (invoke "32_good3" (i64.const 65525)) (f32.const 0.0)) +(assert_return (invoke "32_good4" (i64.const 65525)) (f32.const 0.0)) +(assert_trap (invoke "32_good5" (i64.const 65525)) "out of bounds memory access") + +(assert_trap (invoke "32_bad" (i64.const 0)) "out of bounds memory access") +(assert_trap (invoke "32_bad" (i64.const 1)) "out of bounds memory access") + +;; Load f64 data with different offset/align arguments + +(module + (memory i64 1) + (data (i64.const 0) "\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\f4\7f\01\00\00\00\00\00\fc\7f") + + (func (export "64_good1") (param $i i64) (result f64) + (f64.load offset=0 (local.get $i)) ;; 0.0 '\00\00\00\00\00\00\00\00' + ) + (func (export "64_good2") (param $i i64) (result f64) + (f64.load align=1 (local.get $i)) ;; 0.0 '\00\00\00\00\00\00\00\00' + ) + (func (export "64_good3") (param $i i64) (result f64) + (f64.load offset=1 align=1 (local.get $i)) ;; 0.0 '\00\00\00\00\00\00\00\00' + ) + (func (export "64_good4") (param $i i64) (result f64) + (f64.load offset=2 align=2 (local.get $i)) ;; 0.0 '\00\00\00\00\00\00\00\00' + ) + (func (export "64_good5") (param $i i64) (result f64) + (f64.load offset=18 align=8 (local.get $i)) ;; nan:0xc000000000001 '\01\00\00\00\00\00\fc\7f' + ) + (func (export "64_bad") (param $i i64) + (drop (f64.load offset=4294967295 (local.get $i))) + ) +) + +(assert_return (invoke "64_good1" (i64.const 0)) (f64.const 0.0)) +(assert_return (invoke "64_good2" (i64.const 0)) (f64.const 0.0)) +(assert_return (invoke "64_good3" (i64.const 0)) (f64.const 0.0)) +(assert_return (invoke "64_good4" (i64.const 0)) (f64.const 0.0)) +(assert_return (invoke "64_good5" (i64.const 0)) (f64.const nan:0xc000000000001)) + +(assert_return (invoke "64_good1" (i64.const 65510)) (f64.const 0.0)) +(assert_return (invoke "64_good2" (i64.const 65510)) (f64.const 0.0)) +(assert_return (invoke "64_good3" (i64.const 65510)) (f64.const 0.0)) +(assert_return (invoke "64_good4" (i64.const 65510)) (f64.const 0.0)) +(assert_return (invoke "64_good5" (i64.const 65510)) (f64.const 0.0)) + +(assert_return (invoke "64_good1" (i64.const 65511)) (f64.const 0.0)) +(assert_return (invoke "64_good2" (i64.const 65511)) (f64.const 0.0)) +(assert_return (invoke "64_good3" (i64.const 65511)) (f64.const 0.0)) +(assert_return (invoke "64_good4" (i64.const 65511)) (f64.const 0.0)) +(assert_trap (invoke "64_good5" (i64.const 65511)) "out of bounds memory access") + +(assert_trap (invoke "64_bad" (i64.const 0)) "out of bounds memory access") +(assert_trap (invoke "64_bad" (i64.const 1)) "out of bounds memory access") diff --git a/test/core/align64.wast b/test/core/align64.wast new file mode 100644 index 0000000000..da34947f62 --- /dev/null +++ b/test/core/align64.wast @@ -0,0 +1,866 @@ +;; Test alignment annotation rules + +(module (memory i64 0) (func (drop (i32.load8_s align=1 (i64.const 0))))) +(module (memory i64 0) (func (drop (i32.load8_u align=1 (i64.const 0))))) +(module (memory i64 0) (func (drop (i32.load16_s align=2 (i64.const 0))))) +(module (memory i64 0) (func (drop (i32.load16_u align=2 (i64.const 0))))) +(module (memory i64 0) (func (drop (i32.load align=4 (i64.const 0))))) +(module (memory i64 0) (func (drop (i64.load8_s align=1 (i64.const 0))))) +(module (memory i64 0) (func (drop (i64.load8_u align=1 (i64.const 0))))) +(module (memory i64 0) (func (drop (i64.load16_s align=2 (i64.const 0))))) +(module (memory i64 0) (func (drop (i64.load16_u align=2 (i64.const 0))))) +(module (memory i64 0) (func (drop (i64.load32_s align=4 (i64.const 0))))) +(module (memory i64 0) (func (drop (i64.load32_u align=4 (i64.const 0))))) +(module (memory i64 0) (func (drop (i64.load align=8 (i64.const 0))))) +(module (memory i64 0) (func (drop (f32.load align=4 (i64.const 0))))) +(module (memory i64 0) (func (drop (f64.load align=8 (i64.const 0))))) +(module (memory i64 0) (func (i32.store8 align=1 (i64.const 0) (i32.const 1)))) +(module (memory i64 0) (func (i32.store16 align=2 (i64.const 0) (i32.const 1)))) +(module (memory i64 0) (func (i32.store align=4 (i64.const 0) (i32.const 1)))) +(module (memory i64 0) (func (i64.store8 align=1 (i64.const 0) (i64.const 1)))) +(module (memory i64 0) (func (i64.store16 align=2 (i64.const 0) (i64.const 1)))) +(module (memory i64 0) (func (i64.store32 align=4 (i64.const 0) (i64.const 1)))) +(module (memory i64 0) (func (i64.store align=8 (i64.const 0) (i64.const 1)))) +(module (memory i64 0) (func (f32.store align=4 (i64.const 0) (f32.const 1.0)))) +(module (memory i64 0) (func (f64.store align=8 (i64.const 0) (f64.const 1.0)))) + +(assert_malformed + (module quote + "(module (memory i64 0) (func (drop (i32.load8_s align=0 (i64.const 0)))))" + ) + "alignment" +) +(assert_malformed + (module quote + "(module (memory i64 0) (func (drop (i32.load8_s align=7 (i64.const 0)))))" + ) + "alignment" +) +(assert_malformed + (module quote + "(module (memory i64 0) (func (drop (i32.load8_u align=0 (i64.const 0)))))" + ) + "alignment" +) +(assert_malformed + (module quote + "(module (memory i64 0) (func (drop (i32.load8_u align=7 (i64.const 0)))))" + ) + "alignment" +) +(assert_malformed + (module quote + "(module (memory i64 0) (func (drop (i32.load16_s align=0 (i64.const 0)))))" + ) + "alignment" +) +(assert_malformed + (module quote + "(module (memory i64 0) (func (drop (i32.load16_s align=7 (i64.const 0)))))" + ) + "alignment" +) +(assert_malformed + (module quote + "(module (memory i64 0) (func (drop (i32.load16_u align=0 (i64.const 0)))))" + ) + "alignment" +) +(assert_malformed + (module quote + "(module (memory i64 0) (func (drop (i32.load16_u align=7 (i64.const 0)))))" + ) + "alignment" +) +(assert_malformed + (module quote + "(module (memory i64 0) (func (drop (i32.load align=0 (i64.const 0)))))" + ) + "alignment" +) +(assert_malformed + (module quote + "(module (memory i64 0) (func (drop (i32.load align=7 (i64.const 0)))))" + ) + "alignment" +) +(assert_malformed + (module quote + "(module (memory i64 0) (func (drop (i64.load8_s align=0 (i64.const 0)))))" + ) + "alignment" +) +(assert_malformed + (module quote + "(module (memory i64 0) (func (drop (i64.load8_s align=7 (i64.const 0)))))" + ) + "alignment" +) +(assert_malformed + (module quote + "(module (memory i64 0) (func (drop (i64.load8_u align=0 (i64.const 0)))))" + ) + "alignment" +) +(assert_malformed + (module quote + "(module (memory i64 0) (func (drop (i64.load8_u align=7 (i64.const 0)))))" + ) + "alignment" +) +(assert_malformed + (module quote + "(module (memory i64 0) (func (drop (i64.load16_s align=0 (i64.const 0)))))" + ) + "alignment" +) +(assert_malformed + (module quote + "(module (memory i64 0) (func (drop (i64.load16_s align=7 (i64.const 0)))))" + ) + "alignment" +) +(assert_malformed + (module quote + "(module (memory i64 0) (func (drop (i64.load16_u align=0 (i64.const 0)))))" + ) + "alignment" +) +(assert_malformed + (module quote + "(module (memory i64 0) (func (drop (i64.load16_u align=7 (i64.const 0)))))" + ) + "alignment" +) +(assert_malformed + (module quote + "(module (memory i64 0) (func (drop (i64.load32_s align=0 (i64.const 0)))))" + ) + "alignment" +) +(assert_malformed + (module quote + "(module (memory i64 0) (func (drop (i64.load32_s align=7 (i64.const 0)))))" + ) + "alignment" +) +(assert_malformed + (module quote + "(module (memory i64 0) (func (drop (i64.load32_u align=0 (i64.const 0)))))" + ) + "alignment" +) +(assert_malformed + (module quote + "(module (memory i64 0) (func (drop (i64.load32_u align=7 (i64.const 0)))))" + ) + "alignment" +) +(assert_malformed + (module quote + "(module (memory i64 0) (func (drop (i64.load align=0 (i64.const 0)))))" + ) + "alignment" +) +(assert_malformed + (module quote + "(module (memory i64 0) (func (drop (i64.load align=7 (i64.const 0)))))" + ) + "alignment" +) +(assert_malformed + (module quote + "(module (memory i64 0) (func (drop (f32.load align=0 (i64.const 0)))))" + ) + "alignment" +) +(assert_malformed + (module quote + "(module (memory i64 0) (func (drop (f32.load align=7 (i64.const 0)))))" + ) + "alignment" +) +(assert_malformed + (module quote + "(module (memory i64 0) (func (drop (f64.load align=0 (i64.const 0)))))" + ) + "alignment" +) +(assert_malformed + (module quote + "(module (memory i64 0) (func (drop (f64.load align=7 (i64.const 0)))))" + ) + "alignment" +) + +(assert_malformed + (module quote + "(module (memory i64 0) (func (i32.store8 align=0 (i64.const 0) (i32.const 0))))" + ) + "alignment" +) +(assert_malformed + (module quote + "(module (memory i64 0) (func (i32.store8 align=7 (i64.const 0) (i32.const 0))))" + ) + "alignment" +) +(assert_malformed + (module quote + "(module (memory i64 0) (func (i32.store16 align=0 (i64.const 0) (i32.const 0))))" + ) + "alignment" +) +(assert_malformed + (module quote + "(module (memory i64 0) (func (i32.store16 align=7 (i64.const 0) (i32.const 0))))" + ) + "alignment" +) +(assert_malformed + (module quote + "(module (memory i64 0) (func (i32.store align=0 (i64.const 0) (i32.const 0))))" + ) + "alignment" +) +(assert_malformed + (module quote + "(module (memory i64 0) (func (i32.store align=7 (i64.const 0) (i32.const 0))))" + ) + "alignment" +) +(assert_malformed + (module quote + "(module (memory i64 0) (func (i64.store8 align=0 (i64.const 0) (i64.const 0))))" + ) + "alignment" +) +(assert_malformed + (module quote + "(module (memory i64 0) (func (i64.store8 align=7 (i64.const 0) (i64.const 0))))" + ) + "alignment" +) +(assert_malformed + (module quote + "(module (memory i64 0) (func (i64.store16 align=0 (i64.const 0) (i64.const 0))))" + ) + "alignment" +) +(assert_malformed + (module quote + "(module (memory i64 0) (func (i64.store16 align=7 (i64.const 0) (i64.const 0))))" + ) + "alignment" +) +(assert_malformed + (module quote + "(module (memory i64 0) (func (i64.store32 align=0 (i64.const 0) (i64.const 0))))" + ) + "alignment" +) +(assert_malformed + (module quote + "(module (memory i64 0) (func (i64.store32 align=7 (i64.const 0) (i64.const 0))))" + ) + "alignment" +) +(assert_malformed + (module quote + "(module (memory i64 0) (func (i64.store align=0 (i64.const 0) (i64.const 0))))" + ) + "alignment" +) +(assert_malformed + (module quote + "(module (memory i64 0) (func (i64.store align=7 (i64.const 0) (i64.const 0))))" + ) + "alignment" +) +(assert_malformed + (module quote + "(module (memory i64 0) (func (f32.store align=0 (i64.const 0) (f32.const 0))))" + ) + "alignment" +) +(assert_malformed + (module quote + "(module (memory i64 0) (func (f32.store align=7 (i64.const 0) (f32.const 0))))" + ) + "alignment" +) +(assert_malformed + (module quote + "(module (memory i64 0) (func (f64.store align=0 (i64.const 0) (f32.const 0))))" + ) + "alignment" +) +(assert_malformed + (module quote + "(module (memory i64 0) (func (f64.store align=7 (i64.const 0) (f32.const 0))))" + ) + "alignment" +) + +(assert_invalid + (module (memory i64 0) (func (drop (i32.load8_s align=2 (i64.const 0))))) + "alignment must not be larger than natural" +) +(assert_invalid + (module (memory i64 0) (func (drop (i32.load8_u align=2 (i64.const 0))))) + "alignment must not be larger than natural" +) +(assert_invalid + (module (memory i64 0) (func (drop (i32.load16_s align=4 (i64.const 0))))) + "alignment must not be larger than natural" +) +(assert_invalid + (module (memory i64 0) (func (drop (i32.load16_u align=4 (i64.const 0))))) + "alignment must not be larger than natural" +) +(assert_invalid + (module (memory i64 0) (func (drop (i32.load align=8 (i64.const 0))))) + "alignment must not be larger than natural" +) +(assert_invalid + (module (memory i64 0) (func (drop (i64.load8_s align=2 (i64.const 0))))) + "alignment must not be larger than natural" +) +(assert_invalid + (module (memory i64 0) (func (drop (i64.load8_u align=2 (i64.const 0))))) + "alignment must not be larger than natural" +) +(assert_invalid + (module (memory i64 0) (func (drop (i64.load16_s align=4 (i64.const 0))))) + "alignment must not be larger than natural" +) +(assert_invalid + (module (memory i64 0) (func (drop (i64.load16_u align=4 (i64.const 0))))) + "alignment must not be larger than natural" +) +(assert_invalid + (module (memory i64 0) (func (drop (i64.load32_s align=8 (i64.const 0))))) + "alignment must not be larger than natural" +) +(assert_invalid + (module (memory i64 0) (func (drop (i64.load32_u align=8 (i64.const 0))))) + "alignment must not be larger than natural" +) +(assert_invalid + (module (memory i64 0) (func (drop (i64.load align=16 (i64.const 0))))) + "alignment must not be larger than natural" +) +(assert_invalid + (module (memory i64 0) (func (drop (f32.load align=8 (i64.const 0))))) + "alignment must not be larger than natural" +) +(assert_invalid + (module (memory i64 0) (func (drop (f64.load align=16 (i64.const 0))))) + "alignment must not be larger than natural" +) + +(assert_invalid + (module (memory i64 0) (func (drop (i32.load8_s align=2 (i64.const 0))))) + "alignment must not be larger than natural" +) +(assert_invalid + (module (memory i64 0) (func (drop (i32.load8_u align=2 (i64.const 0))))) + "alignment must not be larger than natural" +) +(assert_invalid + (module (memory i64 0) (func (drop (i32.load16_s align=4 (i64.const 0))))) + "alignment must not be larger than natural" +) +(assert_invalid + (module (memory i64 0) (func (drop (i32.load16_u align=4 (i64.const 0))))) + "alignment must not be larger than natural" +) +(assert_invalid + (module (memory i64 0) (func (drop (i32.load align=8 (i64.const 0))))) + "alignment must not be larger than natural" +) +(assert_invalid + (module (memory i64 0) (func (drop (i64.load8_s align=2 (i64.const 0))))) + "alignment must not be larger than natural" +) +(assert_invalid + (module (memory i64 0) (func (drop (i64.load8_u align=2 (i64.const 0))))) + "alignment must not be larger than natural" +) +(assert_invalid + (module (memory i64 0) (func (drop (i64.load16_s align=4 (i64.const 0))))) + "alignment must not be larger than natural" +) +(assert_invalid + (module (memory i64 0) (func (drop (i64.load16_u align=4 (i64.const 0))))) + "alignment must not be larger than natural" +) +(assert_invalid + (module (memory i64 0) (func (drop (i64.load32_s align=8 (i64.const 0))))) + "alignment must not be larger than natural" +) +(assert_invalid + (module (memory i64 0) (func (drop (i64.load32_u align=8 (i64.const 0))))) + "alignment must not be larger than natural" +) +(assert_invalid + (module (memory i64 0) (func (drop (i64.load align=16 (i64.const 0))))) + "alignment must not be larger than natural" +) +(assert_invalid + (module (memory i64 0) (func (drop (f32.load align=8 (i64.const 0))))) + "alignment must not be larger than natural" +) +(assert_invalid + (module (memory i64 0) (func (drop (f64.load align=16 (i64.const 0))))) + "alignment must not be larger than natural" +) + +(assert_invalid + (module (memory i64 0) (func (i32.store8 align=2 (i64.const 0) (i32.const 0)))) + "alignment must not be larger than natural" +) +(assert_invalid + (module (memory i64 0) (func (i32.store16 align=4 (i64.const 0) (i32.const 0)))) + "alignment must not be larger than natural" +) +(assert_invalid + (module (memory i64 0) (func (i32.store align=8 (i64.const 0) (i32.const 0)))) + "alignment must not be larger than natural" +) +(assert_invalid + (module (memory i64 0) (func (i64.store8 align=2 (i64.const 0) (i64.const 0)))) + "alignment must not be larger than natural" +) +(assert_invalid + (module (memory i64 0) (func (i64.store16 align=4 (i64.const 0) (i64.const 0)))) + "alignment must not be larger than natural" +) +(assert_invalid + (module (memory i64 0) (func (i64.store32 align=8 (i64.const 0) (i64.const 0)))) + "alignment must not be larger than natural" +) +(assert_invalid + (module (memory i64 0) (func (i64.store align=16 (i64.const 0) (i64.const 0)))) + "alignment must not be larger than natural" +) +(assert_invalid + (module (memory i64 0) (func (f32.store align=8 (i64.const 0) (f32.const 0)))) + "alignment must not be larger than natural" +) +(assert_invalid + (module (memory i64 0) (func (f64.store align=16 (i64.const 0) (f64.const 0)))) + "alignment must not be larger than natural" +) + +;; Test aligned and unaligned read/write + +(module + (memory i64 1) + + ;; $default: natural alignment, $1: align=1, $2: align=2, $4: align=4, $8: align=8 + + (func (export "f32_align_switch") (param i32) (result f32) + (local f32 f32) + (local.set 1 (f32.const 10.0)) + (block $4 + (block $2 + (block $1 + (block $default + (block $0 + (br_table $0 $default $1 $2 $4 (local.get 0)) + ) ;; 0 + (f32.store (i64.const 0) (local.get 1)) + (local.set 2 (f32.load (i64.const 0))) + (br $4) + ) ;; default + (f32.store align=1 (i64.const 0) (local.get 1)) + (local.set 2 (f32.load align=1 (i64.const 0))) + (br $4) + ) ;; 1 + (f32.store align=2 (i64.const 0) (local.get 1)) + (local.set 2 (f32.load align=2 (i64.const 0))) + (br $4) + ) ;; 2 + (f32.store align=4 (i64.const 0) (local.get 1)) + (local.set 2 (f32.load align=4 (i64.const 0))) + ) ;; 4 + (local.get 2) + ) + + (func (export "f64_align_switch") (param i32) (result f64) + (local f64 f64) + (local.set 1 (f64.const 10.0)) + (block $8 + (block $4 + (block $2 + (block $1 + (block $default + (block $0 + (br_table $0 $default $1 $2 $4 $8 (local.get 0)) + ) ;; 0 + (f64.store (i64.const 0) (local.get 1)) + (local.set 2 (f64.load (i64.const 0))) + (br $8) + ) ;; default + (f64.store align=1 (i64.const 0) (local.get 1)) + (local.set 2 (f64.load align=1 (i64.const 0))) + (br $8) + ) ;; 1 + (f64.store align=2 (i64.const 0) (local.get 1)) + (local.set 2 (f64.load align=2 (i64.const 0))) + (br $8) + ) ;; 2 + (f64.store align=4 (i64.const 0) (local.get 1)) + (local.set 2 (f64.load align=4 (i64.const 0))) + (br $8) + ) ;; 4 + (f64.store align=8 (i64.const 0) (local.get 1)) + (local.set 2 (f64.load align=8 (i64.const 0))) + ) ;; 8 + (local.get 2) + ) + + ;; $8s: i32/i64.load8_s, $8u: i32/i64.load8_u, $16s: i32/i64.load16_s, $16u: i32/i64.load16_u, $32: i32.load + ;; $32s: i64.load32_s, $32u: i64.load32_u, $64: i64.load + + (func (export "i32_align_switch") (param i32 i32) (result i32) + (local i32 i32) + (local.set 2 (i32.const 10)) + (block $32 + (block $16u + (block $16s + (block $8u + (block $8s + (block $0 + (br_table $0 $8s $8u $16s $16u $32 (local.get 0)) + ) ;; 0 + (if (i32.eq (local.get 1) (i32.const 0)) + (then + (i32.store8 (i64.const 0) (local.get 2)) + (local.set 3 (i32.load8_s (i64.const 0))) + ) + ) + (if (i32.eq (local.get 1) (i32.const 1)) + (then + (i32.store8 align=1 (i64.const 0) (local.get 2)) + (local.set 3 (i32.load8_s align=1 (i64.const 0))) + ) + ) + (br $32) + ) ;; 8s + (if (i32.eq (local.get 1) (i32.const 0)) + (then + (i32.store8 (i64.const 0) (local.get 2)) + (local.set 3 (i32.load8_u (i64.const 0))) + ) + ) + (if (i32.eq (local.get 1) (i32.const 1)) + (then + (i32.store8 align=1 (i64.const 0) (local.get 2)) + (local.set 3 (i32.load8_u align=1 (i64.const 0))) + ) + ) + (br $32) + ) ;; 8u + (if (i32.eq (local.get 1) (i32.const 0)) + (then + (i32.store16 (i64.const 0) (local.get 2)) + (local.set 3 (i32.load16_s (i64.const 0))) + ) + ) + (if (i32.eq (local.get 1) (i32.const 1)) + (then + (i32.store16 align=1 (i64.const 0) (local.get 2)) + (local.set 3 (i32.load16_s align=1 (i64.const 0))) + ) + ) + (if (i32.eq (local.get 1) (i32.const 2)) + (then + (i32.store16 align=2 (i64.const 0) (local.get 2)) + (local.set 3 (i32.load16_s align=2 (i64.const 0))) + ) + ) + (br $32) + ) ;; 16s + (if (i32.eq (local.get 1) (i32.const 0)) + (then + (i32.store16 (i64.const 0) (local.get 2)) + (local.set 3 (i32.load16_u (i64.const 0))) + ) + ) + (if (i32.eq (local.get 1) (i32.const 1)) + (then + (i32.store16 align=1 (i64.const 0) (local.get 2)) + (local.set 3 (i32.load16_u align=1 (i64.const 0))) + ) + ) + (if (i32.eq (local.get 1) (i32.const 2)) + (then + (i32.store16 align=2 (i64.const 0) (local.get 2)) + (local.set 3 (i32.load16_u align=2 (i64.const 0))) + ) + ) + (br $32) + ) ;; 16u + (if (i32.eq (local.get 1) (i32.const 0)) + (then + (i32.store (i64.const 0) (local.get 2)) + (local.set 3 (i32.load (i64.const 0))) + ) + ) + (if (i32.eq (local.get 1) (i32.const 1)) + (then + (i32.store align=1 (i64.const 0) (local.get 2)) + (local.set 3 (i32.load align=1 (i64.const 0))) + ) + ) + (if (i32.eq (local.get 1) (i32.const 2)) + (then + (i32.store align=2 (i64.const 0) (local.get 2)) + (local.set 3 (i32.load align=2 (i64.const 0))) + ) + ) + (if (i32.eq (local.get 1) (i32.const 4)) + (then + (i32.store align=4 (i64.const 0) (local.get 2)) + (local.set 3 (i32.load align=4 (i64.const 0))) + ) + ) + ) ;; 32 + (local.get 3) + ) + + (func (export "i64_align_switch") (param i32 i32) (result i64) + (local i64 i64) + (local.set 2 (i64.const 10)) + (block $64 + (block $32u + (block $32s + (block $16u + (block $16s + (block $8u + (block $8s + (block $0 + (br_table $0 $8s $8u $16s $16u $32s $32u $64 (local.get 0)) + ) ;; 0 + (if (i32.eq (local.get 1) (i32.const 0)) + (then + (i64.store8 (i64.const 0) (local.get 2)) + (local.set 3 (i64.load8_s (i64.const 0))) + ) + ) + (if (i32.eq (local.get 1) (i32.const 1)) + (then + (i64.store8 align=1 (i64.const 0) (local.get 2)) + (local.set 3 (i64.load8_s align=1 (i64.const 0))) + ) + ) + (br $64) + ) ;; 8s + (if (i32.eq (local.get 1) (i32.const 0)) + (then + (i64.store8 (i64.const 0) (local.get 2)) + (local.set 3 (i64.load8_u (i64.const 0))) + ) + ) + (if (i32.eq (local.get 1) (i32.const 1)) + (then + (i64.store8 align=1 (i64.const 0) (local.get 2)) + (local.set 3 (i64.load8_u align=1 (i64.const 0))) + ) + ) + (br $64) + ) ;; 8u + (if (i32.eq (local.get 1) (i32.const 0)) + (then + (i64.store16 (i64.const 0) (local.get 2)) + (local.set 3 (i64.load16_s (i64.const 0))) + ) + ) + (if (i32.eq (local.get 1) (i32.const 1)) + (then + (i64.store16 align=1 (i64.const 0) (local.get 2)) + (local.set 3 (i64.load16_s align=1 (i64.const 0))) + ) + ) + (if (i32.eq (local.get 1) (i32.const 2)) + (then + (i64.store16 align=2 (i64.const 0) (local.get 2)) + (local.set 3 (i64.load16_s align=2 (i64.const 0))) + ) + ) + (br $64) + ) ;; 16s + (if (i32.eq (local.get 1) (i32.const 0)) + (then + (i64.store16 (i64.const 0) (local.get 2)) + (local.set 3 (i64.load16_u (i64.const 0))) + ) + ) + (if (i32.eq (local.get 1) (i32.const 1)) + (then + (i64.store16 align=1 (i64.const 0) (local.get 2)) + (local.set 3 (i64.load16_u align=1 (i64.const 0))) + ) + ) + (if (i32.eq (local.get 1) (i32.const 2)) + (then + (i64.store16 align=2 (i64.const 0) (local.get 2)) + (local.set 3 (i64.load16_u align=2 (i64.const 0))) + ) + ) + (br $64) + ) ;; 16u + (if (i32.eq (local.get 1) (i32.const 0)) + (then + (i64.store32 (i64.const 0) (local.get 2)) + (local.set 3 (i64.load32_s (i64.const 0))) + ) + ) + (if (i32.eq (local.get 1) (i32.const 1)) + (then + (i64.store32 align=1 (i64.const 0) (local.get 2)) + (local.set 3 (i64.load32_s align=1 (i64.const 0))) + ) + ) + (if (i32.eq (local.get 1) (i32.const 2)) + (then + (i64.store32 align=2 (i64.const 0) (local.get 2)) + (local.set 3 (i64.load32_s align=2 (i64.const 0))) + ) + ) + (if (i32.eq (local.get 1) (i32.const 4)) + (then + (i64.store32 align=4 (i64.const 0) (local.get 2)) + (local.set 3 (i64.load32_s align=4 (i64.const 0))) + ) + ) + (br $64) + ) ;; 32s + (if (i32.eq (local.get 1) (i32.const 0)) + (then + (i64.store32 (i64.const 0) (local.get 2)) + (local.set 3 (i64.load32_u (i64.const 0))) + ) + ) + (if (i32.eq (local.get 1) (i32.const 1)) + (then + (i64.store32 align=1 (i64.const 0) (local.get 2)) + (local.set 3 (i64.load32_u align=1 (i64.const 0))) + ) + ) + (if (i32.eq (local.get 1) (i32.const 2)) + (then + (i64.store32 align=2 (i64.const 0) (local.get 2)) + (local.set 3 (i64.load32_u align=2 (i64.const 0))) + ) + ) + (if (i32.eq (local.get 1) (i32.const 4)) + (then + (i64.store32 align=4 (i64.const 0) (local.get 2)) + (local.set 3 (i64.load32_u align=4 (i64.const 0))) + ) + ) + (br $64) + ) ;; 32u + (if (i32.eq (local.get 1) (i32.const 0)) + (then + (i64.store (i64.const 0) (local.get 2)) + (local.set 3 (i64.load (i64.const 0))) + ) + ) + (if (i32.eq (local.get 1) (i32.const 1)) + (then + (i64.store align=1 (i64.const 0) (local.get 2)) + (local.set 3 (i64.load align=1 (i64.const 0))) + ) + ) + (if (i32.eq (local.get 1) (i32.const 2)) + (then + (i64.store align=2 (i64.const 0) (local.get 2)) + (local.set 3 (i64.load align=2 (i64.const 0))) + ) + ) + (if (i32.eq (local.get 1) (i32.const 4)) + (then + (i64.store align=4 (i64.const 0) (local.get 2)) + (local.set 3 (i64.load align=4 (i64.const 0))) + ) + ) + (if (i32.eq (local.get 1) (i32.const 8)) + (then + (i64.store align=8 (i64.const 0) (local.get 2)) + (local.set 3 (i64.load align=8 (i64.const 0))) + ) + ) + ) ;; 64 + (local.get 3) + ) +) + +(assert_return (invoke "f32_align_switch" (i32.const 0)) (f32.const 10.0)) +(assert_return (invoke "f32_align_switch" (i32.const 1)) (f32.const 10.0)) +(assert_return (invoke "f32_align_switch" (i32.const 2)) (f32.const 10.0)) +(assert_return (invoke "f32_align_switch" (i32.const 3)) (f32.const 10.0)) + +(assert_return (invoke "f64_align_switch" (i32.const 0)) (f64.const 10.0)) +(assert_return (invoke "f64_align_switch" (i32.const 1)) (f64.const 10.0)) +(assert_return (invoke "f64_align_switch" (i32.const 2)) (f64.const 10.0)) +(assert_return (invoke "f64_align_switch" (i32.const 3)) (f64.const 10.0)) +(assert_return (invoke "f64_align_switch" (i32.const 4)) (f64.const 10.0)) + +(assert_return (invoke "i32_align_switch" (i32.const 0) (i32.const 0)) (i32.const 10)) +(assert_return (invoke "i32_align_switch" (i32.const 0) (i32.const 1)) (i32.const 10)) +(assert_return (invoke "i32_align_switch" (i32.const 1) (i32.const 0)) (i32.const 10)) +(assert_return (invoke "i32_align_switch" (i32.const 1) (i32.const 1)) (i32.const 10)) +(assert_return (invoke "i32_align_switch" (i32.const 2) (i32.const 0)) (i32.const 10)) +(assert_return (invoke "i32_align_switch" (i32.const 2) (i32.const 1)) (i32.const 10)) +(assert_return (invoke "i32_align_switch" (i32.const 2) (i32.const 2)) (i32.const 10)) +(assert_return (invoke "i32_align_switch" (i32.const 3) (i32.const 0)) (i32.const 10)) +(assert_return (invoke "i32_align_switch" (i32.const 3) (i32.const 1)) (i32.const 10)) +(assert_return (invoke "i32_align_switch" (i32.const 3) (i32.const 2)) (i32.const 10)) +(assert_return (invoke "i32_align_switch" (i32.const 4) (i32.const 0)) (i32.const 10)) +(assert_return (invoke "i32_align_switch" (i32.const 4) (i32.const 1)) (i32.const 10)) +(assert_return (invoke "i32_align_switch" (i32.const 4) (i32.const 2)) (i32.const 10)) +(assert_return (invoke "i32_align_switch" (i32.const 4) (i32.const 4)) (i32.const 10)) + +(assert_return (invoke "i64_align_switch" (i32.const 0) (i32.const 0)) (i64.const 10)) +(assert_return (invoke "i64_align_switch" (i32.const 0) (i32.const 1)) (i64.const 10)) +(assert_return (invoke "i64_align_switch" (i32.const 1) (i32.const 0)) (i64.const 10)) +(assert_return (invoke "i64_align_switch" (i32.const 1) (i32.const 1)) (i64.const 10)) +(assert_return (invoke "i64_align_switch" (i32.const 2) (i32.const 0)) (i64.const 10)) +(assert_return (invoke "i64_align_switch" (i32.const 2) (i32.const 1)) (i64.const 10)) +(assert_return (invoke "i64_align_switch" (i32.const 2) (i32.const 2)) (i64.const 10)) +(assert_return (invoke "i64_align_switch" (i32.const 3) (i32.const 0)) (i64.const 10)) +(assert_return (invoke "i64_align_switch" (i32.const 3) (i32.const 1)) (i64.const 10)) +(assert_return (invoke "i64_align_switch" (i32.const 3) (i32.const 2)) (i64.const 10)) +(assert_return (invoke "i64_align_switch" (i32.const 4) (i32.const 0)) (i64.const 10)) +(assert_return (invoke "i64_align_switch" (i32.const 4) (i32.const 1)) (i64.const 10)) +(assert_return (invoke "i64_align_switch" (i32.const 4) (i32.const 2)) (i64.const 10)) +(assert_return (invoke "i64_align_switch" (i32.const 4) (i32.const 4)) (i64.const 10)) +(assert_return (invoke "i64_align_switch" (i32.const 5) (i32.const 0)) (i64.const 10)) +(assert_return (invoke "i64_align_switch" (i32.const 5) (i32.const 1)) (i64.const 10)) +(assert_return (invoke "i64_align_switch" (i32.const 5) (i32.const 2)) (i64.const 10)) +(assert_return (invoke "i64_align_switch" (i32.const 5) (i32.const 4)) (i64.const 10)) +(assert_return (invoke "i64_align_switch" (i32.const 6) (i32.const 0)) (i64.const 10)) +(assert_return (invoke "i64_align_switch" (i32.const 6) (i32.const 1)) (i64.const 10)) +(assert_return (invoke "i64_align_switch" (i32.const 6) (i32.const 2)) (i64.const 10)) +(assert_return (invoke "i64_align_switch" (i32.const 6) (i32.const 4)) (i64.const 10)) +(assert_return (invoke "i64_align_switch" (i32.const 6) (i32.const 8)) (i64.const 10)) + +;; Test that an i64 store with 4-byte alignment that's 4 bytes out of bounds traps without storing anything + +(module + (memory i64 1) + (func (export "store") (param i64 i64) + (i64.store align=4 (local.get 0) (local.get 1)) + ) + (func (export "load") (param i64) (result i32) + (i32.load (local.get 0)) + ) +) + +(assert_trap (invoke "store" (i64.const 65532) (i64.const -1)) "out of bounds memory access") +;; No memory was changed +(assert_return (invoke "load" (i64.const 65532)) (i32.const 0)) diff --git a/test/core/binary-leb128.wast b/test/core/binary-leb128.wast index 335496f08e..c6b79eb95a 100644 --- a/test/core/binary-leb128.wast +++ b/test/core/binary-leb128.wast @@ -217,8 +217,8 @@ (assert_malformed (module binary "\00asm" "\01\00\00\00" - "\05\08\01" ;; Memory section with 1 entry - "\00\82\80\80\80\80\00" ;; no max, minimum 2 with one byte too many + "\05\08\01" ;; Memory section with 1 entry + "\00\82\80\80\80\80\80\80\80\80\80\00" ;; no max, minimum 2 with one byte too many ) "integer representation too long" ) @@ -227,7 +227,7 @@ "\00asm" "\01\00\00\00" "\05\0a\01" ;; Memory section with 1 entry "\01\82\00" ;; minimum 2 - "\82\80\80\80\80\00" ;; max 2 with one byte too many + "\82\80\80\80\80\80\80\80\80\80\00" ;; max 2 with one byte too many ) "integer representation too long" ) @@ -526,7 +526,7 @@ (module binary "\00asm" "\01\00\00\00" "\05\07\01" ;; Memory section with 1 entry - "\00\82\80\80\80\70" ;; no max, minimum 2 with unused bits set + "\00\82\80\80\80\80\80\80\80\80\70" ;; no max, minimum 2 with unused bits set ) "integer too large" ) @@ -534,7 +534,7 @@ (module binary "\00asm" "\01\00\00\00" "\05\07\01" ;; Memory section with 1 entry - "\00\82\80\80\80\40" ;; no max, minimum 2 with some unused bits set + "\00\82\80\80\80\80\80\80\80\80\40" ;; no max, minimum 2 with some unused bits set ) "integer too large" ) @@ -543,7 +543,7 @@ "\00asm" "\01\00\00\00" "\05\09\01" ;; Memory section with 1 entry "\01\82\00" ;; minimum 2 - "\82\80\80\80\10" ;; max 2 with unused bits set + "\82\80\80\80\80\80\80\80\80\10" ;; max 2 with unused bits set ) "integer too large" ) @@ -552,7 +552,7 @@ "\00asm" "\01\00\00\00" "\05\09\01" ;; Memory section with 1 entry "\01\82\00" ;; minimum 2 - "\82\80\80\80\40" ;; max 2 with some unused bits set + "\82\80\80\80\80\80\80\80\80\40" ;; max 2 with some unused bits set ) "integer too large" ) @@ -744,8 +744,7 @@ "\1a" ;; drop "\0b" ;; end ) - ;; TODO: This changes to "integer too large" with memory64. - "integer representation too long" + "integer too large" ) (assert_malformed (module binary @@ -764,8 +763,7 @@ "\1a" ;; drop "\0b" ;; end ) - ;; TODO: This changes to "integer too large" with memory64. - "integer representation too long" + "integer too large" ) (assert_malformed (module binary @@ -859,8 +857,7 @@ "\82\80\80\80\80\80\80\80\80\10" ;; offset 2 with unused bits set "\0b" ;; end ) - ;; TODO: This changes to "integer too large" with memory64. - "integer representation too long" + "integer too large" ) (assert_malformed (module binary @@ -879,8 +876,40 @@ "\82\80\80\80\80\80\80\80\80\40" ;; offset 2 with some unused bits set "\0b" ;; end ) - ;; TODO: This changes to "integer too large" with memory64. - "integer representation too long" + "integer too large" +) +(module binary + "\00asm" "\01\00\00\00" + "\01\04\01\60\00\00" ;; Type section + "\03\02\01\00" ;; Function section + "\05\03\01\04\00" ;; Memory section (flags: i64) + "\0a\13\01" ;; Code section + ;; function 0 + "\11\00" ;; local type count + "\42\00" ;; i64.const 0 + "\28" ;; i32.load + "\02" ;; alignment 2 + "\ff\ff\ff\ff\ff\ff\ff\ff\ff\01" ;; offset 2^64 - 1 + "\1a" ;; drop + "\0b" ;; end +) +(assert_malformed + (module binary + "\00asm" "\01\00\00\00" + "\01\04\01\60\00\00" ;; Type section + "\03\02\01\00" ;; Function section + "\05\03\01\04\00" ;; Memory section (flags: i64) + "\0a\13\01" ;; Code section + ;; function 0 + "\11\00" ;; local type count + "\42\00" ;; i64.const 0 + "\28" ;; i32.load + "\02" ;; alignment 2 + "\ff\ff\ff\ff\ff\ff\ff\ff\ff\02" ;; offset 2^64 (one unused bit set) + "\1a" ;; drop + "\0b" ;; end + ) + "integer too large" ) ;; Signed LEB128s sign-extend diff --git a/test/core/binary.wast b/test/core/binary.wast index a8abbb4204..38813935d7 100644 --- a/test/core/binary.wast +++ b/test/core/binary.wast @@ -615,19 +615,19 @@ "\00asm" "\01\00\00\00" "\04\03\01" ;; table section with one entry "\70" ;; anyfunc - "\02" ;; malformed table limits flag + "\08" ;; malformed table limits flag ) - "integer too large" + "malformed limits flags" ) (assert_malformed (module binary "\00asm" "\01\00\00\00" "\04\04\01" ;; table section with one entry "\70" ;; anyfunc - "\02" ;; malformed table limits flag + "\08" ;; malformed table limits flag "\00" ;; dummy byte ) - "integer too large" + "malformed limits flags" ) (assert_malformed (module binary @@ -637,7 +637,7 @@ "\81\00" ;; malformed table limits flag as LEB128 "\00\00" ;; dummy bytes ) - "integer representation too long" + "malformed limits flags" ) ;; Memory count can be zero @@ -661,18 +661,18 @@ (module binary "\00asm" "\01\00\00\00" "\05\02\01" ;; memory section with one entry - "\02" ;; malformed memory limits flag + "\08" ;; malformed memory limits flag ) - "integer too large" + "malformed limits flags" ) (assert_malformed (module binary "\00asm" "\01\00\00\00" "\05\03\01" ;; memory section with one entry - "\02" ;; malformed memory limits flag + "\08" ;; malformed memory limits flag "\00" ;; dummy byte ) - "integer too large" + "malformed limits flags" ) (assert_malformed (module binary @@ -681,7 +681,7 @@ "\81\00" ;; malformed memory limits flag as LEB128 "\00\00" ;; dummy bytes ) - "integer representation too long" + "malformed limits flags" ) (assert_malformed (module binary @@ -690,7 +690,7 @@ "\81\01" ;; malformed memory limits flag as LEB128 "\00\00" ;; dummy bytes ) - "integer representation too long" + "malformed limits flags" ) ;; Global count can be zero diff --git a/test/core/bulk64._wast b/test/core/bulk64._wast new file mode 100644 index 0000000000..9f82f16670 --- /dev/null +++ b/test/core/bulk64._wast @@ -0,0 +1,179 @@ +;; segment syntax +(module + (memory i64 1) + (data "foo")) + +;; memory.fill +(module + (memory i64 1) + + (func (export "fill") (param i64 i32 i64) + (memory.fill + (local.get 0) + (local.get 1) + (local.get 2))) + + (func (export "load8_u") (param i64) (result i32) + (i32.load8_u (local.get 0))) +) + +;; Basic fill test. +(invoke "fill" (i64.const 1) (i32.const 0xff) (i64.const 3)) +(assert_return (invoke "load8_u" (i64.const 0)) (i32.const 0)) +(assert_return (invoke "load8_u" (i64.const 1)) (i32.const 0xff)) +(assert_return (invoke "load8_u" (i64.const 2)) (i32.const 0xff)) +(assert_return (invoke "load8_u" (i64.const 3)) (i32.const 0xff)) +(assert_return (invoke "load8_u" (i64.const 4)) (i32.const 0)) + +;; Fill value is stored as a byte. +(invoke "fill" (i64.const 0) (i32.const 0xbbaa) (i64.const 2)) +(assert_return (invoke "load8_u" (i64.const 0)) (i32.const 0xaa)) +(assert_return (invoke "load8_u" (i64.const 1)) (i32.const 0xaa)) + +;; Fill all of memory +(invoke "fill" (i64.const 0) (i32.const 0) (i64.const 0x10000)) + +;; Succeed when writing 0 bytes at the end of the region. +(invoke "fill" (i64.const 0x10000) (i32.const 0) (i64.const 0)) + +;; Writing 0 bytes outside of memory limit is NOT allowed. +(assert_trap + (invoke "fill" (i64.const 0x10001) (i32.const 0) (i64.const 0)) + "out of bounds") + +;; memory.copy +(module + (memory i64 1 1) + (data (i64.const 0) "\aa\bb\cc\dd") + + (func (export "copy") (param i64 i64 i64) + (memory.copy + (local.get 0) + (local.get 1) + (local.get 2))) + + (func (export "load8_u") (param i64) (result i32) + (i32.load8_u (local.get 0))) +) + +;; Non-overlapping copy. +(invoke "copy" (i64.const 10) (i64.const 0) (i64.const 4)) + +(assert_return (invoke "load8_u" (i64.const 9)) (i32.const 0)) +(assert_return (invoke "load8_u" (i64.const 10)) (i32.const 0xaa)) +(assert_return (invoke "load8_u" (i64.const 11)) (i32.const 0xbb)) +(assert_return (invoke "load8_u" (i64.const 12)) (i32.const 0xcc)) +(assert_return (invoke "load8_u" (i64.const 13)) (i32.const 0xdd)) +(assert_return (invoke "load8_u" (i64.const 14)) (i32.const 0)) + +;; Overlap, source > dest +(invoke "copy" (i64.const 8) (i64.const 10) (i64.const 4)) +(assert_return (invoke "load8_u" (i64.const 8)) (i32.const 0xaa)) +(assert_return (invoke "load8_u" (i64.const 9)) (i32.const 0xbb)) +(assert_return (invoke "load8_u" (i64.const 10)) (i32.const 0xcc)) +(assert_return (invoke "load8_u" (i64.const 11)) (i32.const 0xdd)) +(assert_return (invoke "load8_u" (i64.const 12)) (i32.const 0xcc)) +(assert_return (invoke "load8_u" (i64.const 13)) (i32.const 0xdd)) + +;; Overlap, source < dest +(invoke "copy" (i64.const 10) (i64.const 7) (i64.const 6)) +(assert_return (invoke "load8_u" (i64.const 10)) (i32.const 0)) +(assert_return (invoke "load8_u" (i64.const 11)) (i32.const 0xaa)) +(assert_return (invoke "load8_u" (i64.const 12)) (i32.const 0xbb)) +(assert_return (invoke "load8_u" (i64.const 13)) (i32.const 0xcc)) +(assert_return (invoke "load8_u" (i64.const 14)) (i32.const 0xdd)) +(assert_return (invoke "load8_u" (i64.const 15)) (i32.const 0xcc)) +(assert_return (invoke "load8_u" (i64.const 16)) (i32.const 0)) + +;; Overlap, source < dest but size is out of bounds +(assert_trap + (invoke "copy" (i64.const 13) (i64.const 11) (i64.const -1)) + "out of bounds") +(assert_return (invoke "load8_u" (i64.const 10)) (i32.const 0)) +(assert_return (invoke "load8_u" (i64.const 11)) (i32.const 0xaa)) +(assert_return (invoke "load8_u" (i64.const 12)) (i32.const 0xbb)) +(assert_return (invoke "load8_u" (i64.const 13)) (i32.const 0xcc)) +(assert_return (invoke "load8_u" (i64.const 14)) (i32.const 0xdd)) +(assert_return (invoke "load8_u" (i64.const 15)) (i32.const 0xcc)) +(assert_return (invoke "load8_u" (i64.const 16)) (i32.const 0)) + +;; Copy ending at memory limit is ok. +(invoke "copy" (i64.const 0xff00) (i64.const 0) (i64.const 0x100)) +(invoke "copy" (i64.const 0xfe00) (i64.const 0xff00) (i64.const 0x100)) + +;; Succeed when copying 0 bytes at the end of the region. +(invoke "copy" (i64.const 0x10000) (i64.const 0) (i64.const 0)) +(invoke "copy" (i64.const 0) (i64.const 0x10000) (i64.const 0)) + +;; Copying 0 bytes outside of memory limit is NOT allowed. +(assert_trap + (invoke "copy" (i64.const 0x10001) (i64.const 0) (i64.const 0)) + "out of bounds") +(assert_trap + (invoke "copy" (i64.const 0) (i64.const 0x10001) (i64.const 0)) + "out of bounds") + +;; memory.init +(module + (memory i64 1) + (data "\aa\bb\cc\dd") + + (func (export "init") (param i64 i32 i32) + (memory.init 0 + (local.get 0) + (local.get 1) + (local.get 2))) + + (func (export "load8_u") (param i64) (result i32) + (i32.load8_u (local.get 0))) +) + +(invoke "init" (i64.const 0) (i32.const 1) (i32.const 2)) +(assert_return (invoke "load8_u" (i64.const 0)) (i32.const 0xbb)) +(assert_return (invoke "load8_u" (i64.const 1)) (i32.const 0xcc)) +(assert_return (invoke "load8_u" (i64.const 2)) (i32.const 0)) + +;; Init ending at memory limit and segment limit is ok. +(invoke "init" (i64.const 0xfffc) (i32.const 0) (i32.const 4)) + +;; Out-of-bounds writes trap, and no partial writes has been made. +(assert_trap (invoke "init" (i64.const 0xfffe) (i32.const 0) (i32.const 3)) + "out of bounds") +(assert_return (invoke "load8_u" (i64.const 0xfffe)) (i32.const 0xcc)) +(assert_return (invoke "load8_u" (i64.const 0xffff)) (i32.const 0xdd)) + +;; Succeed when writing 0 bytes at the end of either region. +(invoke "init" (i64.const 0x10000) (i32.const 0) (i32.const 0)) +(invoke "init" (i64.const 0) (i32.const 4) (i32.const 0)) + +;; Writing 0 bytes outside of memory / segment limit is NOT allowed. +(assert_trap + (invoke "init" (i64.const 0x10001) (i32.const 0) (i32.const 0)) + "out of bounds") +(assert_trap + (invoke "init" (i64.const 0) (i32.const 5) (i32.const 0)) + "out of bounds") + +;; OK to access 0 bytes at offset 0 in a dropped segment. +(invoke "init" (i64.const 0) (i32.const 0) (i32.const 0)) + +;; data.drop +(module + (memory i64 1) + (data "") + (data (i64.const 0) "") + + (func (export "drop_passive") (data.drop 0)) + (func (export "init_passive") + (memory.init 0 (i64.const 0) (i32.const 0) (i32.const 0))) + + (func (export "drop_active") (data.drop 1)) + (func (export "init_active") + (memory.init 1 (i64.const 0) (i32.const 0) (i32.const 0))) +) + +;; OK to drop the same segment multiple times or drop an active segment. +(invoke "init_passive") +(invoke "drop_passive") +(invoke "drop_passive") +(invoke "drop_active") diff --git a/test/core/call_indirect.wast b/test/core/call_indirect.wast index 74b5e8d2e8..cc26b1b044 100644 --- a/test/core/call_indirect.wast +++ b/test/core/call_indirect.wast @@ -61,10 +61,15 @@ ) ) + (table $t64 i64 funcref + (elem $const-i32) + ) + ;; Syntax (func (call_indirect (i32.const 0)) + (call_indirect $t64 (i64.const 0)) (call_indirect (param i64) (i64.const 0) (i32.const 0)) (call_indirect (param i64) (param) (param f64 i32 i64) (i64.const 0) (f64.const 0) (i32.const 0) (i64.const 0) (i32.const 0) @@ -94,6 +99,9 @@ (func (export "type-i32") (result i32) (call_indirect (type $out-i32) (i32.const 0)) ) + (func (export "type-i32-t64") (result i32) + (call_indirect $t64 (type $out-i32) (i64.const 0)) + ) (func (export "type-i64") (result i64) (call_indirect (type $out-i64) (i32.const 1)) ) @@ -474,6 +482,8 @@ (assert_return (invoke "type-f64") (f64.const 0xf64)) (assert_return (invoke "type-f64-i32") (f64.const 0xf64) (i32.const 32)) +(assert_return (invoke "type-i32-t64") (i32.const 0x132)) + (assert_return (invoke "type-index") (i64.const 100)) (assert_return (invoke "type-first-i32") (i32.const 32)) diff --git a/test/core/endianness64.wast b/test/core/endianness64.wast new file mode 100644 index 0000000000..e583ea9b48 --- /dev/null +++ b/test/core/endianness64.wast @@ -0,0 +1,217 @@ +(module + (memory i64 1) + + ;; Stores an i16 value in little-endian-format + (func $i16_store_little (param $address i64) (param $value i32) + (i32.store8 (local.get $address) (local.get $value)) + (i32.store8 (i64.add (local.get $address) (i64.const 1)) (i32.shr_u (local.get $value) (i32.const 8))) + ) + + ;; Stores an i32 value in little-endian format + (func $i32_store_little (param $address i64) (param $value i32) + (call $i16_store_little (local.get $address) (local.get $value)) + (call $i16_store_little (i64.add (local.get $address) (i64.const 2)) (i32.shr_u (local.get $value) (i32.const 16))) + ) + + ;; Stores an i64 value in little-endian format + (func $i64_store_little (param $address i64) (param $value i64) + (call $i32_store_little (local.get $address) (i32.wrap_i64 (local.get $value))) + (call $i32_store_little (i64.add (local.get $address) (i64.const 4)) (i32.wrap_i64 (i64.shr_u (local.get $value) (i64.const 32)))) + ) + + ;; Loads an i16 value in little-endian format + (func $i16_load_little (param $address i64) (result i32) + (i32.or + (i32.load8_u (local.get $address)) + (i32.shl (i32.load8_u (i64.add (local.get $address) (i64.const 1))) (i32.const 8)) + ) + ) + + ;; Loads an i32 value in little-endian format + (func $i32_load_little (param $address i64) (result i32) + (i32.or + (call $i16_load_little (local.get $address)) + (i32.shl (call $i16_load_little (i64.add (local.get $address) (i64.const 2))) (i32.const 16)) + ) + ) + + ;; Loads an i64 value in little-endian format + (func $i64_load_little (param $address i64) (result i64) + (i64.or + (i64.extend_i32_u (call $i32_load_little (local.get $address))) + (i64.shl (i64.extend_i32_u (call $i32_load_little (i64.add (local.get $address) (i64.const 4)))) (i64.const 32)) + ) + ) + + (func (export "i32_load16_s") (param $value i32) (result i32) + (call $i16_store_little (i64.const 0) (local.get $value)) + (i32.load16_s (i64.const 0)) + ) + + (func (export "i32_load16_u") (param $value i32) (result i32) + (call $i16_store_little (i64.const 0) (local.get $value)) + (i32.load16_u (i64.const 0)) + ) + + (func (export "i32_load") (param $value i32) (result i32) + (call $i32_store_little (i64.const 0) (local.get $value)) + (i32.load (i64.const 0)) + ) + + (func (export "i64_load16_s") (param $value i64) (result i64) + (call $i16_store_little (i64.const 0) (i32.wrap_i64 (local.get $value))) + (i64.load16_s (i64.const 0)) + ) + + (func (export "i64_load16_u") (param $value i64) (result i64) + (call $i16_store_little (i64.const 0) (i32.wrap_i64 (local.get $value))) + (i64.load16_u (i64.const 0)) + ) + + (func (export "i64_load32_s") (param $value i64) (result i64) + (call $i32_store_little (i64.const 0) (i32.wrap_i64 (local.get $value))) + (i64.load32_s (i64.const 0)) + ) + + (func (export "i64_load32_u") (param $value i64) (result i64) + (call $i32_store_little (i64.const 0) (i32.wrap_i64 (local.get $value))) + (i64.load32_u (i64.const 0)) + ) + + (func (export "i64_load") (param $value i64) (result i64) + (call $i64_store_little (i64.const 0) (local.get $value)) + (i64.load (i64.const 0)) + ) + + (func (export "f32_load") (param $value f32) (result f32) + (call $i32_store_little (i64.const 0) (i32.reinterpret_f32 (local.get $value))) + (f32.load (i64.const 0)) + ) + + (func (export "f64_load") (param $value f64) (result f64) + (call $i64_store_little (i64.const 0) (i64.reinterpret_f64 (local.get $value))) + (f64.load (i64.const 0)) + ) + + + (func (export "i32_store16") (param $value i32) (result i32) + (i32.store16 (i64.const 0) (local.get $value)) + (call $i16_load_little (i64.const 0)) + ) + + (func (export "i32_store") (param $value i32) (result i32) + (i32.store (i64.const 0) (local.get $value)) + (call $i32_load_little (i64.const 0)) + ) + + (func (export "i64_store16") (param $value i64) (result i64) + (i64.store16 (i64.const 0) (local.get $value)) + (i64.extend_i32_u (call $i16_load_little (i64.const 0))) + ) + + (func (export "i64_store32") (param $value i64) (result i64) + (i64.store32 (i64.const 0) (local.get $value)) + (i64.extend_i32_u (call $i32_load_little (i64.const 0))) + ) + + (func (export "i64_store") (param $value i64) (result i64) + (i64.store (i64.const 0) (local.get $value)) + (call $i64_load_little (i64.const 0)) + ) + + (func (export "f32_store") (param $value f32) (result f32) + (f32.store (i64.const 0) (local.get $value)) + (f32.reinterpret_i32 (call $i32_load_little (i64.const 0))) + ) + + (func (export "f64_store") (param $value f64) (result f64) + (f64.store (i64.const 0) (local.get $value)) + (f64.reinterpret_i64 (call $i64_load_little (i64.const 0))) + ) +) + +(assert_return (invoke "i32_load16_s" (i32.const -1)) (i32.const -1)) +(assert_return (invoke "i32_load16_s" (i32.const -4242)) (i32.const -4242)) +(assert_return (invoke "i32_load16_s" (i32.const 42)) (i32.const 42)) +(assert_return (invoke "i32_load16_s" (i32.const 0x3210)) (i32.const 0x3210)) + +(assert_return (invoke "i32_load16_u" (i32.const -1)) (i32.const 0xFFFF)) +(assert_return (invoke "i32_load16_u" (i32.const -4242)) (i32.const 61294)) +(assert_return (invoke "i32_load16_u" (i32.const 42)) (i32.const 42)) +(assert_return (invoke "i32_load16_u" (i32.const 0xCAFE)) (i32.const 0xCAFE)) + +(assert_return (invoke "i32_load" (i32.const -1)) (i32.const -1)) +(assert_return (invoke "i32_load" (i32.const -42424242)) (i32.const -42424242)) +(assert_return (invoke "i32_load" (i32.const 42424242)) (i32.const 42424242)) +(assert_return (invoke "i32_load" (i32.const 0xABAD1DEA)) (i32.const 0xABAD1DEA)) + +(assert_return (invoke "i64_load16_s" (i64.const -1)) (i64.const -1)) +(assert_return (invoke "i64_load16_s" (i64.const -4242)) (i64.const -4242)) +(assert_return (invoke "i64_load16_s" (i64.const 42)) (i64.const 42)) +(assert_return (invoke "i64_load16_s" (i64.const 0x3210)) (i64.const 0x3210)) + +(assert_return (invoke "i64_load16_u" (i64.const -1)) (i64.const 0xFFFF)) +(assert_return (invoke "i64_load16_u" (i64.const -4242)) (i64.const 61294)) +(assert_return (invoke "i64_load16_u" (i64.const 42)) (i64.const 42)) +(assert_return (invoke "i64_load16_u" (i64.const 0xCAFE)) (i64.const 0xCAFE)) + +(assert_return (invoke "i64_load32_s" (i64.const -1)) (i64.const -1)) +(assert_return (invoke "i64_load32_s" (i64.const -42424242)) (i64.const -42424242)) +(assert_return (invoke "i64_load32_s" (i64.const 42424242)) (i64.const 42424242)) +(assert_return (invoke "i64_load32_s" (i64.const 0x12345678)) (i64.const 0x12345678)) + +(assert_return (invoke "i64_load32_u" (i64.const -1)) (i64.const 0xFFFFFFFF)) +(assert_return (invoke "i64_load32_u" (i64.const -42424242)) (i64.const 4252543054)) +(assert_return (invoke "i64_load32_u" (i64.const 42424242)) (i64.const 42424242)) +(assert_return (invoke "i64_load32_u" (i64.const 0xABAD1DEA)) (i64.const 0xABAD1DEA)) + +(assert_return (invoke "i64_load" (i64.const -1)) (i64.const -1)) +(assert_return (invoke "i64_load" (i64.const -42424242)) (i64.const -42424242)) +(assert_return (invoke "i64_load" (i64.const 0xABAD1DEA)) (i64.const 0xABAD1DEA)) +(assert_return (invoke "i64_load" (i64.const 0xABADCAFEDEAD1DEA)) (i64.const 0xABADCAFEDEAD1DEA)) + +(assert_return (invoke "f32_load" (f32.const -1)) (f32.const -1)) +(assert_return (invoke "f32_load" (f32.const 1234e-5)) (f32.const 1234e-5)) +(assert_return (invoke "f32_load" (f32.const 4242.4242)) (f32.const 4242.4242)) +(assert_return (invoke "f32_load" (f32.const 0x1.fffffep+127)) (f32.const 0x1.fffffep+127)) + +(assert_return (invoke "f64_load" (f64.const -1)) (f64.const -1)) +(assert_return (invoke "f64_load" (f64.const 123456789e-5)) (f64.const 123456789e-5)) +(assert_return (invoke "f64_load" (f64.const 424242.424242)) (f64.const 424242.424242)) +(assert_return (invoke "f64_load" (f64.const 0x1.fffffffffffffp+1023)) (f64.const 0x1.fffffffffffffp+1023)) + + +(assert_return (invoke "i32_store16" (i32.const -1)) (i32.const 0xFFFF)) +(assert_return (invoke "i32_store16" (i32.const -4242)) (i32.const 61294)) +(assert_return (invoke "i32_store16" (i32.const 42)) (i32.const 42)) +(assert_return (invoke "i32_store16" (i32.const 0xCAFE)) (i32.const 0xCAFE)) + +(assert_return (invoke "i32_store" (i32.const -1)) (i32.const -1)) +(assert_return (invoke "i32_store" (i32.const -4242)) (i32.const -4242)) +(assert_return (invoke "i32_store" (i32.const 42424242)) (i32.const 42424242)) +(assert_return (invoke "i32_store" (i32.const 0xDEADCAFE)) (i32.const 0xDEADCAFE)) + +(assert_return (invoke "i64_store16" (i64.const -1)) (i64.const 0xFFFF)) +(assert_return (invoke "i64_store16" (i64.const -4242)) (i64.const 61294)) +(assert_return (invoke "i64_store16" (i64.const 42)) (i64.const 42)) +(assert_return (invoke "i64_store16" (i64.const 0xCAFE)) (i64.const 0xCAFE)) + +(assert_return (invoke "i64_store32" (i64.const -1)) (i64.const 0xFFFFFFFF)) +(assert_return (invoke "i64_store32" (i64.const -4242)) (i64.const 4294963054)) +(assert_return (invoke "i64_store32" (i64.const 42424242)) (i64.const 42424242)) +(assert_return (invoke "i64_store32" (i64.const 0xDEADCAFE)) (i64.const 0xDEADCAFE)) + +(assert_return (invoke "i64_store" (i64.const -1)) (i64.const -1)) +(assert_return (invoke "i64_store" (i64.const -42424242)) (i64.const -42424242)) +(assert_return (invoke "i64_store" (i64.const 0xABAD1DEA)) (i64.const 0xABAD1DEA)) +(assert_return (invoke "i64_store" (i64.const 0xABADCAFEDEAD1DEA)) (i64.const 0xABADCAFEDEAD1DEA)) + +(assert_return (invoke "f32_store" (f32.const -1)) (f32.const -1)) +(assert_return (invoke "f32_store" (f32.const 1234e-5)) (f32.const 1234e-5)) +(assert_return (invoke "f32_store" (f32.const 4242.4242)) (f32.const 4242.4242)) +(assert_return (invoke "f32_store" (f32.const 0x1.fffffep+127)) (f32.const 0x1.fffffep+127)) + +(assert_return (invoke "f64_store" (f64.const -1)) (f64.const -1)) +(assert_return (invoke "f64_store" (f64.const 123456789e-5)) (f64.const 123456789e-5)) +(assert_return (invoke "f64_store" (f64.const 424242.424242)) (f64.const 424242.424242)) +(assert_return (invoke "f64_store" (f64.const 0x1.fffffffffffffp+1023)) (f64.const 0x1.fffffffffffffp+1023)) diff --git a/test/core/float_memory64.wast b/test/core/float_memory64.wast new file mode 100644 index 0000000000..674b254f5a --- /dev/null +++ b/test/core/float_memory64.wast @@ -0,0 +1,157 @@ +;; Test that floating-point load and store are bit-preserving. + +;; Test that load and store do not canonicalize NaNs as x87 does. + +(module + (memory i64 (data "\00\00\a0\7f")) + + (func (export "f32.load") (result f32) (f32.load (i64.const 0))) + (func (export "i32.load") (result i32) (i32.load (i64.const 0))) + (func (export "f32.store") (f32.store (i64.const 0) (f32.const nan:0x200000))) + (func (export "i32.store") (i32.store (i64.const 0) (i32.const 0x7fa00000))) + (func (export "reset") (i32.store (i64.const 0) (i32.const 0))) +) + +(assert_return (invoke "i32.load") (i32.const 0x7fa00000)) +(assert_return (invoke "f32.load") (f32.const nan:0x200000)) +(invoke "reset") +(assert_return (invoke "i32.load") (i32.const 0x0)) +(assert_return (invoke "f32.load") (f32.const 0.0)) +(invoke "f32.store") +(assert_return (invoke "i32.load") (i32.const 0x7fa00000)) +(assert_return (invoke "f32.load") (f32.const nan:0x200000)) +(invoke "reset") +(assert_return (invoke "i32.load") (i32.const 0x0)) +(assert_return (invoke "f32.load") (f32.const 0.0)) +(invoke "i32.store") +(assert_return (invoke "i32.load") (i32.const 0x7fa00000)) +(assert_return (invoke "f32.load") (f32.const nan:0x200000)) + +(module + (memory i64 (data "\00\00\00\00\00\00\f4\7f")) + + (func (export "f64.load") (result f64) (f64.load (i64.const 0))) + (func (export "i64.load") (result i64) (i64.load (i64.const 0))) + (func (export "f64.store") (f64.store (i64.const 0) (f64.const nan:0x4000000000000))) + (func (export "i64.store") (i64.store (i64.const 0) (i64.const 0x7ff4000000000000))) + (func (export "reset") (i64.store (i64.const 0) (i64.const 0))) +) + +(assert_return (invoke "i64.load") (i64.const 0x7ff4000000000000)) +(assert_return (invoke "f64.load") (f64.const nan:0x4000000000000)) +(invoke "reset") +(assert_return (invoke "i64.load") (i64.const 0x0)) +(assert_return (invoke "f64.load") (f64.const 0.0)) +(invoke "f64.store") +(assert_return (invoke "i64.load") (i64.const 0x7ff4000000000000)) +(assert_return (invoke "f64.load") (f64.const nan:0x4000000000000)) +(invoke "reset") +(assert_return (invoke "i64.load") (i64.const 0x0)) +(assert_return (invoke "f64.load") (f64.const 0.0)) +(invoke "i64.store") +(assert_return (invoke "i64.load") (i64.const 0x7ff4000000000000)) +(assert_return (invoke "f64.load") (f64.const nan:0x4000000000000)) + +;; Test that unaligned load and store do not canonicalize NaNs. + +(module + (memory i64 (data "\00\00\00\a0\7f")) + + (func (export "f32.load") (result f32) (f32.load (i64.const 1))) + (func (export "i32.load") (result i32) (i32.load (i64.const 1))) + (func (export "f32.store") (f32.store (i64.const 1) (f32.const nan:0x200000))) + (func (export "i32.store") (i32.store (i64.const 1) (i32.const 0x7fa00000))) + (func (export "reset") (i32.store (i64.const 1) (i32.const 0))) +) + +(assert_return (invoke "i32.load") (i32.const 0x7fa00000)) +(assert_return (invoke "f32.load") (f32.const nan:0x200000)) +(invoke "reset") +(assert_return (invoke "i32.load") (i32.const 0x0)) +(assert_return (invoke "f32.load") (f32.const 0.0)) +(invoke "f32.store") +(assert_return (invoke "i32.load") (i32.const 0x7fa00000)) +(assert_return (invoke "f32.load") (f32.const nan:0x200000)) +(invoke "reset") +(assert_return (invoke "i32.load") (i32.const 0x0)) +(assert_return (invoke "f32.load") (f32.const 0.0)) +(invoke "i32.store") +(assert_return (invoke "i32.load") (i32.const 0x7fa00000)) +(assert_return (invoke "f32.load") (f32.const nan:0x200000)) + +(module + (memory i64 (data "\00\00\00\00\00\00\00\f4\7f")) + + (func (export "f64.load") (result f64) (f64.load (i64.const 1))) + (func (export "i64.load") (result i64) (i64.load (i64.const 1))) + (func (export "f64.store") (f64.store (i64.const 1) (f64.const nan:0x4000000000000))) + (func (export "i64.store") (i64.store (i64.const 1) (i64.const 0x7ff4000000000000))) + (func (export "reset") (i64.store (i64.const 1) (i64.const 0))) +) + +(assert_return (invoke "i64.load") (i64.const 0x7ff4000000000000)) +(assert_return (invoke "f64.load") (f64.const nan:0x4000000000000)) +(invoke "reset") +(assert_return (invoke "i64.load") (i64.const 0x0)) +(assert_return (invoke "f64.load") (f64.const 0.0)) +(invoke "f64.store") +(assert_return (invoke "i64.load") (i64.const 0x7ff4000000000000)) +(assert_return (invoke "f64.load") (f64.const nan:0x4000000000000)) +(invoke "reset") +(assert_return (invoke "i64.load") (i64.const 0x0)) +(assert_return (invoke "f64.load") (f64.const 0.0)) +(invoke "i64.store") +(assert_return (invoke "i64.load") (i64.const 0x7ff4000000000000)) +(assert_return (invoke "f64.load") (f64.const nan:0x4000000000000)) + +;; Test that load and store do not canonicalize NaNs as some JS engines do. + +(module + (memory i64 (data "\01\00\d0\7f")) + + (func (export "f32.load") (result f32) (f32.load (i64.const 0))) + (func (export "i32.load") (result i32) (i32.load (i64.const 0))) + (func (export "f32.store") (f32.store (i64.const 0) (f32.const nan:0x500001))) + (func (export "i32.store") (i32.store (i64.const 0) (i32.const 0x7fd00001))) + (func (export "reset") (i32.store (i64.const 0) (i32.const 0))) +) + +(assert_return (invoke "i32.load") (i32.const 0x7fd00001)) +(assert_return (invoke "f32.load") (f32.const nan:0x500001)) +(invoke "reset") +(assert_return (invoke "i32.load") (i32.const 0x0)) +(assert_return (invoke "f32.load") (f32.const 0.0)) +(invoke "f32.store") +(assert_return (invoke "i32.load") (i32.const 0x7fd00001)) +(assert_return (invoke "f32.load") (f32.const nan:0x500001)) +(invoke "reset") +(assert_return (invoke "i32.load") (i32.const 0x0)) +(assert_return (invoke "f32.load") (f32.const 0.0)) +(invoke "i32.store") +(assert_return (invoke "i32.load") (i32.const 0x7fd00001)) +(assert_return (invoke "f32.load") (f32.const nan:0x500001)) + +(module + (memory i64 (data "\01\00\00\00\00\00\fc\7f")) + + (func (export "f64.load") (result f64) (f64.load (i64.const 0))) + (func (export "i64.load") (result i64) (i64.load (i64.const 0))) + (func (export "f64.store") (f64.store (i64.const 0) (f64.const nan:0xc000000000001))) + (func (export "i64.store") (i64.store (i64.const 0) (i64.const 0x7ffc000000000001))) + (func (export "reset") (i64.store (i64.const 0) (i64.const 0))) +) + +(assert_return (invoke "i64.load") (i64.const 0x7ffc000000000001)) +(assert_return (invoke "f64.load") (f64.const nan:0xc000000000001)) +(invoke "reset") +(assert_return (invoke "i64.load") (i64.const 0x0)) +(assert_return (invoke "f64.load") (f64.const 0.0)) +(invoke "f64.store") +(assert_return (invoke "i64.load") (i64.const 0x7ffc000000000001)) +(assert_return (invoke "f64.load") (f64.const nan:0xc000000000001)) +(invoke "reset") +(assert_return (invoke "i64.load") (i64.const 0x0)) +(assert_return (invoke "f64.load") (f64.const 0.0)) +(invoke "i64.store") +(assert_return (invoke "i64.load") (i64.const 0x7ffc000000000001)) +(assert_return (invoke "f64.load") (f64.const nan:0xc000000000001)) diff --git a/test/core/gc/array.wast b/test/core/gc/array.wast index 6ad95c0873..cebf20069e 100644 --- a/test/core/gc/array.wast +++ b/test/core/gc/array.wast @@ -158,6 +158,10 @@ (array.new_data $vec $d (i32.const 1) (i32.const 3)) ) + (func $new-overflow (export "new-overflow") (result (ref $vec)) + (array.new_data $vec $d (i32.const 0x8000_0000) (i32.const 0x8000_0000)) + ) + (func $get_u (param $i i32) (param $v (ref $vec)) (result i32) (array.get_u $vec (local.get $v) (local.get $i)) ) @@ -189,6 +193,10 @@ (func (export "len") (result i32) (call $len (call $new)) ) + + (func (export "drop_segs") + (data.drop $d) + ) ) (assert_return (invoke "new") (ref.array)) @@ -198,10 +206,16 @@ (assert_return (invoke "set_get" (i32.const 1) (i32.const 7)) (i32.const 7)) (assert_return (invoke "len") (i32.const 3)) +(assert_trap (invoke "new-overflow") "out of bounds memory access") (assert_trap (invoke "get_u" (i32.const 10)) "out of bounds array access") (assert_trap (invoke "get_s" (i32.const 10)) "out of bounds array access") (assert_trap (invoke "set_get" (i32.const 10) (i32.const 7)) "out of bounds array access") +(assert_return (invoke "drop_segs")) + +(assert_trap (invoke "new") "out of bounds memory access") +(assert_trap (invoke "new-overflow") "out of bounds memory access") + (module (type $bvec (array i8)) (type $vec (array (ref $bvec))) @@ -218,6 +232,10 @@ (array.new_elem $vec $e (i32.const 0) (i32.const 2)) ) + (func $new-overflow (export "new-overflow") (result (ref $vec)) + (array.new_elem $vec $e (i32.const 0x8000_0000) (i32.const 0x8000_0000)) + ) + (func $sub1 (result (ref $nvec)) (array.new_elem $nvec $e (i32.const 0) (i32.const 2)) ) @@ -249,6 +267,10 @@ (func (export "len") (result i32) (call $len (call $new)) ) + + (func (export "drop_segs") + (elem.drop $e) + ) ) (assert_return (invoke "new") (ref.array)) @@ -258,9 +280,15 @@ (assert_return (invoke "set_get" (i32.const 0) (i32.const 1) (i32.const 1)) (i32.const 2)) (assert_return (invoke "len") (i32.const 2)) +(assert_trap (invoke "new-overflow") "out of bounds table access") (assert_trap (invoke "get" (i32.const 10) (i32.const 0)) "out of bounds array access") (assert_trap (invoke "set_get" (i32.const 10) (i32.const 0) (i32.const 0)) "out of bounds array access") +(assert_return (invoke "drop_segs")) + +(assert_trap (invoke "new") "out of bounds table access") +(assert_trap (invoke "new-overflow") "out of bounds table access") + (assert_invalid (module (type $a (array i64)) diff --git a/test/core/imports.wast b/test/core/imports.wast index af33448de0..e65e5a2769 100644 --- a/test/core/imports.wast +++ b/test/core/imports.wast @@ -13,9 +13,12 @@ (global (export "global-mut-i64") (mut i64) (i64.const 66)) (table (export "table-10-inf") 10 funcref) (table (export "table-10-20") 10 20 funcref) + (table (export "table64-10-inf") i64 10 funcref) + (table (export "table64-10-20") i64 10 20 funcref) (memory (export "memory-2-inf") 2) - ;; Multiple memories are not yet supported - ;; (memory (export "memory-2-4") 2 4) + (memory (export "memory-2-4") 2 4) + (memory (export "memory64-2-inf") i64 2) + (memory (export "memory64-2-4") i64 2 4) (tag (export "tag")) (tag $tag-i32 (param i32)) (export "tag-i32" (tag $tag-i32)) @@ -376,6 +379,7 @@ (module (type (func (result i32))) (import "spectest" "table" (table $tab 10 20 funcref)) + (import "test" "table64-10-inf" (table $tab64 i64 10 funcref)) (elem (table $tab) (i32.const 1) func $f $g) (func (export "call") (param i32) (result i32) @@ -395,6 +399,7 @@ (module (type (func (result i32))) (table $tab (import "spectest" "table") 10 20 funcref) + (table $tab64 (import "test" "table64-10-inf") i64 10 funcref) (elem (table $tab) (i32.const 1) func $f $g) (func (export "call") (param i32) (result i32) @@ -413,8 +418,12 @@ (module (import "spectest" "table" (table 0 funcref)) (import "spectest" "table" (table 0 funcref)) + (import "test" "table64-10-inf" (table i64 10 funcref)) + (import "test" "table64-10-inf" (table i64 10 funcref)) (table 10 funcref) (table 10 funcref) + (table i64 10 funcref) + (table i64 10 funcref) ) (module (import "test" "table-10-inf" (table 10 funcref))) @@ -429,6 +438,18 @@ (module (import "test" "table-10-20" (table 10 25 funcref))) (module (import "test" "table-10-20" (table 5 25 funcref))) (module (import "test" "table-10-20" (table 0 25 funcref))) +(module (import "test" "table64-10-inf" (table i64 10 funcref))) +(module (import "test" "table64-10-inf" (table i64 5 funcref))) +(module (import "test" "table64-10-inf" (table i64 0 funcref))) +(module (import "test" "table64-10-20" (table i64 10 funcref))) +(module (import "test" "table64-10-20" (table i64 5 funcref))) +(module (import "test" "table64-10-20" (table i64 0 funcref))) +(module (import "test" "table64-10-20" (table i64 10 20 funcref))) +(module (import "test" "table64-10-20" (table i64 5 20 funcref))) +(module (import "test" "table64-10-20" (table i64 0 20 funcref))) +(module (import "test" "table64-10-20" (table i64 10 25 funcref))) +(module (import "test" "table64-10-20" (table i64 5 25 funcref))) +(module (import "test" "table64-10-20" (table i64 0 25 funcref))) (module (import "spectest" "table" (table 10 funcref))) (module (import "spectest" "table" (table 5 funcref))) (module (import "spectest" "table" (table 0 funcref))) @@ -455,6 +476,14 @@ (module (import "test" "table-10-inf" (table 10 20 funcref))) "incompatible import type" ) +(assert_unlinkable + (module (import "test" "table64-10-inf" (table i64 12 funcref))) + "incompatible import type" +) +(assert_unlinkable + (module (import "test" "table64-10-inf" (table i64 10 20 funcref))) + "incompatible import type" +) (assert_unlinkable (module (import "test" "table-10-20" (table 12 20 funcref))) "incompatible import type" @@ -463,6 +492,14 @@ (module (import "test" "table-10-20" (table 10 18 funcref))) "incompatible import type" ) +(assert_unlinkable + (module (import "test" "table64-10-20" (table i64 12 20 funcref))) + "incompatible import type" +) +(assert_unlinkable + (module (import "test" "table64-10-20" (table i64 10 18 funcref))) + "incompatible import type" +) (assert_unlinkable (module (import "spectest" "table" (table 12 funcref))) "incompatible import type" @@ -489,12 +526,30 @@ "incompatible import type" ) +(assert_unlinkable + (module (import "test" "table-10-inf" (table i64 10 funcref))) + "incompatible import type" +) +(assert_unlinkable + (module (import "test" "table64-10-inf" (table 10 funcref))) + "incompatible import type" +) +(assert_unlinkable + (module (import "test" "table-10-20" (table i64 10 20 funcref))) + "incompatible import type" +) +(assert_unlinkable + (module (import "test" "table64-10-20" (table 10 20 funcref))) + "incompatible import type" +) ;; Memories (module (import "spectest" "memory" (memory 1 2)) + (import "test" "memory-2-inf" (memory 2)) + (import "test" "memory64-2-inf" (memory i64 2)) (data (memory 0) (i32.const 10) "\10") (func (export "load") (param i32) (result i32) (i32.load (local.get 0))) @@ -507,6 +562,8 @@ (module (memory (import "spectest" "memory") 1 2) + (memory (import "test" "memory-2-inf") 2) + (memory (import "test" "memory64-2-inf") i64 2) (data (memory 0) (i32.const 10) "\10") (func (export "load") (param i32) (result i32) (i32.load (local.get 0))) @@ -519,6 +576,26 @@ (module (import "test" "memory-2-inf" (memory 2))) (module (import "test" "memory-2-inf" (memory 1))) (module (import "test" "memory-2-inf" (memory 0))) +(module (import "test" "memory-2-4" (memory 2))) +(module (import "test" "memory-2-4" (memory 1))) +(module (import "test" "memory-2-4" (memory 0))) +(module (import "test" "memory-2-4" (memory 2 4))) +(module (import "test" "memory-2-4" (memory 1 4))) +(module (import "test" "memory-2-4" (memory 0 4))) +(module (import "test" "memory-2-4" (memory 2 5))) +(module (import "test" "memory-2-4" (memory 2 6))) +(module (import "test" "memory64-2-inf" (memory i64 2))) +(module (import "test" "memory64-2-inf" (memory i64 1))) +(module (import "test" "memory64-2-inf" (memory i64 0))) +(module (import "test" "memory64-2-4" (memory i64 2))) +(module (import "test" "memory64-2-4" (memory i64 1))) +(module (import "test" "memory64-2-4" (memory i64 0))) +(module (import "test" "memory64-2-4" (memory i64 2 4))) +(module (import "test" "memory64-2-4" (memory i64 1 4))) +(module (import "test" "memory64-2-4" (memory i64 0 4))) +(module (import "test" "memory64-2-4" (memory i64 2 5))) +(module (import "test" "memory64-2-4" (memory i64 1 5))) +(module (import "test" "memory64-2-4" (memory i64 0 5))) (module (import "spectest" "memory" (memory 1))) (module (import "spectest" "memory" (memory 0))) (module (import "spectest" "memory" (memory 1 2))) @@ -536,13 +613,149 @@ ) (assert_unlinkable - (module (import "test" "memory-2-inf" (memory 3))) + (module (import "test" "memory-2-inf" (memory 0 1))) + "incompatible import type" +) +(assert_unlinkable + (module (import "test" "memory-2-inf" (memory 0 2))) + "incompatible import type" +) +(assert_unlinkable + (module (import "test" "memory-2-inf" (memory 0 3))) "incompatible import type" ) (assert_unlinkable (module (import "test" "memory-2-inf" (memory 2 3))) "incompatible import type" ) +(assert_unlinkable + (module (import "test" "memory-2-inf" (memory 3))) + "incompatible import type" +) +(assert_unlinkable + (module (import "test" "memory-2-4" (memory 0 1))) + "incompatible import type" +) +(assert_unlinkable + (module (import "test" "memory-2-4" (memory 0 2))) + "incompatible import type" +) +(assert_unlinkable + (module (import "test" "memory-2-4" (memory 0 3))) + "incompatible import type" +) +(assert_unlinkable + (module (import "test" "memory-2-4" (memory 2 2))) + "incompatible import type" +) +(assert_unlinkable + (module (import "test" "memory-2-4" (memory 2 3))) + "incompatible import type" +) +(assert_unlinkable + (module (import "test" "memory-2-4" (memory 3 3))) + "incompatible import type" +) +(assert_unlinkable + (module (import "test" "memory-2-4" (memory 3 4))) + "incompatible import type" +) +(assert_unlinkable + (module (import "test" "memory-2-4" (memory 3 5))) + "incompatible import type" +) +(assert_unlinkable + (module (import "test" "memory-2-4" (memory 4 4))) + "incompatible import type" +) +(assert_unlinkable + (module (import "test" "memory-2-4" (memory 4 5))) + "incompatible import type" +) +(assert_unlinkable + (module (import "test" "memory-2-4" (memory 3))) + "incompatible import type" +) +(assert_unlinkable + (module (import "test" "memory-2-4" (memory 4))) + "incompatible import type" +) +(assert_unlinkable + (module (import "test" "memory-2-4" (memory 5))) + "incompatible import type" +) +(assert_unlinkable + (module (import "test" "memory64-2-inf" (memory i64 0 1))) + "incompatible import type" +) +(assert_unlinkable + (module (import "test" "memory64-2-inf" (memory i64 0 2))) + "incompatible import type" +) +(assert_unlinkable + (module (import "test" "memory64-2-inf" (memory i64 0 3))) + "incompatible import type" +) +(assert_unlinkable + (module (import "test" "memory64-2-inf" (memory i64 2 3))) + "incompatible import type" +) +(assert_unlinkable + (module (import "test" "memory64-2-inf" (memory i64 3))) + "incompatible import type" +) +(assert_unlinkable + (module (import "test" "memory64-2-4" (memory i64 0 1))) + "incompatible import type" +) +(assert_unlinkable + (module (import "test" "memory64-2-4" (memory i64 0 2))) + "incompatible import type" +) +(assert_unlinkable + (module (import "test" "memory64-2-4" (memory i64 0 3))) + "incompatible import type" +) +(assert_unlinkable + (module (import "test" "memory64-2-4" (memory i64 2 2))) + "incompatible import type" +) +(assert_unlinkable + (module (import "test" "memory64-2-4" (memory i64 2 3))) + "incompatible import type" +) +(assert_unlinkable + (module (import "test" "memory64-2-4" (memory i64 3 3))) + "incompatible import type" +) +(assert_unlinkable + (module (import "test" "memory64-2-4" (memory i64 3 4))) + "incompatible import type" +) +(assert_unlinkable + (module (import "test" "memory64-2-4" (memory i64 3 5))) + "incompatible import type" +) +(assert_unlinkable + (module (import "test" "memory64-2-4" (memory i64 4 4))) + "incompatible import type" +) +(assert_unlinkable + (module (import "test" "memory64-2-4" (memory i64 4 5))) + "incompatible import type" +) +(assert_unlinkable + (module (import "test" "memory64-2-4" (memory i64 3))) + "incompatible import type" +) +(assert_unlinkable + (module (import "test" "memory64-2-4" (memory i64 4))) + "incompatible import type" +) +(assert_unlinkable + (module (import "test" "memory64-2-4" (memory i64 5))) + "incompatible import type" +) (assert_unlinkable (module (import "spectest" "memory" (memory 2))) "incompatible import type" @@ -552,6 +765,23 @@ "incompatible import type" ) +(assert_unlinkable + (module (import "test" "memory-2-inf" (memory i64 2))) + "incompatible import type" +) +(assert_unlinkable + (module (import "test" "memory64-2-inf" (memory 2))) + "incompatible import type" +) +(assert_unlinkable + (module (import "test" "memory-2-4" (memory i64 2 4))) + "incompatible import type" +) +(assert_unlinkable + (module (import "test" "memory64-2-4" (memory 2 4))) + "incompatible import type" +) + (assert_unlinkable (module (import "test" "func-i32" (memory 1))) "incompatible import type" diff --git a/test/core/load64.wast b/test/core/load64.wast new file mode 100644 index 0000000000..e4a6a98338 --- /dev/null +++ b/test/core/load64.wast @@ -0,0 +1,567 @@ +;; Load operator as the argument of control constructs and instructions + +(module + (memory i64 1) + + (func (export "as-br-value") (result i32) + (block (result i32) (br 0 (i32.load (i64.const 0)))) + ) + + (func (export "as-br_if-cond") + (block (br_if 0 (i32.load (i64.const 0)))) + ) + (func (export "as-br_if-value") (result i32) + (block (result i32) + (drop (br_if 0 (i32.load (i64.const 0)) (i32.const 1))) (i32.const 7) + ) + ) + (func (export "as-br_if-value-cond") (result i32) + (block (result i32) + (drop (br_if 0 (i32.const 6) (i32.load (i64.const 0)))) (i32.const 7) + ) + ) + + (func (export "as-br_table-index") + (block (br_table 0 0 0 (i32.load (i64.const 0)))) + ) + (func (export "as-br_table-value") (result i32) + (block (result i32) + (br_table 0 0 0 (i32.load (i64.const 0)) (i32.const 1)) (i32.const 7) + ) + ) + (func (export "as-br_table-value-index") (result i32) + (block (result i32) + (br_table 0 0 (i32.const 6) (i32.load (i64.const 0))) (i32.const 7) + ) + ) + + (func (export "as-return-value") (result i32) + (return (i32.load (i64.const 0))) + ) + + (func (export "as-if-cond") (result i32) + (if (result i32) (i32.load (i64.const 0)) + (then (i32.const 0)) (else (i32.const 1)) + ) + ) + (func (export "as-if-then") (result i32) + (if (result i32) (i32.const 1) + (then (i32.load (i64.const 0))) (else (i32.const 0)) + ) + ) + (func (export "as-if-else") (result i32) + (if (result i32) (i32.const 0) + (then (i32.const 0)) (else (i32.load (i64.const 0))) + ) + ) + + (func (export "as-select-first") (param i32 i32) (result i32) + (select (i32.load (i64.const 0)) (local.get 0) (local.get 1)) + ) + (func (export "as-select-second") (param i32 i32) (result i32) + (select (local.get 0) (i32.load (i64.const 0)) (local.get 1)) + ) + (func (export "as-select-cond") (result i32) + (select (i32.const 0) (i32.const 1) (i32.load (i64.const 0))) + ) + + (func $f (param i32 i32 i32) (result i32) (i32.const -1)) + (func (export "as-call-first") (result i32) + (call $f (i32.load (i64.const 0)) (i32.const 2) (i32.const 3)) + ) + (func (export "as-call-mid") (result i32) + (call $f (i32.const 1) (i32.load (i64.const 0)) (i32.const 3)) + ) + (func (export "as-call-last") (result i32) + (call $f (i32.const 1) (i32.const 2) (i32.load (i64.const 0))) + ) + + (type $sig (func (param i32 i32 i32) (result i32))) + (table funcref (elem $f)) + (func (export "as-call_indirect-first") (result i32) + (call_indirect (type $sig) + (i32.load (i64.const 0)) (i32.const 2) (i32.const 3) (i32.const 0) + ) + ) + (func (export "as-call_indirect-mid") (result i32) + (call_indirect (type $sig) + (i32.const 1) (i32.load (i64.const 0)) (i32.const 3) (i32.const 0) + ) + ) + (func (export "as-call_indirect-last") (result i32) + (call_indirect (type $sig) + (i32.const 1) (i32.const 2) (i32.load (i64.const 0)) (i32.const 0) + ) + ) + (func (export "as-call_indirect-index") (result i32) + (call_indirect (type $sig) + (i32.const 1) (i32.const 2) (i32.const 3) (i32.load (i64.const 0)) + ) + ) + + (func (export "as-local.set-value") (local i32) + (local.set 0 (i32.load (i64.const 0))) + ) + (func (export "as-local.tee-value") (result i32) (local i32) + (local.tee 0 (i32.load (i64.const 0))) + ) + (global $g (mut i32) (i32.const 0)) + (func (export "as-global.set-value") (local i32) + (global.set $g (i32.load (i64.const 0))) + ) + + (func (export "as-load-address") (result i32) + (i32.load (i64.load (i64.const 0))) + ) + (func (export "as-loadN-address") (result i32) + (i32.load8_s (i64.load (i64.const 0))) + ) + + (func (export "as-store-address") + (i32.store (i64.load (i64.const 0)) (i32.const 7)) + ) + (func (export "as-store-value") + (i32.store (i64.const 2) (i32.load (i64.const 0))) + ) + + (func (export "as-storeN-address") + (i32.store8 (i64.load8_s (i64.const 0)) (i32.const 7)) + ) + (func (export "as-storeN-value") + (i32.store16 (i64.const 2) (i32.load (i64.const 0))) + ) + + (func (export "as-unary-operand") (result i32) + (i32.clz (i32.load (i64.const 100))) + ) + + (func (export "as-binary-left") (result i32) + (i32.add (i32.load (i64.const 100)) (i32.const 10)) + ) + (func (export "as-binary-right") (result i32) + (i32.sub (i32.const 10) (i32.load (i64.const 100))) + ) + + (func (export "as-test-operand") (result i32) + (i32.eqz (i32.load (i64.const 100))) + ) + + (func (export "as-compare-left") (result i32) + (i32.le_s (i32.load (i64.const 100)) (i32.const 10)) + ) + (func (export "as-compare-right") (result i32) + (i32.ne (i32.const 10) (i32.load (i64.const 100))) + ) + + (func (export "as-memory.grow-size") (result i64) + (memory.grow (i64.load (i64.const 100))) + ) +) + +(assert_return (invoke "as-br-value") (i32.const 0)) + +(assert_return (invoke "as-br_if-cond")) +(assert_return (invoke "as-br_if-value") (i32.const 0)) +(assert_return (invoke "as-br_if-value-cond") (i32.const 7)) + +(assert_return (invoke "as-br_table-index")) +(assert_return (invoke "as-br_table-value") (i32.const 0)) +(assert_return (invoke "as-br_table-value-index") (i32.const 6)) + +(assert_return (invoke "as-return-value") (i32.const 0)) + +(assert_return (invoke "as-if-cond") (i32.const 1)) +(assert_return (invoke "as-if-then") (i32.const 0)) +(assert_return (invoke "as-if-else") (i32.const 0)) + +(assert_return (invoke "as-select-first" (i32.const 0) (i32.const 1)) (i32.const 0)) +(assert_return (invoke "as-select-second" (i32.const 0) (i32.const 0)) (i32.const 0)) +(assert_return (invoke "as-select-cond") (i32.const 1)) + +(assert_return (invoke "as-call-first") (i32.const -1)) +(assert_return (invoke "as-call-mid") (i32.const -1)) +(assert_return (invoke "as-call-last") (i32.const -1)) + +(assert_return (invoke "as-call_indirect-first") (i32.const -1)) +(assert_return (invoke "as-call_indirect-mid") (i32.const -1)) +(assert_return (invoke "as-call_indirect-last") (i32.const -1)) +(assert_return (invoke "as-call_indirect-index") (i32.const -1)) + +(assert_return (invoke "as-local.set-value")) +(assert_return (invoke "as-local.tee-value") (i32.const 0)) +(assert_return (invoke "as-global.set-value")) + +(assert_return (invoke "as-load-address") (i32.const 0)) +(assert_return (invoke "as-loadN-address") (i32.const 0)) +(assert_return (invoke "as-store-address")) +(assert_return (invoke "as-store-value")) +(assert_return (invoke "as-storeN-address")) +(assert_return (invoke "as-storeN-value")) + +(assert_return (invoke "as-unary-operand") (i32.const 32)) + +(assert_return (invoke "as-binary-left") (i32.const 10)) +(assert_return (invoke "as-binary-right") (i32.const 10)) + +(assert_return (invoke "as-test-operand") (i32.const 1)) + +(assert_return (invoke "as-compare-left") (i32.const 1)) +(assert_return (invoke "as-compare-right") (i32.const 1)) + +(assert_return (invoke "as-memory.grow-size") (i64.const 1)) + +(assert_malformed + (module quote + "(memory i64 1)" + "(func (param i64) (result i32) (i32.load32 (local.get 0)))" + ) + "unknown operator" +) +(assert_malformed + (module quote + "(memory i64 1)" + "(func (param i64) (result i32) (i32.load32_u (local.get 0)))" + ) + "unknown operator" +) +(assert_malformed + (module quote + "(memory i64 1)" + "(func (param i64) (result i32) (i32.load32_s (local.get 0)))" + ) + "unknown operator" +) +(assert_malformed + (module quote + "(memory i64 1)" + "(func (param i64) (result i32) (i32.load64 (local.get 0)))" + ) + "unknown operator" +) +(assert_malformed + (module quote + "(memory i64 1)" + "(func (param i64) (result i32) (i32.load64_u (local.get 0)))" + ) + "unknown operator" +) +(assert_malformed + (module quote + "(memory i64 1)" + "(func (param i64) (result i32) (i32.load64_s (local.get 0)))" + ) + "unknown operator" +) + +(assert_malformed + (module quote + "(memory i64 1)" + "(func (param i64) (result i64) (i64.load64 (local.get 0)))" + ) + "unknown operator" +) +(assert_malformed + (module quote + "(memory i64 1)" + "(func (param i64) (result i64) (i64.load64_u (local.get 0)))" + ) + "unknown operator" +) +(assert_malformed + (module quote + "(memory i64 1)" + "(func (param i64) (result i64) (i64.load64_s (local.get 0)))" + ) + "unknown operator" +) + +(assert_malformed + (module quote + "(memory i64 1)" + "(func (param i64) (result f32) (f32.load32 (local.get 0)))" + ) + "unknown operator" +) +(assert_malformed + (module quote + "(memory i64 1)" + "(func (param i64) (result f32) (f32.load64 (local.get 0)))" + ) + "unknown operator" +) + +(assert_malformed + (module quote + "(memory i64 1)" + "(func (param i64) (result f64) (f64.load32 (local.get 0)))" + ) + "unknown operator" +) +(assert_malformed + (module quote + "(memory i64 1)" + "(func (param i64) (result f64) (f64.load64 (local.get 0)))" + ) + "unknown operator" +) + + +;; load should have retval + +(assert_invalid + (module (memory i64 1) (func $load_i32 (i32.load (i64.const 0)))) + "type mismatch" +) +(assert_invalid + (module (memory i64 1) (func $load8_s_i32 (i32.load8_s (i64.const 0)))) + "type mismatch" +) +(assert_invalid + (module (memory i64 1) (func $load8_u_i32 (i32.load8_u (i64.const 0)))) + "type mismatch" +) +(assert_invalid + (module (memory i64 1) (func $load16_s_i32 (i32.load16_s (i64.const 0)))) + "type mismatch" +) +(assert_invalid + (module (memory i64 1) (func $load16_u_i32 (i32.load16_u (i64.const 0)))) + "type mismatch" +) +(assert_invalid + (module (memory i64 1) (func $load_i64 (i64.load (i64.const 0)))) + "type mismatch" +) +(assert_invalid + (module (memory i64 1) (func $load8_s_i64 (i64.load8_s (i64.const 0)))) + "type mismatch" +) +(assert_invalid + (module (memory i64 1) (func $load8_u_i64 (i64.load8_u (i64.const 0)))) + "type mismatch" +) +(assert_invalid + (module (memory i64 1) (func $load16_s_i64 (i64.load16_s (i64.const 0)))) + "type mismatch" +) +(assert_invalid + (module (memory i64 1) (func $load16_u_i64 (i64.load16_u (i64.const 0)))) + "type mismatch" +) +(assert_invalid + (module (memory i64 1) (func $load32_s_i64 (i64.load32_s (i64.const 0)))) + "type mismatch" +) +(assert_invalid + (module (memory i64 1) (func $load32_u_i64 (i64.load32_u (i64.const 0)))) + "type mismatch" +) +(assert_invalid + (module (memory i64 1) (func $load_f32 (f32.load (i64.const 0)))) + "type mismatch" +) +(assert_invalid + (module (memory i64 1) (func $load_f64 (f64.load (i64.const 0)))) + "type mismatch" +) + + +;; Type check + +(assert_invalid (module (memory i64 1) (func (result i32) (i32.load (f32.const 0)))) "type mismatch") +(assert_invalid (module (memory i64 1) (func (result i32) (i32.load8_s (f32.const 0)))) "type mismatch") +(assert_invalid (module (memory i64 1) (func (result i32) (i32.load8_u (f32.const 0)))) "type mismatch") +(assert_invalid (module (memory i64 1) (func (result i32) (i32.load16_s (f32.const 0)))) "type mismatch") +(assert_invalid (module (memory i64 1) (func (result i32) (i32.load16_u (f32.const 0)))) "type mismatch") +(assert_invalid (module (memory i64 1) (func (result i64) (i64.load (f32.const 0)))) "type mismatch") +(assert_invalid (module (memory i64 1) (func (result i64) (i64.load8_s (f32.const 0)))) "type mismatch") +(assert_invalid (module (memory i64 1) (func (result i64) (i64.load8_u (f32.const 0)))) "type mismatch") +(assert_invalid (module (memory i64 1) (func (result i64) (i64.load16_s (f32.const 0)))) "type mismatch") +(assert_invalid (module (memory i64 1) (func (result i64) (i64.load16_u (f32.const 0)))) "type mismatch") +(assert_invalid (module (memory i64 1) (func (result i64) (i64.load32_s (f32.const 0)))) "type mismatch") +(assert_invalid (module (memory i64 1) (func (result i64) (i64.load32_u (f32.const 0)))) "type mismatch") +(assert_invalid (module (memory i64 1) (func (result f32) (f32.load (f32.const 0)))) "type mismatch") +(assert_invalid (module (memory i64 1) (func (result f64) (f64.load (f32.const 0)))) "type mismatch") + + +(assert_invalid + (module + (memory i64 0) + (func $type-address-empty + (i32.load) (drop) + ) + ) + "type mismatch" +) +(assert_invalid + (module + (memory i64 0) + (func $type-address-empty-in-block + (i32.const 0) + (block (i32.load) (drop)) + ) + ) + "type mismatch" +) +(assert_invalid + (module + (memory i64 0) + (func $type-address-empty-in-loop + (i32.const 0) + (loop (i32.load) (drop)) + ) + ) + "type mismatch" +) +(assert_invalid + (module + (memory i64 0) + (func $type-address-empty-in-then + (i32.const 0) (i32.const 0) + (if (then (i32.load) (drop))) + ) + ) + "type mismatch" +) +(assert_invalid + (module + (memory i64 0) + (func $type-address-empty-in-else + (i32.const 0) (i32.const 0) + (if (result i32) (then (i32.const 0)) (else (i32.load))) (drop) + ) + ) + "type mismatch" +) +(assert_invalid + (module + (memory i64 0) + (func $type-address-empty-in-br + (i32.const 0) + (block (br 0 (i32.load)) (drop)) + ) + ) + "type mismatch" +) +(assert_invalid + (module + (memory i64 0) + (func $type-address-empty-in-br_if + (i32.const 0) + (block (br_if 0 (i32.load) (i32.const 1)) (drop)) + ) + ) + "type mismatch" +) +(assert_invalid + (module + (memory i64 0) + (func $type-address-empty-in-br_table + (i32.const 0) + (block (br_table 0 (i32.load)) (drop)) + ) + ) + "type mismatch" +) +(assert_invalid + (module + (memory i64 0) + (func $type-address-empty-in-return + (return (i32.load)) (drop) + ) + ) + "type mismatch" +) +(assert_invalid + (module + (memory i64 0) + (func $type-address-empty-in-select + (select (i32.load) (i32.const 1) (i32.const 2)) (drop) + ) + ) + "type mismatch" +) +(assert_invalid + (module + (memory i64 0) + (func $type-address-empty-in-call + (call 1 (i32.load)) (drop) + ) + (func (param i32) (result i32) (local.get 0)) + ) + "type mismatch" +) +(assert_invalid + (module + (memory i64 0) + (func $f (param i32) (result i32) (local.get 0)) + (type $sig (func (param i32) (result i32))) + (table funcref (elem $f)) + (func $type-address-empty-in-call_indirect + (block (result i32) + (call_indirect (type $sig) + (i32.load) (i32.const 0) + ) + (drop) + ) + ) + ) + "type mismatch" +) +(assert_invalid + (module + (memory i64 0) + (func $type-address-empty-in-local.set + (local i32) + (local.set 0 (i32.load)) (local.get 0) (drop) + ) + ) + "type mismatch" +) +(assert_invalid + (module + (memory i64 0) + (func $type-address-empty-in-local.tee + (local i32) + (local.tee 0 (i32.load)) (drop) + ) + ) + "type mismatch" +) +(assert_invalid + (module + (memory i64 0) + (global $x (mut i32) (i32.const 0)) + (func $type-address-empty-in-global.set + (global.set $x (i32.load)) (global.get $x) (drop) + ) + ) + "type mismatch" +) +(assert_invalid + (module + (memory i64 0) + (func $type-address-empty-in-memory.grow + (memory.grow (i64.load)) (drop) + ) + ) + "type mismatch" +) +(assert_invalid + (module + (memory i64 0) + (func $type-address-empty-in-load + (i32.load (i32.load)) (drop) + ) + ) + "type mismatch" +) +(assert_invalid + (module + (memory i64 1) + (func $type-address-empty-in-store + (i32.store (i32.load) (i32.const 1)) + ) + ) + "type mismatch" +) diff --git a/test/core/memory.wast b/test/core/memory.wast index b54efd3d96..e01170a8f4 100644 --- a/test/core/memory.wast +++ b/test/core/memory.wast @@ -50,40 +50,53 @@ ) (assert_invalid (module (memory 65537)) - "memory size must be at most 65536 pages (4GiB)" + "memory size" ) (assert_invalid (module (memory 2147483648)) - "memory size must be at most 65536 pages (4GiB)" + "memory size" ) (assert_invalid (module (memory 4294967295)) - "memory size must be at most 65536 pages (4GiB)" + "memory size" ) (assert_invalid (module (memory 0 65537)) - "memory size must be at most 65536 pages (4GiB)" + "memory size" ) (assert_invalid (module (memory 0 2147483648)) - "memory size must be at most 65536 pages (4GiB)" + "memory size" ) (assert_invalid (module (memory 0 4294967295)) - "memory size must be at most 65536 pages (4GiB)" + "memory size" ) -(assert_malformed - (module quote "(memory 0x1_0000_0000)") - "i32 constant out of range" +(assert_invalid + (module (memory 0x1_0000_0000)) + "memory size" +) +(assert_invalid + (module (memory 0x1_0000_0000 0x1_0000_0000)) + "memory size" +) +(assert_invalid + (module (memory 0 0x1_0000_0000)) + "memory size" ) -(assert_malformed - (module quote "(memory 0x1_0000_0000 0x1_0000_0000)") - "i32 constant out of range" + +(assert_invalid + (module (memory (import "M" "m") 0x1_0000_0000)) + "memory size" ) -(assert_malformed - (module quote "(memory 0 0x1_0000_0000)") - "i32 constant out of range" +(assert_invalid + (module (memory (import "M" "m") 0x1_0000_0000 0x1_0000_0000)) + "memory size" +) +(assert_invalid + (module (memory (import "M" "m") 0 0x1_0000_0000)) + "memory size" ) (module diff --git a/test/core/memory64.wast b/test/core/memory64.wast new file mode 100644 index 0000000000..ba3b242335 --- /dev/null +++ b/test/core/memory64.wast @@ -0,0 +1,204 @@ +;; Test memory section structure +;; Largely duplicated from memory, but with all memories using a 64-bit index. + +(module (memory i64 0 0)) +(module (memory i64 0 1)) +(module (memory i64 1 256)) +(module (memory i64 0 65536)) + +(module (memory i64 (data)) (func (export "memsize") (result i64) (memory.size))) +(assert_return (invoke "memsize") (i64.const 0)) +(module (memory i64 (data "")) (func (export "memsize") (result i64) (memory.size))) +(assert_return (invoke "memsize") (i64.const 0)) +(module (memory i64 (data "x")) (func (export "memsize") (result i64) (memory.size))) +(assert_return (invoke "memsize") (i64.const 1)) + +(assert_invalid (module (data (i64.const 0))) "unknown memory") +(assert_invalid (module (data (i64.const 0) "")) "unknown memory") +(assert_invalid (module (data (i64.const 0) "x")) "unknown memory") + +(assert_invalid + (module (func (drop (f32.load (i64.const 0))))) + "unknown memory" +) +(assert_invalid + (module (func (f32.store (i64.const 0) (f32.const 0)))) + "unknown memory" +) +(assert_invalid + (module (func (drop (i32.load8_s (i64.const 0))))) + "unknown memory" +) +(assert_invalid + (module (func (i32.store8 (i64.const 0) (i32.const 0)))) + "unknown memory" +) +(assert_invalid + (module (func (drop (memory.size)))) + "unknown memory" +) +(assert_invalid + (module (func (drop (memory.grow (i64.const 0))))) + "unknown memory" +) + + +(assert_invalid + (module (memory i64 1 0)) + "size minimum must not be greater than maximum" +) + +(assert_invalid + (module (memory i64 0x1_0000_0000_0001)) + "memory size" +) +(assert_invalid + (module (memory i64 0 0x1_0000_0000_0001)) + "memory size" +) + +(assert_invalid + (module (memory (import "M" "m") i64 0x1_0000_0000_0001)) + "memory size" +) +(assert_invalid + (module (memory (import "M" "m") i64 0 0x1_0000_0000_0001)) + "memory size" +) + +(module + (memory i64 1) + (data (i64.const 0) "ABC\a7D") (data (i64.const 20) "WASM") + + ;; Data section + (func (export "data") (result i32) + (i32.and + (i32.and + (i32.and + (i32.eq (i32.load8_u (i64.const 0)) (i32.const 65)) + (i32.eq (i32.load8_u (i64.const 3)) (i32.const 167)) + ) + (i32.and + (i32.eq (i32.load8_u (i64.const 6)) (i32.const 0)) + (i32.eq (i32.load8_u (i64.const 19)) (i32.const 0)) + ) + ) + (i32.and + (i32.and + (i32.eq (i32.load8_u (i64.const 20)) (i32.const 87)) + (i32.eq (i32.load8_u (i64.const 23)) (i32.const 77)) + ) + (i32.and + (i32.eq (i32.load8_u (i64.const 24)) (i32.const 0)) + (i32.eq (i32.load8_u (i64.const 1023)) (i32.const 0)) + ) + ) + ) + ) + + ;; Memory cast + (func (export "cast") (result f64) + (i64.store (i64.const 8) (i64.const -12345)) + (if + (f64.eq + (f64.load (i64.const 8)) + (f64.reinterpret_i64 (i64.const -12345)) + ) + (then (return (f64.const 0))) + ) + (i64.store align=1 (i64.const 9) (i64.const 0)) + (i32.store16 align=1 (i64.const 15) (i32.const 16453)) + (f64.load align=1 (i64.const 9)) + ) + + ;; Sign and zero extending memory loads + (func (export "i32_load8_s") (param $i i32) (result i32) + (i32.store8 (i64.const 8) (local.get $i)) + (i32.load8_s (i64.const 8)) + ) + (func (export "i32_load8_u") (param $i i32) (result i32) + (i32.store8 (i64.const 8) (local.get $i)) + (i32.load8_u (i64.const 8)) + ) + (func (export "i32_load16_s") (param $i i32) (result i32) + (i32.store16 (i64.const 8) (local.get $i)) + (i32.load16_s (i64.const 8)) + ) + (func (export "i32_load16_u") (param $i i32) (result i32) + (i32.store16 (i64.const 8) (local.get $i)) + (i32.load16_u (i64.const 8)) + ) + (func (export "i64_load8_s") (param $i i64) (result i64) + (i64.store8 (i64.const 8) (local.get $i)) + (i64.load8_s (i64.const 8)) + ) + (func (export "i64_load8_u") (param $i i64) (result i64) + (i64.store8 (i64.const 8) (local.get $i)) + (i64.load8_u (i64.const 8)) + ) + (func (export "i64_load16_s") (param $i i64) (result i64) + (i64.store16 (i64.const 8) (local.get $i)) + (i64.load16_s (i64.const 8)) + ) + (func (export "i64_load16_u") (param $i i64) (result i64) + (i64.store16 (i64.const 8) (local.get $i)) + (i64.load16_u (i64.const 8)) + ) + (func (export "i64_load32_s") (param $i i64) (result i64) + (i64.store32 (i64.const 8) (local.get $i)) + (i64.load32_s (i64.const 8)) + ) + (func (export "i64_load32_u") (param $i i64) (result i64) + (i64.store32 (i64.const 8) (local.get $i)) + (i64.load32_u (i64.const 8)) + ) +) + +(assert_return (invoke "data") (i32.const 1)) +(assert_return (invoke "cast") (f64.const 42.0)) + +(assert_return (invoke "i32_load8_s" (i32.const -1)) (i32.const -1)) +(assert_return (invoke "i32_load8_u" (i32.const -1)) (i32.const 255)) +(assert_return (invoke "i32_load16_s" (i32.const -1)) (i32.const -1)) +(assert_return (invoke "i32_load16_u" (i32.const -1)) (i32.const 65535)) + +(assert_return (invoke "i32_load8_s" (i32.const 100)) (i32.const 100)) +(assert_return (invoke "i32_load8_u" (i32.const 200)) (i32.const 200)) +(assert_return (invoke "i32_load16_s" (i32.const 20000)) (i32.const 20000)) +(assert_return (invoke "i32_load16_u" (i32.const 40000)) (i32.const 40000)) + +(assert_return (invoke "i32_load8_s" (i32.const 0xfedc6543)) (i32.const 0x43)) +(assert_return (invoke "i32_load8_s" (i32.const 0x3456cdef)) (i32.const 0xffffffef)) +(assert_return (invoke "i32_load8_u" (i32.const 0xfedc6543)) (i32.const 0x43)) +(assert_return (invoke "i32_load8_u" (i32.const 0x3456cdef)) (i32.const 0xef)) +(assert_return (invoke "i32_load16_s" (i32.const 0xfedc6543)) (i32.const 0x6543)) +(assert_return (invoke "i32_load16_s" (i32.const 0x3456cdef)) (i32.const 0xffffcdef)) +(assert_return (invoke "i32_load16_u" (i32.const 0xfedc6543)) (i32.const 0x6543)) +(assert_return (invoke "i32_load16_u" (i32.const 0x3456cdef)) (i32.const 0xcdef)) + +(assert_return (invoke "i64_load8_s" (i64.const -1)) (i64.const -1)) +(assert_return (invoke "i64_load8_u" (i64.const -1)) (i64.const 255)) +(assert_return (invoke "i64_load16_s" (i64.const -1)) (i64.const -1)) +(assert_return (invoke "i64_load16_u" (i64.const -1)) (i64.const 65535)) +(assert_return (invoke "i64_load32_s" (i64.const -1)) (i64.const -1)) +(assert_return (invoke "i64_load32_u" (i64.const -1)) (i64.const 4294967295)) + +(assert_return (invoke "i64_load8_s" (i64.const 100)) (i64.const 100)) +(assert_return (invoke "i64_load8_u" (i64.const 200)) (i64.const 200)) +(assert_return (invoke "i64_load16_s" (i64.const 20000)) (i64.const 20000)) +(assert_return (invoke "i64_load16_u" (i64.const 40000)) (i64.const 40000)) +(assert_return (invoke "i64_load32_s" (i64.const 20000)) (i64.const 20000)) +(assert_return (invoke "i64_load32_u" (i64.const 40000)) (i64.const 40000)) + +(assert_return (invoke "i64_load8_s" (i64.const 0xfedcba9856346543)) (i64.const 0x43)) +(assert_return (invoke "i64_load8_s" (i64.const 0x3456436598bacdef)) (i64.const 0xffffffffffffffef)) +(assert_return (invoke "i64_load8_u" (i64.const 0xfedcba9856346543)) (i64.const 0x43)) +(assert_return (invoke "i64_load8_u" (i64.const 0x3456436598bacdef)) (i64.const 0xef)) +(assert_return (invoke "i64_load16_s" (i64.const 0xfedcba9856346543)) (i64.const 0x6543)) +(assert_return (invoke "i64_load16_s" (i64.const 0x3456436598bacdef)) (i64.const 0xffffffffffffcdef)) +(assert_return (invoke "i64_load16_u" (i64.const 0xfedcba9856346543)) (i64.const 0x6543)) +(assert_return (invoke "i64_load16_u" (i64.const 0x3456436598bacdef)) (i64.const 0xcdef)) +(assert_return (invoke "i64_load32_s" (i64.const 0xfedcba9856346543)) (i64.const 0x56346543)) +(assert_return (invoke "i64_load32_s" (i64.const 0x3456436598bacdef)) (i64.const 0xffffffff98bacdef)) +(assert_return (invoke "i64_load32_u" (i64.const 0xfedcba9856346543)) (i64.const 0x56346543)) +(assert_return (invoke "i64_load32_u" (i64.const 0x3456436598bacdef)) (i64.const 0x98bacdef)) diff --git a/test/core/memory_copy.wast b/test/core/memory_copy.wast index 472995d79d..680bba5a82 100644 --- a/test/core/memory_copy.wast +++ b/test/core/memory_copy.wast @@ -5576,3 +5576,5577 @@ (i32.const -1)) (assert_return (invoke "checkRange" (i32.const 64834) (i32.const 65536) (i32.const 0)) (i32.const -1)) + +(module + (memory (export "memory0") i64 1 1) + (data (i64.const 2) "\03\01\04\01") + (data (i64.const 12) "\07\05\02\03\06") + (func (export "test") + (nop)) + (func (export "load8_u") (param i64) (result i32) + (i32.load8_u (local.get 0)))) + +(invoke "test") + +(assert_return (invoke "load8_u" (i64.const 0)) (i32.const 0)) +(assert_return (invoke "load8_u" (i64.const 1)) (i32.const 0)) +(assert_return (invoke "load8_u" (i64.const 2)) (i32.const 3)) +(assert_return (invoke "load8_u" (i64.const 3)) (i32.const 1)) +(assert_return (invoke "load8_u" (i64.const 4)) (i32.const 4)) +(assert_return (invoke "load8_u" (i64.const 5)) (i32.const 1)) +(assert_return (invoke "load8_u" (i64.const 6)) (i32.const 0)) +(assert_return (invoke "load8_u" (i64.const 7)) (i32.const 0)) +(assert_return (invoke "load8_u" (i64.const 8)) (i32.const 0)) +(assert_return (invoke "load8_u" (i64.const 9)) (i32.const 0)) +(assert_return (invoke "load8_u" (i64.const 10)) (i32.const 0)) +(assert_return (invoke "load8_u" (i64.const 11)) (i32.const 0)) +(assert_return (invoke "load8_u" (i64.const 12)) (i32.const 7)) +(assert_return (invoke "load8_u" (i64.const 13)) (i32.const 5)) +(assert_return (invoke "load8_u" (i64.const 14)) (i32.const 2)) +(assert_return (invoke "load8_u" (i64.const 15)) (i32.const 3)) +(assert_return (invoke "load8_u" (i64.const 16)) (i32.const 6)) +(assert_return (invoke "load8_u" (i64.const 17)) (i32.const 0)) +(assert_return (invoke "load8_u" (i64.const 18)) (i32.const 0)) +(assert_return (invoke "load8_u" (i64.const 19)) (i32.const 0)) +(assert_return (invoke "load8_u" (i64.const 20)) (i32.const 0)) +(assert_return (invoke "load8_u" (i64.const 21)) (i32.const 0)) +(assert_return (invoke "load8_u" (i64.const 22)) (i32.const 0)) +(assert_return (invoke "load8_u" (i64.const 23)) (i32.const 0)) +(assert_return (invoke "load8_u" (i64.const 24)) (i32.const 0)) +(assert_return (invoke "load8_u" (i64.const 25)) (i32.const 0)) +(assert_return (invoke "load8_u" (i64.const 26)) (i32.const 0)) +(assert_return (invoke "load8_u" (i64.const 27)) (i32.const 0)) +(assert_return (invoke "load8_u" (i64.const 28)) (i32.const 0)) +(assert_return (invoke "load8_u" (i64.const 29)) (i32.const 0)) + +(module + (memory (export "memory0") i64 1 1) + (data (i64.const 2) "\03\01\04\01") + (data (i64.const 12) "\07\05\02\03\06") + (func (export "test") + (memory.copy (i64.const 13) (i64.const 2) (i64.const 3))) + (func (export "load8_u") (param i64) (result i32) + (i32.load8_u (local.get 0)))) + +(invoke "test") + +(assert_return (invoke "load8_u" (i64.const 0)) (i32.const 0)) +(assert_return (invoke "load8_u" (i64.const 1)) (i32.const 0)) +(assert_return (invoke "load8_u" (i64.const 2)) (i32.const 3)) +(assert_return (invoke "load8_u" (i64.const 3)) (i32.const 1)) +(assert_return (invoke "load8_u" (i64.const 4)) (i32.const 4)) +(assert_return (invoke "load8_u" (i64.const 5)) (i32.const 1)) +(assert_return (invoke "load8_u" (i64.const 6)) (i32.const 0)) +(assert_return (invoke "load8_u" (i64.const 7)) (i32.const 0)) +(assert_return (invoke "load8_u" (i64.const 8)) (i32.const 0)) +(assert_return (invoke "load8_u" (i64.const 9)) (i32.const 0)) +(assert_return (invoke "load8_u" (i64.const 10)) (i32.const 0)) +(assert_return (invoke "load8_u" (i64.const 11)) (i32.const 0)) +(assert_return (invoke "load8_u" (i64.const 12)) (i32.const 7)) +(assert_return (invoke "load8_u" (i64.const 13)) (i32.const 3)) +(assert_return (invoke "load8_u" (i64.const 14)) (i32.const 1)) +(assert_return (invoke "load8_u" (i64.const 15)) (i32.const 4)) +(assert_return (invoke "load8_u" (i64.const 16)) (i32.const 6)) +(assert_return (invoke "load8_u" (i64.const 17)) (i32.const 0)) +(assert_return (invoke "load8_u" (i64.const 18)) (i32.const 0)) +(assert_return (invoke "load8_u" (i64.const 19)) (i32.const 0)) +(assert_return (invoke "load8_u" (i64.const 20)) (i32.const 0)) +(assert_return (invoke "load8_u" (i64.const 21)) (i32.const 0)) +(assert_return (invoke "load8_u" (i64.const 22)) (i32.const 0)) +(assert_return (invoke "load8_u" (i64.const 23)) (i32.const 0)) +(assert_return (invoke "load8_u" (i64.const 24)) (i32.const 0)) +(assert_return (invoke "load8_u" (i64.const 25)) (i32.const 0)) +(assert_return (invoke "load8_u" (i64.const 26)) (i32.const 0)) +(assert_return (invoke "load8_u" (i64.const 27)) (i32.const 0)) +(assert_return (invoke "load8_u" (i64.const 28)) (i32.const 0)) +(assert_return (invoke "load8_u" (i64.const 29)) (i32.const 0)) + +(module + (memory (export "memory0") i64 1 1) + (data (i64.const 2) "\03\01\04\01") + (data (i64.const 12) "\07\05\02\03\06") + (func (export "test") + (memory.copy (i64.const 25) (i64.const 15) (i64.const 2))) + (func (export "load8_u") (param i64) (result i32) + (i32.load8_u (local.get 0)))) + +(invoke "test") + +(assert_return (invoke "load8_u" (i64.const 0)) (i32.const 0)) +(assert_return (invoke "load8_u" (i64.const 1)) (i32.const 0)) +(assert_return (invoke "load8_u" (i64.const 2)) (i32.const 3)) +(assert_return (invoke "load8_u" (i64.const 3)) (i32.const 1)) +(assert_return (invoke "load8_u" (i64.const 4)) (i32.const 4)) +(assert_return (invoke "load8_u" (i64.const 5)) (i32.const 1)) +(assert_return (invoke "load8_u" (i64.const 6)) (i32.const 0)) +(assert_return (invoke "load8_u" (i64.const 7)) (i32.const 0)) +(assert_return (invoke "load8_u" (i64.const 8)) (i32.const 0)) +(assert_return (invoke "load8_u" (i64.const 9)) (i32.const 0)) +(assert_return (invoke "load8_u" (i64.const 10)) (i32.const 0)) +(assert_return (invoke "load8_u" (i64.const 11)) (i32.const 0)) +(assert_return (invoke "load8_u" (i64.const 12)) (i32.const 7)) +(assert_return (invoke "load8_u" (i64.const 13)) (i32.const 5)) +(assert_return (invoke "load8_u" (i64.const 14)) (i32.const 2)) +(assert_return (invoke "load8_u" (i64.const 15)) (i32.const 3)) +(assert_return (invoke "load8_u" (i64.const 16)) (i32.const 6)) +(assert_return (invoke "load8_u" (i64.const 17)) (i32.const 0)) +(assert_return (invoke "load8_u" (i64.const 18)) (i32.const 0)) +(assert_return (invoke "load8_u" (i64.const 19)) (i32.const 0)) +(assert_return (invoke "load8_u" (i64.const 20)) (i32.const 0)) +(assert_return (invoke "load8_u" (i64.const 21)) (i32.const 0)) +(assert_return (invoke "load8_u" (i64.const 22)) (i32.const 0)) +(assert_return (invoke "load8_u" (i64.const 23)) (i32.const 0)) +(assert_return (invoke "load8_u" (i64.const 24)) (i32.const 0)) +(assert_return (invoke "load8_u" (i64.const 25)) (i32.const 3)) +(assert_return (invoke "load8_u" (i64.const 26)) (i32.const 6)) +(assert_return (invoke "load8_u" (i64.const 27)) (i32.const 0)) +(assert_return (invoke "load8_u" (i64.const 28)) (i32.const 0)) +(assert_return (invoke "load8_u" (i64.const 29)) (i32.const 0)) + +(module + (memory (export "memory0") i64 1 1) + (data (i64.const 2) "\03\01\04\01") + (data (i64.const 12) "\07\05\02\03\06") + (func (export "test") + (memory.copy (i64.const 13) (i64.const 25) (i64.const 3))) + (func (export "load8_u") (param i64) (result i32) + (i32.load8_u (local.get 0)))) + +(invoke "test") + +(assert_return (invoke "load8_u" (i64.const 0)) (i32.const 0)) +(assert_return (invoke "load8_u" (i64.const 1)) (i32.const 0)) +(assert_return (invoke "load8_u" (i64.const 2)) (i32.const 3)) +(assert_return (invoke "load8_u" (i64.const 3)) (i32.const 1)) +(assert_return (invoke "load8_u" (i64.const 4)) (i32.const 4)) +(assert_return (invoke "load8_u" (i64.const 5)) (i32.const 1)) +(assert_return (invoke "load8_u" (i64.const 6)) (i32.const 0)) +(assert_return (invoke "load8_u" (i64.const 7)) (i32.const 0)) +(assert_return (invoke "load8_u" (i64.const 8)) (i32.const 0)) +(assert_return (invoke "load8_u" (i64.const 9)) (i32.const 0)) +(assert_return (invoke "load8_u" (i64.const 10)) (i32.const 0)) +(assert_return (invoke "load8_u" (i64.const 11)) (i32.const 0)) +(assert_return (invoke "load8_u" (i64.const 12)) (i32.const 7)) +(assert_return (invoke "load8_u" (i64.const 13)) (i32.const 0)) +(assert_return (invoke "load8_u" (i64.const 14)) (i32.const 0)) +(assert_return (invoke "load8_u" (i64.const 15)) (i32.const 0)) +(assert_return (invoke "load8_u" (i64.const 16)) (i32.const 6)) +(assert_return (invoke "load8_u" (i64.const 17)) (i32.const 0)) +(assert_return (invoke "load8_u" (i64.const 18)) (i32.const 0)) +(assert_return (invoke "load8_u" (i64.const 19)) (i32.const 0)) +(assert_return (invoke "load8_u" (i64.const 20)) (i32.const 0)) +(assert_return (invoke "load8_u" (i64.const 21)) (i32.const 0)) +(assert_return (invoke "load8_u" (i64.const 22)) (i32.const 0)) +(assert_return (invoke "load8_u" (i64.const 23)) (i32.const 0)) +(assert_return (invoke "load8_u" (i64.const 24)) (i32.const 0)) +(assert_return (invoke "load8_u" (i64.const 25)) (i32.const 0)) +(assert_return (invoke "load8_u" (i64.const 26)) (i32.const 0)) +(assert_return (invoke "load8_u" (i64.const 27)) (i32.const 0)) +(assert_return (invoke "load8_u" (i64.const 28)) (i32.const 0)) +(assert_return (invoke "load8_u" (i64.const 29)) (i32.const 0)) + +(module + (memory (export "memory0") i64 1 1) + (data (i64.const 2) "\03\01\04\01") + (data (i64.const 12) "\07\05\02\03\06") + (func (export "test") + (memory.copy (i64.const 20) (i64.const 22) (i64.const 4))) + (func (export "load8_u") (param i64) (result i32) + (i32.load8_u (local.get 0)))) + +(invoke "test") + +(assert_return (invoke "load8_u" (i64.const 0)) (i32.const 0)) +(assert_return (invoke "load8_u" (i64.const 1)) (i32.const 0)) +(assert_return (invoke "load8_u" (i64.const 2)) (i32.const 3)) +(assert_return (invoke "load8_u" (i64.const 3)) (i32.const 1)) +(assert_return (invoke "load8_u" (i64.const 4)) (i32.const 4)) +(assert_return (invoke "load8_u" (i64.const 5)) (i32.const 1)) +(assert_return (invoke "load8_u" (i64.const 6)) (i32.const 0)) +(assert_return (invoke "load8_u" (i64.const 7)) (i32.const 0)) +(assert_return (invoke "load8_u" (i64.const 8)) (i32.const 0)) +(assert_return (invoke "load8_u" (i64.const 9)) (i32.const 0)) +(assert_return (invoke "load8_u" (i64.const 10)) (i32.const 0)) +(assert_return (invoke "load8_u" (i64.const 11)) (i32.const 0)) +(assert_return (invoke "load8_u" (i64.const 12)) (i32.const 7)) +(assert_return (invoke "load8_u" (i64.const 13)) (i32.const 5)) +(assert_return (invoke "load8_u" (i64.const 14)) (i32.const 2)) +(assert_return (invoke "load8_u" (i64.const 15)) (i32.const 3)) +(assert_return (invoke "load8_u" (i64.const 16)) (i32.const 6)) +(assert_return (invoke "load8_u" (i64.const 17)) (i32.const 0)) +(assert_return (invoke "load8_u" (i64.const 18)) (i32.const 0)) +(assert_return (invoke "load8_u" (i64.const 19)) (i32.const 0)) +(assert_return (invoke "load8_u" (i64.const 20)) (i32.const 0)) +(assert_return (invoke "load8_u" (i64.const 21)) (i32.const 0)) +(assert_return (invoke "load8_u" (i64.const 22)) (i32.const 0)) +(assert_return (invoke "load8_u" (i64.const 23)) (i32.const 0)) +(assert_return (invoke "load8_u" (i64.const 24)) (i32.const 0)) +(assert_return (invoke "load8_u" (i64.const 25)) (i32.const 0)) +(assert_return (invoke "load8_u" (i64.const 26)) (i32.const 0)) +(assert_return (invoke "load8_u" (i64.const 27)) (i32.const 0)) +(assert_return (invoke "load8_u" (i64.const 28)) (i32.const 0)) +(assert_return (invoke "load8_u" (i64.const 29)) (i32.const 0)) + +(module + (memory (export "memory0") i64 1 1) + (data (i64.const 2) "\03\01\04\01") + (data (i64.const 12) "\07\05\02\03\06") + (func (export "test") + (memory.copy (i64.const 25) (i64.const 1) (i64.const 3))) + (func (export "load8_u") (param i64) (result i32) + (i32.load8_u (local.get 0)))) + +(invoke "test") + +(assert_return (invoke "load8_u" (i64.const 0)) (i32.const 0)) +(assert_return (invoke "load8_u" (i64.const 1)) (i32.const 0)) +(assert_return (invoke "load8_u" (i64.const 2)) (i32.const 3)) +(assert_return (invoke "load8_u" (i64.const 3)) (i32.const 1)) +(assert_return (invoke "load8_u" (i64.const 4)) (i32.const 4)) +(assert_return (invoke "load8_u" (i64.const 5)) (i32.const 1)) +(assert_return (invoke "load8_u" (i64.const 6)) (i32.const 0)) +(assert_return (invoke "load8_u" (i64.const 7)) (i32.const 0)) +(assert_return (invoke "load8_u" (i64.const 8)) (i32.const 0)) +(assert_return (invoke "load8_u" (i64.const 9)) (i32.const 0)) +(assert_return (invoke "load8_u" (i64.const 10)) (i32.const 0)) +(assert_return (invoke "load8_u" (i64.const 11)) (i32.const 0)) +(assert_return (invoke "load8_u" (i64.const 12)) (i32.const 7)) +(assert_return (invoke "load8_u" (i64.const 13)) (i32.const 5)) +(assert_return (invoke "load8_u" (i64.const 14)) (i32.const 2)) +(assert_return (invoke "load8_u" (i64.const 15)) (i32.const 3)) +(assert_return (invoke "load8_u" (i64.const 16)) (i32.const 6)) +(assert_return (invoke "load8_u" (i64.const 17)) (i32.const 0)) +(assert_return (invoke "load8_u" (i64.const 18)) (i32.const 0)) +(assert_return (invoke "load8_u" (i64.const 19)) (i32.const 0)) +(assert_return (invoke "load8_u" (i64.const 20)) (i32.const 0)) +(assert_return (invoke "load8_u" (i64.const 21)) (i32.const 0)) +(assert_return (invoke "load8_u" (i64.const 22)) (i32.const 0)) +(assert_return (invoke "load8_u" (i64.const 23)) (i32.const 0)) +(assert_return (invoke "load8_u" (i64.const 24)) (i32.const 0)) +(assert_return (invoke "load8_u" (i64.const 25)) (i32.const 0)) +(assert_return (invoke "load8_u" (i64.const 26)) (i32.const 3)) +(assert_return (invoke "load8_u" (i64.const 27)) (i32.const 1)) +(assert_return (invoke "load8_u" (i64.const 28)) (i32.const 0)) +(assert_return (invoke "load8_u" (i64.const 29)) (i32.const 0)) + +(module + (memory (export "memory0") i64 1 1) + (data (i64.const 2) "\03\01\04\01") + (data (i64.const 12) "\07\05\02\03\06") + (func (export "test") + (memory.copy (i64.const 10) (i64.const 12) (i64.const 7))) + (func (export "load8_u") (param i64) (result i32) + (i32.load8_u (local.get 0)))) + +(invoke "test") + +(assert_return (invoke "load8_u" (i64.const 0)) (i32.const 0)) +(assert_return (invoke "load8_u" (i64.const 1)) (i32.const 0)) +(assert_return (invoke "load8_u" (i64.const 2)) (i32.const 3)) +(assert_return (invoke "load8_u" (i64.const 3)) (i32.const 1)) +(assert_return (invoke "load8_u" (i64.const 4)) (i32.const 4)) +(assert_return (invoke "load8_u" (i64.const 5)) (i32.const 1)) +(assert_return (invoke "load8_u" (i64.const 6)) (i32.const 0)) +(assert_return (invoke "load8_u" (i64.const 7)) (i32.const 0)) +(assert_return (invoke "load8_u" (i64.const 8)) (i32.const 0)) +(assert_return (invoke "load8_u" (i64.const 9)) (i32.const 0)) +(assert_return (invoke "load8_u" (i64.const 10)) (i32.const 7)) +(assert_return (invoke "load8_u" (i64.const 11)) (i32.const 5)) +(assert_return (invoke "load8_u" (i64.const 12)) (i32.const 2)) +(assert_return (invoke "load8_u" (i64.const 13)) (i32.const 3)) +(assert_return (invoke "load8_u" (i64.const 14)) (i32.const 6)) +(assert_return (invoke "load8_u" (i64.const 15)) (i32.const 0)) +(assert_return (invoke "load8_u" (i64.const 16)) (i32.const 0)) +(assert_return (invoke "load8_u" (i64.const 17)) (i32.const 0)) +(assert_return (invoke "load8_u" (i64.const 18)) (i32.const 0)) +(assert_return (invoke "load8_u" (i64.const 19)) (i32.const 0)) +(assert_return (invoke "load8_u" (i64.const 20)) (i32.const 0)) +(assert_return (invoke "load8_u" (i64.const 21)) (i32.const 0)) +(assert_return (invoke "load8_u" (i64.const 22)) (i32.const 0)) +(assert_return (invoke "load8_u" (i64.const 23)) (i32.const 0)) +(assert_return (invoke "load8_u" (i64.const 24)) (i32.const 0)) +(assert_return (invoke "load8_u" (i64.const 25)) (i32.const 0)) +(assert_return (invoke "load8_u" (i64.const 26)) (i32.const 0)) +(assert_return (invoke "load8_u" (i64.const 27)) (i32.const 0)) +(assert_return (invoke "load8_u" (i64.const 28)) (i32.const 0)) +(assert_return (invoke "load8_u" (i64.const 29)) (i32.const 0)) + +(module + (memory (export "memory0") i64 1 1) + (data (i64.const 2) "\03\01\04\01") + (data (i64.const 12) "\07\05\02\03\06") + (func (export "test") + (memory.copy (i64.const 12) (i64.const 10) (i64.const 7))) + (func (export "load8_u") (param i64) (result i32) + (i32.load8_u (local.get 0)))) + +(invoke "test") + +(assert_return (invoke "load8_u" (i64.const 0)) (i32.const 0)) +(assert_return (invoke "load8_u" (i64.const 1)) (i32.const 0)) +(assert_return (invoke "load8_u" (i64.const 2)) (i32.const 3)) +(assert_return (invoke "load8_u" (i64.const 3)) (i32.const 1)) +(assert_return (invoke "load8_u" (i64.const 4)) (i32.const 4)) +(assert_return (invoke "load8_u" (i64.const 5)) (i32.const 1)) +(assert_return (invoke "load8_u" (i64.const 6)) (i32.const 0)) +(assert_return (invoke "load8_u" (i64.const 7)) (i32.const 0)) +(assert_return (invoke "load8_u" (i64.const 8)) (i32.const 0)) +(assert_return (invoke "load8_u" (i64.const 9)) (i32.const 0)) +(assert_return (invoke "load8_u" (i64.const 10)) (i32.const 0)) +(assert_return (invoke "load8_u" (i64.const 11)) (i32.const 0)) +(assert_return (invoke "load8_u" (i64.const 12)) (i32.const 0)) +(assert_return (invoke "load8_u" (i64.const 13)) (i32.const 0)) +(assert_return (invoke "load8_u" (i64.const 14)) (i32.const 7)) +(assert_return (invoke "load8_u" (i64.const 15)) (i32.const 5)) +(assert_return (invoke "load8_u" (i64.const 16)) (i32.const 2)) +(assert_return (invoke "load8_u" (i64.const 17)) (i32.const 3)) +(assert_return (invoke "load8_u" (i64.const 18)) (i32.const 6)) +(assert_return (invoke "load8_u" (i64.const 19)) (i32.const 0)) +(assert_return (invoke "load8_u" (i64.const 20)) (i32.const 0)) +(assert_return (invoke "load8_u" (i64.const 21)) (i32.const 0)) +(assert_return (invoke "load8_u" (i64.const 22)) (i32.const 0)) +(assert_return (invoke "load8_u" (i64.const 23)) (i32.const 0)) +(assert_return (invoke "load8_u" (i64.const 24)) (i32.const 0)) +(assert_return (invoke "load8_u" (i64.const 25)) (i32.const 0)) +(assert_return (invoke "load8_u" (i64.const 26)) (i32.const 0)) +(assert_return (invoke "load8_u" (i64.const 27)) (i32.const 0)) +(assert_return (invoke "load8_u" (i64.const 28)) (i32.const 0)) +(assert_return (invoke "load8_u" (i64.const 29)) (i32.const 0)) + +(module + (memory (export "mem") 1 1 ) + (data (i32.const 0) "\00\01\02\03\04\05\06\07\08\09\0a\0b\0c\0d\0e\0f\10\11\12\13") + (func (export "run") (param $targetOffs i32) (param $srcOffs i32) (param $len i32) + (memory.copy (local.get $targetOffs) (local.get $srcOffs) (local.get $len))) + (func (export "load8_u") (param i32) (result i32) + (i32.load8_u (local.get 0)))) + +(assert_trap (invoke "run" (i32.const 65516) (i32.const 0) (i32.const 40)) + "out of bounds memory access") + +(assert_return (invoke "load8_u" (i32.const 0)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 1)) (i32.const 1)) +(assert_return (invoke "load8_u" (i32.const 2)) (i32.const 2)) +(assert_return (invoke "load8_u" (i32.const 3)) (i32.const 3)) +(assert_return (invoke "load8_u" (i32.const 4)) (i32.const 4)) +(assert_return (invoke "load8_u" (i32.const 5)) (i32.const 5)) +(assert_return (invoke "load8_u" (i32.const 6)) (i32.const 6)) +(assert_return (invoke "load8_u" (i32.const 7)) (i32.const 7)) +(assert_return (invoke "load8_u" (i32.const 8)) (i32.const 8)) +(assert_return (invoke "load8_u" (i32.const 9)) (i32.const 9)) +(assert_return (invoke "load8_u" (i32.const 10)) (i32.const 10)) +(assert_return (invoke "load8_u" (i32.const 11)) (i32.const 11)) +(assert_return (invoke "load8_u" (i32.const 12)) (i32.const 12)) +(assert_return (invoke "load8_u" (i32.const 13)) (i32.const 13)) +(assert_return (invoke "load8_u" (i32.const 14)) (i32.const 14)) +(assert_return (invoke "load8_u" (i32.const 15)) (i32.const 15)) +(assert_return (invoke "load8_u" (i32.const 16)) (i32.const 16)) +(assert_return (invoke "load8_u" (i32.const 17)) (i32.const 17)) +(assert_return (invoke "load8_u" (i32.const 18)) (i32.const 18)) +(assert_return (invoke "load8_u" (i32.const 19)) (i32.const 19)) +(assert_return (invoke "load8_u" (i32.const 218)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 417)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 616)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 815)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 1014)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 1213)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 1412)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 1611)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 1810)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 2009)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 2208)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 2407)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 2606)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 2805)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 3004)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 3203)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 3402)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 3601)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 3800)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 3999)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 4198)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 4397)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 4596)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 4795)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 4994)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 5193)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 5392)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 5591)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 5790)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 5989)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 6188)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 6387)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 6586)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 6785)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 6984)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 7183)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 7382)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 7581)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 7780)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 7979)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 8178)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 8377)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 8576)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 8775)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 8974)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 9173)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 9372)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 9571)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 9770)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 9969)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 10168)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 10367)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 10566)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 10765)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 10964)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 11163)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 11362)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 11561)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 11760)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 11959)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 12158)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 12357)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 12556)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 12755)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 12954)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 13153)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 13352)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 13551)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 13750)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 13949)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 14148)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 14347)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 14546)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 14745)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 14944)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 15143)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 15342)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 15541)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 15740)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 15939)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 16138)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 16337)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 16536)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 16735)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 16934)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 17133)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 17332)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 17531)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 17730)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 17929)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 18128)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 18327)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 18526)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 18725)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 18924)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 19123)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 19322)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 19521)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 19720)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 19919)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 20118)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 20317)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 20516)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 20715)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 20914)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 21113)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 21312)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 21511)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 21710)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 21909)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 22108)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 22307)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 22506)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 22705)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 22904)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 23103)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 23302)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 23501)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 23700)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 23899)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 24098)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 24297)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 24496)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 24695)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 24894)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 25093)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 25292)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 25491)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 25690)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 25889)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 26088)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 26287)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 26486)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 26685)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 26884)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 27083)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 27282)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 27481)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 27680)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 27879)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 28078)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 28277)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 28476)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 28675)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 28874)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 29073)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 29272)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 29471)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 29670)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 29869)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 30068)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 30267)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 30466)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 30665)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 30864)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 31063)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 31262)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 31461)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 31660)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 31859)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 32058)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 32257)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 32456)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 32655)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 32854)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 33053)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 33252)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 33451)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 33650)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 33849)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 34048)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 34247)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 34446)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 34645)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 34844)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 35043)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 35242)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 35441)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 35640)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 35839)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 36038)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 36237)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 36436)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 36635)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 36834)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 37033)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 37232)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 37431)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 37630)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 37829)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 38028)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 38227)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 38426)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 38625)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 38824)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 39023)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 39222)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 39421)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 39620)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 39819)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 40018)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 40217)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 40416)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 40615)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 40814)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 41013)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 41212)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 41411)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 41610)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 41809)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 42008)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 42207)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 42406)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 42605)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 42804)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 43003)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 43202)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 43401)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 43600)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 43799)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 43998)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 44197)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 44396)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 44595)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 44794)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 44993)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 45192)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 45391)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 45590)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 45789)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 45988)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 46187)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 46386)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 46585)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 46784)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 46983)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 47182)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 47381)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 47580)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 47779)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 47978)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 48177)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 48376)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 48575)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 48774)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 48973)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 49172)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 49371)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 49570)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 49769)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 49968)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 50167)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 50366)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 50565)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 50764)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 50963)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 51162)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 51361)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 51560)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 51759)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 51958)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 52157)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 52356)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 52555)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 52754)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 52953)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 53152)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 53351)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 53550)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 53749)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 53948)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 54147)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 54346)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 54545)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 54744)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 54943)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 55142)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 55341)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 55540)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 55739)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 55938)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 56137)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 56336)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 56535)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 56734)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 56933)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 57132)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 57331)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 57530)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 57729)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 57928)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 58127)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 58326)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 58525)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 58724)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 58923)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 59122)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 59321)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 59520)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 59719)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 59918)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 60117)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 60316)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 60515)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 60714)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 60913)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 61112)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 61311)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 61510)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 61709)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 61908)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 62107)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 62306)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 62505)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 62704)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 62903)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 63102)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 63301)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 63500)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 63699)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 63898)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 64097)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 64296)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 64495)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 64694)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 64893)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 65092)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 65291)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 65490)) (i32.const 0)) + +(module + (memory (export "mem") 1 1 ) + (data (i32.const 0) "\00\01\02\03\04\05\06\07\08\09\0a\0b\0c\0d\0e\0f\10\11\12\13\14") + (func (export "run") (param $targetOffs i32) (param $srcOffs i32) (param $len i32) + (memory.copy (local.get $targetOffs) (local.get $srcOffs) (local.get $len))) + (func (export "load8_u") (param i32) (result i32) + (i32.load8_u (local.get 0)))) + +(assert_trap (invoke "run" (i32.const 65515) (i32.const 0) (i32.const 39)) + "out of bounds memory access") + +(assert_return (invoke "load8_u" (i32.const 0)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 1)) (i32.const 1)) +(assert_return (invoke "load8_u" (i32.const 2)) (i32.const 2)) +(assert_return (invoke "load8_u" (i32.const 3)) (i32.const 3)) +(assert_return (invoke "load8_u" (i32.const 4)) (i32.const 4)) +(assert_return (invoke "load8_u" (i32.const 5)) (i32.const 5)) +(assert_return (invoke "load8_u" (i32.const 6)) (i32.const 6)) +(assert_return (invoke "load8_u" (i32.const 7)) (i32.const 7)) +(assert_return (invoke "load8_u" (i32.const 8)) (i32.const 8)) +(assert_return (invoke "load8_u" (i32.const 9)) (i32.const 9)) +(assert_return (invoke "load8_u" (i32.const 10)) (i32.const 10)) +(assert_return (invoke "load8_u" (i32.const 11)) (i32.const 11)) +(assert_return (invoke "load8_u" (i32.const 12)) (i32.const 12)) +(assert_return (invoke "load8_u" (i32.const 13)) (i32.const 13)) +(assert_return (invoke "load8_u" (i32.const 14)) (i32.const 14)) +(assert_return (invoke "load8_u" (i32.const 15)) (i32.const 15)) +(assert_return (invoke "load8_u" (i32.const 16)) (i32.const 16)) +(assert_return (invoke "load8_u" (i32.const 17)) (i32.const 17)) +(assert_return (invoke "load8_u" (i32.const 18)) (i32.const 18)) +(assert_return (invoke "load8_u" (i32.const 19)) (i32.const 19)) +(assert_return (invoke "load8_u" (i32.const 20)) (i32.const 20)) +(assert_return (invoke "load8_u" (i32.const 219)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 418)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 617)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 816)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 1015)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 1214)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 1413)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 1612)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 1811)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 2010)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 2209)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 2408)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 2607)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 2806)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 3005)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 3204)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 3403)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 3602)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 3801)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 4000)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 4199)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 4398)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 4597)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 4796)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 4995)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 5194)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 5393)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 5592)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 5791)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 5990)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 6189)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 6388)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 6587)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 6786)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 6985)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 7184)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 7383)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 7582)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 7781)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 7980)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 8179)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 8378)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 8577)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 8776)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 8975)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 9174)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 9373)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 9572)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 9771)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 9970)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 10169)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 10368)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 10567)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 10766)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 10965)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 11164)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 11363)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 11562)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 11761)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 11960)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 12159)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 12358)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 12557)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 12756)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 12955)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 13154)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 13353)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 13552)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 13751)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 13950)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 14149)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 14348)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 14547)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 14746)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 14945)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 15144)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 15343)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 15542)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 15741)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 15940)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 16139)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 16338)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 16537)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 16736)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 16935)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 17134)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 17333)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 17532)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 17731)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 17930)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 18129)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 18328)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 18527)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 18726)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 18925)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 19124)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 19323)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 19522)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 19721)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 19920)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 20119)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 20318)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 20517)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 20716)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 20915)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 21114)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 21313)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 21512)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 21711)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 21910)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 22109)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 22308)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 22507)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 22706)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 22905)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 23104)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 23303)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 23502)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 23701)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 23900)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 24099)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 24298)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 24497)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 24696)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 24895)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 25094)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 25293)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 25492)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 25691)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 25890)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 26089)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 26288)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 26487)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 26686)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 26885)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 27084)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 27283)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 27482)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 27681)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 27880)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 28079)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 28278)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 28477)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 28676)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 28875)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 29074)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 29273)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 29472)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 29671)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 29870)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 30069)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 30268)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 30467)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 30666)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 30865)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 31064)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 31263)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 31462)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 31661)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 31860)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 32059)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 32258)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 32457)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 32656)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 32855)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 33054)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 33253)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 33452)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 33651)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 33850)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 34049)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 34248)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 34447)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 34646)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 34845)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 35044)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 35243)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 35442)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 35641)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 35840)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 36039)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 36238)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 36437)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 36636)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 36835)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 37034)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 37233)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 37432)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 37631)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 37830)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 38029)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 38228)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 38427)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 38626)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 38825)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 39024)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 39223)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 39422)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 39621)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 39820)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 40019)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 40218)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 40417)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 40616)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 40815)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 41014)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 41213)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 41412)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 41611)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 41810)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 42009)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 42208)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 42407)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 42606)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 42805)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 43004)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 43203)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 43402)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 43601)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 43800)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 43999)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 44198)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 44397)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 44596)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 44795)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 44994)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 45193)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 45392)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 45591)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 45790)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 45989)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 46188)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 46387)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 46586)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 46785)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 46984)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 47183)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 47382)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 47581)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 47780)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 47979)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 48178)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 48377)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 48576)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 48775)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 48974)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 49173)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 49372)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 49571)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 49770)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 49969)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 50168)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 50367)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 50566)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 50765)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 50964)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 51163)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 51362)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 51561)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 51760)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 51959)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 52158)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 52357)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 52556)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 52755)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 52954)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 53153)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 53352)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 53551)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 53750)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 53949)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 54148)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 54347)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 54546)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 54745)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 54944)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 55143)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 55342)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 55541)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 55740)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 55939)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 56138)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 56337)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 56536)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 56735)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 56934)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 57133)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 57332)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 57531)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 57730)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 57929)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 58128)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 58327)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 58526)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 58725)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 58924)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 59123)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 59322)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 59521)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 59720)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 59919)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 60118)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 60317)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 60516)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 60715)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 60914)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 61113)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 61312)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 61511)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 61710)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 61909)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 62108)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 62307)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 62506)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 62705)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 62904)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 63103)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 63302)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 63501)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 63700)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 63899)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 64098)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 64297)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 64496)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 64695)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 64894)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 65093)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 65292)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 65491)) (i32.const 0)) + +(module + (memory (export "mem") 1 1 ) + (data (i32.const 65516) "\00\01\02\03\04\05\06\07\08\09\0a\0b\0c\0d\0e\0f\10\11\12\13") + (func (export "run") (param $targetOffs i32) (param $srcOffs i32) (param $len i32) + (memory.copy (local.get $targetOffs) (local.get $srcOffs) (local.get $len))) + (func (export "load8_u") (param i32) (result i32) + (i32.load8_u (local.get 0)))) + +(assert_trap (invoke "run" (i32.const 0) (i32.const 65516) (i32.const 40)) + "out of bounds memory access") + +(assert_return (invoke "load8_u" (i32.const 198)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 397)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 596)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 795)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 994)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 1193)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 1392)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 1591)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 1790)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 1989)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 2188)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 2387)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 2586)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 2785)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 2984)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 3183)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 3382)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 3581)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 3780)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 3979)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 4178)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 4377)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 4576)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 4775)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 4974)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 5173)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 5372)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 5571)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 5770)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 5969)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 6168)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 6367)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 6566)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 6765)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 6964)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 7163)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 7362)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 7561)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 7760)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 7959)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 8158)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 8357)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 8556)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 8755)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 8954)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 9153)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 9352)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 9551)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 9750)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 9949)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 10148)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 10347)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 10546)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 10745)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 10944)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 11143)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 11342)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 11541)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 11740)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 11939)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 12138)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 12337)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 12536)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 12735)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 12934)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 13133)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 13332)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 13531)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 13730)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 13929)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 14128)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 14327)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 14526)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 14725)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 14924)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 15123)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 15322)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 15521)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 15720)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 15919)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 16118)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 16317)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 16516)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 16715)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 16914)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 17113)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 17312)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 17511)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 17710)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 17909)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 18108)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 18307)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 18506)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 18705)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 18904)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 19103)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 19302)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 19501)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 19700)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 19899)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 20098)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 20297)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 20496)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 20695)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 20894)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 21093)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 21292)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 21491)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 21690)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 21889)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 22088)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 22287)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 22486)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 22685)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 22884)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 23083)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 23282)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 23481)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 23680)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 23879)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 24078)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 24277)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 24476)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 24675)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 24874)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 25073)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 25272)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 25471)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 25670)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 25869)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 26068)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 26267)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 26466)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 26665)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 26864)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 27063)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 27262)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 27461)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 27660)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 27859)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 28058)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 28257)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 28456)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 28655)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 28854)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 29053)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 29252)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 29451)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 29650)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 29849)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 30048)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 30247)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 30446)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 30645)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 30844)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 31043)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 31242)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 31441)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 31640)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 31839)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 32038)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 32237)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 32436)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 32635)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 32834)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 33033)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 33232)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 33431)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 33630)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 33829)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 34028)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 34227)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 34426)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 34625)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 34824)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 35023)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 35222)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 35421)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 35620)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 35819)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 36018)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 36217)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 36416)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 36615)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 36814)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 37013)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 37212)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 37411)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 37610)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 37809)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 38008)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 38207)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 38406)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 38605)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 38804)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 39003)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 39202)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 39401)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 39600)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 39799)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 39998)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 40197)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 40396)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 40595)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 40794)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 40993)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 41192)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 41391)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 41590)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 41789)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 41988)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 42187)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 42386)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 42585)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 42784)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 42983)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 43182)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 43381)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 43580)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 43779)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 43978)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 44177)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 44376)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 44575)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 44774)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 44973)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 45172)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 45371)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 45570)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 45769)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 45968)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 46167)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 46366)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 46565)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 46764)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 46963)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 47162)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 47361)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 47560)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 47759)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 47958)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 48157)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 48356)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 48555)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 48754)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 48953)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 49152)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 49351)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 49550)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 49749)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 49948)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 50147)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 50346)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 50545)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 50744)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 50943)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 51142)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 51341)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 51540)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 51739)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 51938)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 52137)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 52336)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 52535)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 52734)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 52933)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 53132)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 53331)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 53530)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 53729)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 53928)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 54127)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 54326)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 54525)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 54724)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 54923)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 55122)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 55321)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 55520)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 55719)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 55918)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 56117)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 56316)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 56515)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 56714)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 56913)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 57112)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 57311)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 57510)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 57709)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 57908)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 58107)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 58306)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 58505)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 58704)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 58903)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 59102)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 59301)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 59500)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 59699)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 59898)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 60097)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 60296)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 60495)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 60694)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 60893)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 61092)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 61291)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 61490)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 61689)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 61888)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 62087)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 62286)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 62485)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 62684)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 62883)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 63082)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 63281)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 63480)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 63679)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 63878)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 64077)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 64276)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 64475)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 64674)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 64873)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 65072)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 65271)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 65470)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 65516)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 65517)) (i32.const 1)) +(assert_return (invoke "load8_u" (i32.const 65518)) (i32.const 2)) +(assert_return (invoke "load8_u" (i32.const 65519)) (i32.const 3)) +(assert_return (invoke "load8_u" (i32.const 65520)) (i32.const 4)) +(assert_return (invoke "load8_u" (i32.const 65521)) (i32.const 5)) +(assert_return (invoke "load8_u" (i32.const 65522)) (i32.const 6)) +(assert_return (invoke "load8_u" (i32.const 65523)) (i32.const 7)) +(assert_return (invoke "load8_u" (i32.const 65524)) (i32.const 8)) +(assert_return (invoke "load8_u" (i32.const 65525)) (i32.const 9)) +(assert_return (invoke "load8_u" (i32.const 65526)) (i32.const 10)) +(assert_return (invoke "load8_u" (i32.const 65527)) (i32.const 11)) +(assert_return (invoke "load8_u" (i32.const 65528)) (i32.const 12)) +(assert_return (invoke "load8_u" (i32.const 65529)) (i32.const 13)) +(assert_return (invoke "load8_u" (i32.const 65530)) (i32.const 14)) +(assert_return (invoke "load8_u" (i32.const 65531)) (i32.const 15)) +(assert_return (invoke "load8_u" (i32.const 65532)) (i32.const 16)) +(assert_return (invoke "load8_u" (i32.const 65533)) (i32.const 17)) +(assert_return (invoke "load8_u" (i32.const 65534)) (i32.const 18)) +(assert_return (invoke "load8_u" (i32.const 65535)) (i32.const 19)) + +(module + (memory (export "mem") 1 1 ) + (data (i32.const 65515) "\00\01\02\03\04\05\06\07\08\09\0a\0b\0c\0d\0e\0f\10\11\12\13\14") + (func (export "run") (param $targetOffs i32) (param $srcOffs i32) (param $len i32) + (memory.copy (local.get $targetOffs) (local.get $srcOffs) (local.get $len))) + (func (export "load8_u") (param i32) (result i32) + (i32.load8_u (local.get 0)))) + +(assert_trap (invoke "run" (i32.const 0) (i32.const 65515) (i32.const 39)) + "out of bounds memory access") + +(assert_return (invoke "load8_u" (i32.const 198)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 397)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 596)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 795)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 994)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 1193)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 1392)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 1591)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 1790)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 1989)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 2188)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 2387)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 2586)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 2785)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 2984)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 3183)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 3382)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 3581)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 3780)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 3979)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 4178)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 4377)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 4576)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 4775)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 4974)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 5173)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 5372)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 5571)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 5770)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 5969)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 6168)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 6367)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 6566)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 6765)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 6964)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 7163)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 7362)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 7561)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 7760)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 7959)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 8158)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 8357)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 8556)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 8755)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 8954)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 9153)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 9352)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 9551)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 9750)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 9949)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 10148)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 10347)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 10546)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 10745)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 10944)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 11143)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 11342)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 11541)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 11740)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 11939)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 12138)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 12337)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 12536)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 12735)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 12934)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 13133)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 13332)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 13531)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 13730)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 13929)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 14128)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 14327)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 14526)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 14725)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 14924)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 15123)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 15322)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 15521)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 15720)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 15919)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 16118)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 16317)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 16516)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 16715)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 16914)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 17113)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 17312)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 17511)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 17710)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 17909)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 18108)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 18307)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 18506)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 18705)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 18904)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 19103)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 19302)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 19501)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 19700)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 19899)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 20098)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 20297)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 20496)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 20695)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 20894)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 21093)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 21292)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 21491)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 21690)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 21889)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 22088)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 22287)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 22486)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 22685)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 22884)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 23083)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 23282)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 23481)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 23680)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 23879)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 24078)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 24277)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 24476)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 24675)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 24874)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 25073)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 25272)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 25471)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 25670)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 25869)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 26068)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 26267)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 26466)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 26665)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 26864)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 27063)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 27262)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 27461)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 27660)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 27859)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 28058)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 28257)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 28456)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 28655)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 28854)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 29053)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 29252)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 29451)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 29650)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 29849)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 30048)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 30247)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 30446)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 30645)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 30844)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 31043)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 31242)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 31441)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 31640)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 31839)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 32038)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 32237)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 32436)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 32635)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 32834)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 33033)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 33232)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 33431)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 33630)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 33829)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 34028)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 34227)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 34426)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 34625)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 34824)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 35023)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 35222)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 35421)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 35620)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 35819)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 36018)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 36217)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 36416)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 36615)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 36814)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 37013)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 37212)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 37411)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 37610)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 37809)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 38008)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 38207)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 38406)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 38605)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 38804)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 39003)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 39202)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 39401)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 39600)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 39799)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 39998)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 40197)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 40396)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 40595)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 40794)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 40993)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 41192)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 41391)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 41590)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 41789)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 41988)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 42187)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 42386)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 42585)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 42784)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 42983)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 43182)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 43381)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 43580)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 43779)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 43978)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 44177)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 44376)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 44575)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 44774)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 44973)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 45172)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 45371)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 45570)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 45769)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 45968)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 46167)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 46366)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 46565)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 46764)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 46963)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 47162)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 47361)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 47560)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 47759)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 47958)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 48157)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 48356)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 48555)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 48754)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 48953)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 49152)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 49351)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 49550)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 49749)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 49948)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 50147)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 50346)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 50545)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 50744)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 50943)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 51142)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 51341)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 51540)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 51739)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 51938)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 52137)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 52336)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 52535)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 52734)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 52933)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 53132)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 53331)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 53530)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 53729)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 53928)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 54127)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 54326)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 54525)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 54724)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 54923)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 55122)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 55321)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 55520)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 55719)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 55918)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 56117)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 56316)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 56515)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 56714)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 56913)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 57112)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 57311)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 57510)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 57709)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 57908)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 58107)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 58306)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 58505)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 58704)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 58903)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 59102)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 59301)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 59500)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 59699)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 59898)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 60097)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 60296)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 60495)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 60694)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 60893)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 61092)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 61291)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 61490)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 61689)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 61888)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 62087)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 62286)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 62485)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 62684)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 62883)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 63082)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 63281)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 63480)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 63679)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 63878)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 64077)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 64276)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 64475)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 64674)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 64873)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 65072)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 65271)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 65470)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 65515)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 65516)) (i32.const 1)) +(assert_return (invoke "load8_u" (i32.const 65517)) (i32.const 2)) +(assert_return (invoke "load8_u" (i32.const 65518)) (i32.const 3)) +(assert_return (invoke "load8_u" (i32.const 65519)) (i32.const 4)) +(assert_return (invoke "load8_u" (i32.const 65520)) (i32.const 5)) +(assert_return (invoke "load8_u" (i32.const 65521)) (i32.const 6)) +(assert_return (invoke "load8_u" (i32.const 65522)) (i32.const 7)) +(assert_return (invoke "load8_u" (i32.const 65523)) (i32.const 8)) +(assert_return (invoke "load8_u" (i32.const 65524)) (i32.const 9)) +(assert_return (invoke "load8_u" (i32.const 65525)) (i32.const 10)) +(assert_return (invoke "load8_u" (i32.const 65526)) (i32.const 11)) +(assert_return (invoke "load8_u" (i32.const 65527)) (i32.const 12)) +(assert_return (invoke "load8_u" (i32.const 65528)) (i32.const 13)) +(assert_return (invoke "load8_u" (i32.const 65529)) (i32.const 14)) +(assert_return (invoke "load8_u" (i32.const 65530)) (i32.const 15)) +(assert_return (invoke "load8_u" (i32.const 65531)) (i32.const 16)) +(assert_return (invoke "load8_u" (i32.const 65532)) (i32.const 17)) +(assert_return (invoke "load8_u" (i32.const 65533)) (i32.const 18)) +(assert_return (invoke "load8_u" (i32.const 65534)) (i32.const 19)) +(assert_return (invoke "load8_u" (i32.const 65535)) (i32.const 20)) + +(module + (memory (export "mem") 1 1 ) + (data (i32.const 65486) "\00\01\02\03\04\05\06\07\08\09\0a\0b\0c\0d\0e\0f\10\11\12\13") + (func (export "run") (param $targetOffs i32) (param $srcOffs i32) (param $len i32) + (memory.copy (local.get $targetOffs) (local.get $srcOffs) (local.get $len))) + (func (export "load8_u") (param i32) (result i32) + (i32.load8_u (local.get 0)))) + +(assert_trap (invoke "run" (i32.const 65516) (i32.const 65486) (i32.const 40)) + "out of bounds memory access") + +(assert_return (invoke "load8_u" (i32.const 198)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 397)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 596)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 795)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 994)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 1193)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 1392)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 1591)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 1790)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 1989)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 2188)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 2387)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 2586)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 2785)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 2984)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 3183)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 3382)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 3581)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 3780)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 3979)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 4178)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 4377)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 4576)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 4775)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 4974)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 5173)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 5372)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 5571)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 5770)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 5969)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 6168)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 6367)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 6566)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 6765)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 6964)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 7163)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 7362)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 7561)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 7760)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 7959)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 8158)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 8357)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 8556)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 8755)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 8954)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 9153)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 9352)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 9551)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 9750)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 9949)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 10148)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 10347)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 10546)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 10745)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 10944)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 11143)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 11342)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 11541)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 11740)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 11939)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 12138)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 12337)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 12536)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 12735)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 12934)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 13133)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 13332)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 13531)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 13730)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 13929)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 14128)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 14327)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 14526)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 14725)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 14924)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 15123)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 15322)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 15521)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 15720)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 15919)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 16118)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 16317)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 16516)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 16715)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 16914)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 17113)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 17312)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 17511)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 17710)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 17909)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 18108)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 18307)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 18506)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 18705)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 18904)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 19103)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 19302)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 19501)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 19700)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 19899)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 20098)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 20297)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 20496)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 20695)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 20894)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 21093)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 21292)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 21491)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 21690)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 21889)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 22088)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 22287)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 22486)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 22685)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 22884)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 23083)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 23282)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 23481)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 23680)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 23879)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 24078)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 24277)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 24476)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 24675)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 24874)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 25073)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 25272)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 25471)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 25670)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 25869)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 26068)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 26267)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 26466)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 26665)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 26864)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 27063)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 27262)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 27461)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 27660)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 27859)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 28058)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 28257)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 28456)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 28655)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 28854)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 29053)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 29252)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 29451)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 29650)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 29849)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 30048)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 30247)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 30446)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 30645)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 30844)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 31043)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 31242)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 31441)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 31640)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 31839)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 32038)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 32237)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 32436)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 32635)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 32834)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 33033)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 33232)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 33431)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 33630)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 33829)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 34028)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 34227)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 34426)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 34625)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 34824)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 35023)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 35222)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 35421)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 35620)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 35819)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 36018)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 36217)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 36416)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 36615)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 36814)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 37013)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 37212)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 37411)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 37610)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 37809)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 38008)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 38207)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 38406)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 38605)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 38804)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 39003)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 39202)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 39401)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 39600)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 39799)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 39998)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 40197)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 40396)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 40595)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 40794)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 40993)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 41192)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 41391)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 41590)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 41789)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 41988)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 42187)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 42386)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 42585)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 42784)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 42983)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 43182)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 43381)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 43580)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 43779)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 43978)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 44177)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 44376)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 44575)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 44774)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 44973)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 45172)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 45371)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 45570)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 45769)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 45968)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 46167)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 46366)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 46565)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 46764)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 46963)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 47162)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 47361)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 47560)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 47759)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 47958)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 48157)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 48356)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 48555)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 48754)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 48953)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 49152)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 49351)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 49550)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 49749)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 49948)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 50147)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 50346)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 50545)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 50744)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 50943)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 51142)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 51341)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 51540)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 51739)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 51938)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 52137)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 52336)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 52535)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 52734)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 52933)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 53132)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 53331)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 53530)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 53729)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 53928)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 54127)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 54326)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 54525)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 54724)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 54923)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 55122)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 55321)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 55520)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 55719)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 55918)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 56117)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 56316)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 56515)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 56714)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 56913)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 57112)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 57311)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 57510)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 57709)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 57908)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 58107)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 58306)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 58505)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 58704)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 58903)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 59102)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 59301)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 59500)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 59699)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 59898)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 60097)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 60296)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 60495)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 60694)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 60893)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 61092)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 61291)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 61490)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 61689)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 61888)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 62087)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 62286)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 62485)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 62684)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 62883)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 63082)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 63281)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 63480)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 63679)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 63878)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 64077)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 64276)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 64475)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 64674)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 64873)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 65072)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 65271)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 65470)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 65486)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 65487)) (i32.const 1)) +(assert_return (invoke "load8_u" (i32.const 65488)) (i32.const 2)) +(assert_return (invoke "load8_u" (i32.const 65489)) (i32.const 3)) +(assert_return (invoke "load8_u" (i32.const 65490)) (i32.const 4)) +(assert_return (invoke "load8_u" (i32.const 65491)) (i32.const 5)) +(assert_return (invoke "load8_u" (i32.const 65492)) (i32.const 6)) +(assert_return (invoke "load8_u" (i32.const 65493)) (i32.const 7)) +(assert_return (invoke "load8_u" (i32.const 65494)) (i32.const 8)) +(assert_return (invoke "load8_u" (i32.const 65495)) (i32.const 9)) +(assert_return (invoke "load8_u" (i32.const 65496)) (i32.const 10)) +(assert_return (invoke "load8_u" (i32.const 65497)) (i32.const 11)) +(assert_return (invoke "load8_u" (i32.const 65498)) (i32.const 12)) +(assert_return (invoke "load8_u" (i32.const 65499)) (i32.const 13)) +(assert_return (invoke "load8_u" (i32.const 65500)) (i32.const 14)) +(assert_return (invoke "load8_u" (i32.const 65501)) (i32.const 15)) +(assert_return (invoke "load8_u" (i32.const 65502)) (i32.const 16)) +(assert_return (invoke "load8_u" (i32.const 65503)) (i32.const 17)) +(assert_return (invoke "load8_u" (i32.const 65504)) (i32.const 18)) +(assert_return (invoke "load8_u" (i32.const 65505)) (i32.const 19)) + +(module + (memory (export "mem") 1 1 ) + (data (i32.const 65516) "\00\01\02\03\04\05\06\07\08\09\0a\0b\0c\0d\0e\0f\10\11\12\13") + (func (export "run") (param $targetOffs i32) (param $srcOffs i32) (param $len i32) + (memory.copy (local.get $targetOffs) (local.get $srcOffs) (local.get $len))) + (func (export "load8_u") (param i32) (result i32) + (i32.load8_u (local.get 0)))) + +(assert_trap (invoke "run" (i32.const 65486) (i32.const 65516) (i32.const 40)) + "out of bounds memory access") + +(assert_return (invoke "load8_u" (i32.const 198)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 397)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 596)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 795)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 994)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 1193)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 1392)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 1591)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 1790)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 1989)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 2188)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 2387)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 2586)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 2785)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 2984)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 3183)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 3382)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 3581)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 3780)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 3979)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 4178)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 4377)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 4576)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 4775)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 4974)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 5173)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 5372)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 5571)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 5770)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 5969)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 6168)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 6367)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 6566)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 6765)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 6964)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 7163)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 7362)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 7561)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 7760)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 7959)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 8158)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 8357)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 8556)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 8755)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 8954)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 9153)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 9352)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 9551)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 9750)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 9949)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 10148)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 10347)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 10546)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 10745)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 10944)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 11143)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 11342)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 11541)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 11740)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 11939)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 12138)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 12337)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 12536)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 12735)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 12934)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 13133)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 13332)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 13531)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 13730)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 13929)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 14128)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 14327)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 14526)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 14725)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 14924)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 15123)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 15322)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 15521)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 15720)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 15919)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 16118)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 16317)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 16516)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 16715)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 16914)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 17113)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 17312)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 17511)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 17710)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 17909)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 18108)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 18307)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 18506)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 18705)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 18904)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 19103)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 19302)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 19501)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 19700)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 19899)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 20098)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 20297)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 20496)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 20695)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 20894)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 21093)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 21292)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 21491)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 21690)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 21889)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 22088)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 22287)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 22486)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 22685)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 22884)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 23083)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 23282)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 23481)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 23680)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 23879)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 24078)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 24277)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 24476)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 24675)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 24874)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 25073)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 25272)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 25471)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 25670)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 25869)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 26068)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 26267)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 26466)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 26665)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 26864)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 27063)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 27262)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 27461)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 27660)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 27859)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 28058)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 28257)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 28456)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 28655)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 28854)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 29053)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 29252)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 29451)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 29650)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 29849)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 30048)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 30247)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 30446)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 30645)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 30844)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 31043)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 31242)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 31441)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 31640)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 31839)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 32038)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 32237)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 32436)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 32635)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 32834)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 33033)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 33232)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 33431)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 33630)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 33829)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 34028)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 34227)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 34426)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 34625)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 34824)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 35023)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 35222)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 35421)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 35620)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 35819)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 36018)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 36217)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 36416)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 36615)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 36814)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 37013)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 37212)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 37411)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 37610)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 37809)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 38008)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 38207)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 38406)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 38605)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 38804)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 39003)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 39202)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 39401)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 39600)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 39799)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 39998)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 40197)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 40396)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 40595)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 40794)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 40993)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 41192)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 41391)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 41590)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 41789)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 41988)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 42187)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 42386)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 42585)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 42784)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 42983)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 43182)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 43381)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 43580)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 43779)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 43978)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 44177)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 44376)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 44575)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 44774)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 44973)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 45172)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 45371)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 45570)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 45769)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 45968)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 46167)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 46366)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 46565)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 46764)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 46963)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 47162)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 47361)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 47560)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 47759)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 47958)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 48157)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 48356)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 48555)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 48754)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 48953)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 49152)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 49351)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 49550)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 49749)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 49948)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 50147)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 50346)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 50545)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 50744)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 50943)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 51142)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 51341)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 51540)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 51739)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 51938)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 52137)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 52336)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 52535)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 52734)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 52933)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 53132)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 53331)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 53530)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 53729)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 53928)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 54127)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 54326)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 54525)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 54724)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 54923)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 55122)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 55321)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 55520)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 55719)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 55918)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 56117)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 56316)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 56515)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 56714)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 56913)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 57112)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 57311)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 57510)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 57709)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 57908)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 58107)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 58306)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 58505)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 58704)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 58903)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 59102)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 59301)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 59500)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 59699)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 59898)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 60097)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 60296)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 60495)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 60694)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 60893)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 61092)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 61291)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 61490)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 61689)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 61888)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 62087)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 62286)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 62485)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 62684)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 62883)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 63082)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 63281)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 63480)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 63679)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 63878)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 64077)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 64276)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 64475)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 64674)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 64873)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 65072)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 65271)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 65470)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 65516)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 65517)) (i32.const 1)) +(assert_return (invoke "load8_u" (i32.const 65518)) (i32.const 2)) +(assert_return (invoke "load8_u" (i32.const 65519)) (i32.const 3)) +(assert_return (invoke "load8_u" (i32.const 65520)) (i32.const 4)) +(assert_return (invoke "load8_u" (i32.const 65521)) (i32.const 5)) +(assert_return (invoke "load8_u" (i32.const 65522)) (i32.const 6)) +(assert_return (invoke "load8_u" (i32.const 65523)) (i32.const 7)) +(assert_return (invoke "load8_u" (i32.const 65524)) (i32.const 8)) +(assert_return (invoke "load8_u" (i32.const 65525)) (i32.const 9)) +(assert_return (invoke "load8_u" (i32.const 65526)) (i32.const 10)) +(assert_return (invoke "load8_u" (i32.const 65527)) (i32.const 11)) +(assert_return (invoke "load8_u" (i32.const 65528)) (i32.const 12)) +(assert_return (invoke "load8_u" (i32.const 65529)) (i32.const 13)) +(assert_return (invoke "load8_u" (i32.const 65530)) (i32.const 14)) +(assert_return (invoke "load8_u" (i32.const 65531)) (i32.const 15)) +(assert_return (invoke "load8_u" (i32.const 65532)) (i32.const 16)) +(assert_return (invoke "load8_u" (i32.const 65533)) (i32.const 17)) +(assert_return (invoke "load8_u" (i32.const 65534)) (i32.const 18)) +(assert_return (invoke "load8_u" (i32.const 65535)) (i32.const 19)) + +(module + (memory (export "mem") 1 1 ) + (data (i32.const 65506) "\00\01\02\03\04\05\06\07\08\09\0a\0b\0c\0d\0e\0f\10\11\12\13") + (func (export "run") (param $targetOffs i32) (param $srcOffs i32) (param $len i32) + (memory.copy (local.get $targetOffs) (local.get $srcOffs) (local.get $len))) + (func (export "load8_u") (param i32) (result i32) + (i32.load8_u (local.get 0)))) + +(assert_trap (invoke "run" (i32.const 65516) (i32.const 65506) (i32.const 40)) + "out of bounds memory access") + +(assert_return (invoke "load8_u" (i32.const 198)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 397)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 596)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 795)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 994)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 1193)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 1392)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 1591)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 1790)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 1989)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 2188)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 2387)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 2586)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 2785)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 2984)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 3183)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 3382)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 3581)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 3780)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 3979)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 4178)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 4377)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 4576)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 4775)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 4974)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 5173)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 5372)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 5571)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 5770)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 5969)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 6168)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 6367)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 6566)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 6765)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 6964)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 7163)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 7362)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 7561)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 7760)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 7959)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 8158)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 8357)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 8556)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 8755)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 8954)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 9153)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 9352)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 9551)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 9750)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 9949)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 10148)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 10347)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 10546)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 10745)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 10944)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 11143)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 11342)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 11541)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 11740)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 11939)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 12138)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 12337)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 12536)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 12735)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 12934)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 13133)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 13332)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 13531)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 13730)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 13929)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 14128)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 14327)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 14526)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 14725)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 14924)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 15123)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 15322)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 15521)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 15720)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 15919)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 16118)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 16317)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 16516)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 16715)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 16914)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 17113)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 17312)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 17511)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 17710)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 17909)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 18108)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 18307)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 18506)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 18705)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 18904)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 19103)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 19302)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 19501)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 19700)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 19899)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 20098)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 20297)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 20496)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 20695)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 20894)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 21093)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 21292)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 21491)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 21690)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 21889)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 22088)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 22287)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 22486)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 22685)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 22884)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 23083)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 23282)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 23481)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 23680)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 23879)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 24078)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 24277)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 24476)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 24675)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 24874)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 25073)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 25272)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 25471)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 25670)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 25869)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 26068)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 26267)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 26466)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 26665)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 26864)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 27063)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 27262)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 27461)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 27660)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 27859)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 28058)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 28257)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 28456)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 28655)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 28854)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 29053)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 29252)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 29451)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 29650)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 29849)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 30048)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 30247)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 30446)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 30645)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 30844)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 31043)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 31242)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 31441)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 31640)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 31839)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 32038)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 32237)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 32436)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 32635)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 32834)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 33033)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 33232)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 33431)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 33630)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 33829)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 34028)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 34227)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 34426)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 34625)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 34824)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 35023)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 35222)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 35421)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 35620)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 35819)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 36018)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 36217)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 36416)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 36615)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 36814)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 37013)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 37212)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 37411)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 37610)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 37809)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 38008)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 38207)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 38406)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 38605)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 38804)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 39003)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 39202)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 39401)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 39600)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 39799)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 39998)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 40197)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 40396)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 40595)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 40794)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 40993)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 41192)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 41391)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 41590)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 41789)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 41988)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 42187)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 42386)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 42585)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 42784)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 42983)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 43182)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 43381)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 43580)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 43779)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 43978)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 44177)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 44376)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 44575)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 44774)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 44973)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 45172)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 45371)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 45570)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 45769)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 45968)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 46167)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 46366)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 46565)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 46764)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 46963)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 47162)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 47361)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 47560)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 47759)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 47958)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 48157)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 48356)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 48555)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 48754)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 48953)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 49152)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 49351)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 49550)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 49749)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 49948)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 50147)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 50346)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 50545)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 50744)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 50943)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 51142)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 51341)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 51540)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 51739)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 51938)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 52137)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 52336)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 52535)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 52734)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 52933)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 53132)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 53331)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 53530)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 53729)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 53928)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 54127)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 54326)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 54525)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 54724)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 54923)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 55122)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 55321)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 55520)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 55719)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 55918)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 56117)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 56316)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 56515)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 56714)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 56913)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 57112)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 57311)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 57510)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 57709)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 57908)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 58107)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 58306)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 58505)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 58704)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 58903)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 59102)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 59301)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 59500)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 59699)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 59898)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 60097)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 60296)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 60495)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 60694)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 60893)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 61092)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 61291)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 61490)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 61689)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 61888)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 62087)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 62286)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 62485)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 62684)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 62883)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 63082)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 63281)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 63480)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 63679)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 63878)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 64077)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 64276)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 64475)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 64674)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 64873)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 65072)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 65271)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 65470)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 65506)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 65507)) (i32.const 1)) +(assert_return (invoke "load8_u" (i32.const 65508)) (i32.const 2)) +(assert_return (invoke "load8_u" (i32.const 65509)) (i32.const 3)) +(assert_return (invoke "load8_u" (i32.const 65510)) (i32.const 4)) +(assert_return (invoke "load8_u" (i32.const 65511)) (i32.const 5)) +(assert_return (invoke "load8_u" (i32.const 65512)) (i32.const 6)) +(assert_return (invoke "load8_u" (i32.const 65513)) (i32.const 7)) +(assert_return (invoke "load8_u" (i32.const 65514)) (i32.const 8)) +(assert_return (invoke "load8_u" (i32.const 65515)) (i32.const 9)) +(assert_return (invoke "load8_u" (i32.const 65516)) (i32.const 10)) +(assert_return (invoke "load8_u" (i32.const 65517)) (i32.const 11)) +(assert_return (invoke "load8_u" (i32.const 65518)) (i32.const 12)) +(assert_return (invoke "load8_u" (i32.const 65519)) (i32.const 13)) +(assert_return (invoke "load8_u" (i32.const 65520)) (i32.const 14)) +(assert_return (invoke "load8_u" (i32.const 65521)) (i32.const 15)) +(assert_return (invoke "load8_u" (i32.const 65522)) (i32.const 16)) +(assert_return (invoke "load8_u" (i32.const 65523)) (i32.const 17)) +(assert_return (invoke "load8_u" (i32.const 65524)) (i32.const 18)) +(assert_return (invoke "load8_u" (i32.const 65525)) (i32.const 19)) + +(module + (memory (export "mem") 1 1 ) + (data (i32.const 65516) "\00\01\02\03\04\05\06\07\08\09\0a\0b\0c\0d\0e\0f\10\11\12\13") + (func (export "run") (param $targetOffs i32) (param $srcOffs i32) (param $len i32) + (memory.copy (local.get $targetOffs) (local.get $srcOffs) (local.get $len))) + (func (export "load8_u") (param i32) (result i32) + (i32.load8_u (local.get 0)))) + +(assert_trap (invoke "run" (i32.const 65506) (i32.const 65516) (i32.const 40)) + "out of bounds memory access") + +(assert_return (invoke "load8_u" (i32.const 198)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 397)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 596)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 795)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 994)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 1193)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 1392)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 1591)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 1790)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 1989)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 2188)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 2387)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 2586)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 2785)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 2984)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 3183)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 3382)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 3581)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 3780)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 3979)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 4178)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 4377)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 4576)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 4775)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 4974)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 5173)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 5372)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 5571)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 5770)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 5969)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 6168)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 6367)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 6566)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 6765)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 6964)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 7163)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 7362)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 7561)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 7760)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 7959)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 8158)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 8357)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 8556)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 8755)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 8954)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 9153)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 9352)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 9551)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 9750)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 9949)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 10148)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 10347)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 10546)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 10745)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 10944)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 11143)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 11342)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 11541)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 11740)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 11939)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 12138)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 12337)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 12536)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 12735)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 12934)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 13133)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 13332)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 13531)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 13730)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 13929)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 14128)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 14327)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 14526)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 14725)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 14924)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 15123)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 15322)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 15521)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 15720)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 15919)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 16118)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 16317)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 16516)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 16715)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 16914)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 17113)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 17312)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 17511)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 17710)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 17909)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 18108)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 18307)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 18506)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 18705)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 18904)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 19103)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 19302)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 19501)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 19700)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 19899)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 20098)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 20297)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 20496)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 20695)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 20894)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 21093)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 21292)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 21491)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 21690)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 21889)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 22088)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 22287)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 22486)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 22685)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 22884)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 23083)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 23282)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 23481)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 23680)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 23879)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 24078)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 24277)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 24476)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 24675)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 24874)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 25073)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 25272)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 25471)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 25670)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 25869)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 26068)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 26267)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 26466)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 26665)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 26864)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 27063)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 27262)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 27461)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 27660)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 27859)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 28058)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 28257)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 28456)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 28655)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 28854)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 29053)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 29252)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 29451)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 29650)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 29849)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 30048)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 30247)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 30446)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 30645)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 30844)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 31043)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 31242)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 31441)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 31640)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 31839)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 32038)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 32237)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 32436)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 32635)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 32834)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 33033)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 33232)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 33431)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 33630)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 33829)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 34028)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 34227)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 34426)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 34625)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 34824)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 35023)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 35222)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 35421)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 35620)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 35819)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 36018)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 36217)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 36416)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 36615)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 36814)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 37013)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 37212)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 37411)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 37610)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 37809)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 38008)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 38207)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 38406)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 38605)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 38804)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 39003)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 39202)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 39401)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 39600)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 39799)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 39998)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 40197)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 40396)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 40595)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 40794)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 40993)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 41192)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 41391)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 41590)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 41789)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 41988)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 42187)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 42386)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 42585)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 42784)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 42983)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 43182)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 43381)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 43580)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 43779)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 43978)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 44177)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 44376)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 44575)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 44774)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 44973)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 45172)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 45371)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 45570)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 45769)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 45968)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 46167)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 46366)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 46565)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 46764)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 46963)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 47162)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 47361)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 47560)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 47759)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 47958)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 48157)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 48356)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 48555)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 48754)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 48953)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 49152)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 49351)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 49550)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 49749)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 49948)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 50147)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 50346)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 50545)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 50744)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 50943)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 51142)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 51341)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 51540)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 51739)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 51938)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 52137)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 52336)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 52535)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 52734)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 52933)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 53132)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 53331)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 53530)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 53729)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 53928)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 54127)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 54326)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 54525)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 54724)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 54923)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 55122)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 55321)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 55520)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 55719)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 55918)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 56117)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 56316)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 56515)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 56714)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 56913)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 57112)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 57311)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 57510)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 57709)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 57908)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 58107)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 58306)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 58505)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 58704)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 58903)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 59102)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 59301)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 59500)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 59699)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 59898)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 60097)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 60296)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 60495)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 60694)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 60893)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 61092)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 61291)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 61490)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 61689)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 61888)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 62087)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 62286)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 62485)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 62684)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 62883)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 63082)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 63281)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 63480)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 63679)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 63878)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 64077)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 64276)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 64475)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 64674)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 64873)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 65072)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 65271)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 65470)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 65516)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 65517)) (i32.const 1)) +(assert_return (invoke "load8_u" (i32.const 65518)) (i32.const 2)) +(assert_return (invoke "load8_u" (i32.const 65519)) (i32.const 3)) +(assert_return (invoke "load8_u" (i32.const 65520)) (i32.const 4)) +(assert_return (invoke "load8_u" (i32.const 65521)) (i32.const 5)) +(assert_return (invoke "load8_u" (i32.const 65522)) (i32.const 6)) +(assert_return (invoke "load8_u" (i32.const 65523)) (i32.const 7)) +(assert_return (invoke "load8_u" (i32.const 65524)) (i32.const 8)) +(assert_return (invoke "load8_u" (i32.const 65525)) (i32.const 9)) +(assert_return (invoke "load8_u" (i32.const 65526)) (i32.const 10)) +(assert_return (invoke "load8_u" (i32.const 65527)) (i32.const 11)) +(assert_return (invoke "load8_u" (i32.const 65528)) (i32.const 12)) +(assert_return (invoke "load8_u" (i32.const 65529)) (i32.const 13)) +(assert_return (invoke "load8_u" (i32.const 65530)) (i32.const 14)) +(assert_return (invoke "load8_u" (i32.const 65531)) (i32.const 15)) +(assert_return (invoke "load8_u" (i32.const 65532)) (i32.const 16)) +(assert_return (invoke "load8_u" (i32.const 65533)) (i32.const 17)) +(assert_return (invoke "load8_u" (i32.const 65534)) (i32.const 18)) +(assert_return (invoke "load8_u" (i32.const 65535)) (i32.const 19)) + +(module + (memory (export "mem") 1 1 ) + (data (i32.const 65516) "\00\01\02\03\04\05\06\07\08\09\0a\0b\0c\0d\0e\0f\10\11\12\13") + (func (export "run") (param $targetOffs i32) (param $srcOffs i32) (param $len i32) + (memory.copy (local.get $targetOffs) (local.get $srcOffs) (local.get $len))) + (func (export "load8_u") (param i32) (result i32) + (i32.load8_u (local.get 0)))) + +(assert_trap (invoke "run" (i32.const 65516) (i32.const 65516) (i32.const 40)) + "out of bounds memory access") + +(assert_return (invoke "load8_u" (i32.const 198)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 397)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 596)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 795)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 994)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 1193)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 1392)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 1591)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 1790)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 1989)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 2188)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 2387)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 2586)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 2785)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 2984)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 3183)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 3382)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 3581)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 3780)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 3979)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 4178)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 4377)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 4576)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 4775)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 4974)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 5173)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 5372)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 5571)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 5770)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 5969)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 6168)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 6367)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 6566)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 6765)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 6964)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 7163)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 7362)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 7561)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 7760)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 7959)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 8158)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 8357)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 8556)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 8755)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 8954)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 9153)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 9352)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 9551)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 9750)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 9949)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 10148)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 10347)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 10546)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 10745)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 10944)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 11143)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 11342)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 11541)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 11740)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 11939)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 12138)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 12337)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 12536)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 12735)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 12934)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 13133)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 13332)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 13531)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 13730)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 13929)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 14128)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 14327)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 14526)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 14725)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 14924)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 15123)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 15322)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 15521)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 15720)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 15919)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 16118)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 16317)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 16516)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 16715)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 16914)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 17113)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 17312)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 17511)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 17710)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 17909)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 18108)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 18307)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 18506)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 18705)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 18904)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 19103)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 19302)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 19501)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 19700)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 19899)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 20098)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 20297)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 20496)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 20695)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 20894)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 21093)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 21292)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 21491)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 21690)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 21889)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 22088)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 22287)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 22486)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 22685)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 22884)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 23083)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 23282)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 23481)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 23680)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 23879)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 24078)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 24277)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 24476)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 24675)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 24874)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 25073)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 25272)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 25471)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 25670)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 25869)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 26068)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 26267)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 26466)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 26665)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 26864)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 27063)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 27262)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 27461)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 27660)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 27859)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 28058)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 28257)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 28456)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 28655)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 28854)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 29053)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 29252)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 29451)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 29650)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 29849)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 30048)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 30247)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 30446)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 30645)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 30844)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 31043)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 31242)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 31441)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 31640)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 31839)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 32038)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 32237)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 32436)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 32635)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 32834)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 33033)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 33232)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 33431)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 33630)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 33829)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 34028)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 34227)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 34426)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 34625)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 34824)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 35023)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 35222)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 35421)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 35620)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 35819)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 36018)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 36217)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 36416)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 36615)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 36814)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 37013)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 37212)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 37411)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 37610)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 37809)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 38008)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 38207)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 38406)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 38605)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 38804)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 39003)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 39202)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 39401)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 39600)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 39799)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 39998)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 40197)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 40396)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 40595)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 40794)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 40993)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 41192)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 41391)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 41590)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 41789)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 41988)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 42187)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 42386)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 42585)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 42784)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 42983)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 43182)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 43381)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 43580)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 43779)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 43978)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 44177)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 44376)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 44575)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 44774)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 44973)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 45172)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 45371)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 45570)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 45769)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 45968)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 46167)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 46366)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 46565)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 46764)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 46963)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 47162)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 47361)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 47560)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 47759)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 47958)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 48157)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 48356)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 48555)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 48754)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 48953)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 49152)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 49351)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 49550)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 49749)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 49948)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 50147)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 50346)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 50545)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 50744)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 50943)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 51142)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 51341)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 51540)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 51739)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 51938)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 52137)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 52336)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 52535)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 52734)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 52933)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 53132)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 53331)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 53530)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 53729)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 53928)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 54127)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 54326)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 54525)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 54724)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 54923)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 55122)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 55321)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 55520)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 55719)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 55918)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 56117)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 56316)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 56515)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 56714)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 56913)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 57112)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 57311)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 57510)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 57709)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 57908)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 58107)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 58306)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 58505)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 58704)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 58903)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 59102)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 59301)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 59500)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 59699)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 59898)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 60097)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 60296)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 60495)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 60694)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 60893)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 61092)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 61291)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 61490)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 61689)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 61888)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 62087)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 62286)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 62485)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 62684)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 62883)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 63082)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 63281)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 63480)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 63679)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 63878)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 64077)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 64276)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 64475)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 64674)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 64873)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 65072)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 65271)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 65470)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 65516)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 65517)) (i32.const 1)) +(assert_return (invoke "load8_u" (i32.const 65518)) (i32.const 2)) +(assert_return (invoke "load8_u" (i32.const 65519)) (i32.const 3)) +(assert_return (invoke "load8_u" (i32.const 65520)) (i32.const 4)) +(assert_return (invoke "load8_u" (i32.const 65521)) (i32.const 5)) +(assert_return (invoke "load8_u" (i32.const 65522)) (i32.const 6)) +(assert_return (invoke "load8_u" (i32.const 65523)) (i32.const 7)) +(assert_return (invoke "load8_u" (i32.const 65524)) (i32.const 8)) +(assert_return (invoke "load8_u" (i32.const 65525)) (i32.const 9)) +(assert_return (invoke "load8_u" (i32.const 65526)) (i32.const 10)) +(assert_return (invoke "load8_u" (i32.const 65527)) (i32.const 11)) +(assert_return (invoke "load8_u" (i32.const 65528)) (i32.const 12)) +(assert_return (invoke "load8_u" (i32.const 65529)) (i32.const 13)) +(assert_return (invoke "load8_u" (i32.const 65530)) (i32.const 14)) +(assert_return (invoke "load8_u" (i32.const 65531)) (i32.const 15)) +(assert_return (invoke "load8_u" (i32.const 65532)) (i32.const 16)) +(assert_return (invoke "load8_u" (i32.const 65533)) (i32.const 17)) +(assert_return (invoke "load8_u" (i32.const 65534)) (i32.const 18)) +(assert_return (invoke "load8_u" (i32.const 65535)) (i32.const 19)) + +(module + (memory (export "mem") 1 ) + (data (i32.const 65516) "\00\01\02\03\04\05\06\07\08\09\0a\0b\0c\0d\0e\0f\10\11\12\13") + (func (export "run") (param $targetOffs i32) (param $srcOffs i32) (param $len i32) + (memory.copy (local.get $targetOffs) (local.get $srcOffs) (local.get $len))) + (func (export "load8_u") (param i32) (result i32) + (i32.load8_u (local.get 0)))) + +(assert_trap (invoke "run" (i32.const 0) (i32.const 65516) (i32.const 4294963200)) + "out of bounds memory access") + +(assert_return (invoke "load8_u" (i32.const 198)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 397)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 596)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 795)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 994)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 1193)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 1392)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 1591)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 1790)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 1989)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 2188)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 2387)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 2586)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 2785)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 2984)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 3183)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 3382)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 3581)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 3780)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 3979)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 4178)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 4377)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 4576)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 4775)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 4974)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 5173)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 5372)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 5571)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 5770)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 5969)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 6168)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 6367)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 6566)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 6765)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 6964)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 7163)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 7362)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 7561)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 7760)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 7959)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 8158)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 8357)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 8556)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 8755)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 8954)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 9153)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 9352)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 9551)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 9750)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 9949)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 10148)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 10347)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 10546)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 10745)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 10944)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 11143)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 11342)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 11541)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 11740)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 11939)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 12138)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 12337)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 12536)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 12735)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 12934)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 13133)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 13332)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 13531)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 13730)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 13929)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 14128)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 14327)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 14526)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 14725)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 14924)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 15123)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 15322)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 15521)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 15720)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 15919)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 16118)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 16317)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 16516)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 16715)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 16914)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 17113)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 17312)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 17511)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 17710)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 17909)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 18108)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 18307)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 18506)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 18705)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 18904)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 19103)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 19302)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 19501)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 19700)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 19899)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 20098)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 20297)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 20496)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 20695)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 20894)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 21093)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 21292)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 21491)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 21690)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 21889)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 22088)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 22287)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 22486)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 22685)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 22884)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 23083)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 23282)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 23481)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 23680)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 23879)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 24078)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 24277)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 24476)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 24675)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 24874)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 25073)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 25272)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 25471)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 25670)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 25869)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 26068)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 26267)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 26466)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 26665)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 26864)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 27063)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 27262)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 27461)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 27660)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 27859)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 28058)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 28257)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 28456)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 28655)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 28854)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 29053)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 29252)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 29451)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 29650)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 29849)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 30048)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 30247)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 30446)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 30645)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 30844)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 31043)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 31242)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 31441)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 31640)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 31839)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 32038)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 32237)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 32436)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 32635)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 32834)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 33033)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 33232)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 33431)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 33630)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 33829)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 34028)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 34227)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 34426)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 34625)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 34824)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 35023)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 35222)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 35421)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 35620)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 35819)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 36018)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 36217)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 36416)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 36615)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 36814)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 37013)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 37212)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 37411)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 37610)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 37809)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 38008)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 38207)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 38406)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 38605)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 38804)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 39003)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 39202)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 39401)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 39600)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 39799)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 39998)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 40197)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 40396)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 40595)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 40794)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 40993)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 41192)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 41391)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 41590)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 41789)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 41988)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 42187)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 42386)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 42585)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 42784)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 42983)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 43182)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 43381)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 43580)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 43779)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 43978)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 44177)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 44376)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 44575)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 44774)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 44973)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 45172)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 45371)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 45570)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 45769)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 45968)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 46167)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 46366)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 46565)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 46764)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 46963)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 47162)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 47361)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 47560)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 47759)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 47958)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 48157)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 48356)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 48555)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 48754)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 48953)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 49152)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 49351)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 49550)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 49749)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 49948)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 50147)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 50346)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 50545)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 50744)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 50943)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 51142)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 51341)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 51540)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 51739)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 51938)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 52137)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 52336)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 52535)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 52734)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 52933)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 53132)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 53331)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 53530)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 53729)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 53928)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 54127)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 54326)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 54525)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 54724)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 54923)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 55122)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 55321)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 55520)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 55719)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 55918)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 56117)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 56316)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 56515)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 56714)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 56913)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 57112)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 57311)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 57510)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 57709)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 57908)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 58107)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 58306)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 58505)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 58704)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 58903)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 59102)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 59301)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 59500)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 59699)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 59898)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 60097)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 60296)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 60495)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 60694)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 60893)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 61092)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 61291)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 61490)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 61689)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 61888)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 62087)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 62286)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 62485)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 62684)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 62883)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 63082)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 63281)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 63480)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 63679)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 63878)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 64077)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 64276)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 64475)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 64674)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 64873)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 65072)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 65271)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 65470)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 65516)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 65517)) (i32.const 1)) +(assert_return (invoke "load8_u" (i32.const 65518)) (i32.const 2)) +(assert_return (invoke "load8_u" (i32.const 65519)) (i32.const 3)) +(assert_return (invoke "load8_u" (i32.const 65520)) (i32.const 4)) +(assert_return (invoke "load8_u" (i32.const 65521)) (i32.const 5)) +(assert_return (invoke "load8_u" (i32.const 65522)) (i32.const 6)) +(assert_return (invoke "load8_u" (i32.const 65523)) (i32.const 7)) +(assert_return (invoke "load8_u" (i32.const 65524)) (i32.const 8)) +(assert_return (invoke "load8_u" (i32.const 65525)) (i32.const 9)) +(assert_return (invoke "load8_u" (i32.const 65526)) (i32.const 10)) +(assert_return (invoke "load8_u" (i32.const 65527)) (i32.const 11)) +(assert_return (invoke "load8_u" (i32.const 65528)) (i32.const 12)) +(assert_return (invoke "load8_u" (i32.const 65529)) (i32.const 13)) +(assert_return (invoke "load8_u" (i32.const 65530)) (i32.const 14)) +(assert_return (invoke "load8_u" (i32.const 65531)) (i32.const 15)) +(assert_return (invoke "load8_u" (i32.const 65532)) (i32.const 16)) +(assert_return (invoke "load8_u" (i32.const 65533)) (i32.const 17)) +(assert_return (invoke "load8_u" (i32.const 65534)) (i32.const 18)) +(assert_return (invoke "load8_u" (i32.const 65535)) (i32.const 19)) + +(module + (memory (export "mem") 1 1 ) + (data (i32.const 61440) "\00\01\02\03\04\05\06\07\08\09\0a\0b\0c\0d\0e\0f\10\11\12\13") + (func (export "run") (param $targetOffs i32) (param $srcOffs i32) (param $len i32) + (memory.copy (local.get $targetOffs) (local.get $srcOffs) (local.get $len))) + (func (export "load8_u") (param i32) (result i32) + (i32.load8_u (local.get 0)))) + +(assert_trap (invoke "run" (i32.const 65516) (i32.const 61440) (i32.const 4294967040)) + "out of bounds memory access") + +(assert_return (invoke "load8_u" (i32.const 198)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 397)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 596)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 795)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 994)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 1193)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 1392)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 1591)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 1790)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 1989)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 2188)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 2387)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 2586)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 2785)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 2984)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 3183)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 3382)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 3581)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 3780)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 3979)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 4178)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 4377)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 4576)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 4775)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 4974)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 5173)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 5372)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 5571)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 5770)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 5969)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 6168)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 6367)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 6566)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 6765)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 6964)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 7163)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 7362)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 7561)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 7760)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 7959)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 8158)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 8357)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 8556)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 8755)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 8954)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 9153)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 9352)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 9551)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 9750)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 9949)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 10148)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 10347)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 10546)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 10745)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 10944)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 11143)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 11342)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 11541)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 11740)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 11939)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 12138)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 12337)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 12536)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 12735)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 12934)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 13133)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 13332)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 13531)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 13730)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 13929)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 14128)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 14327)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 14526)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 14725)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 14924)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 15123)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 15322)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 15521)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 15720)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 15919)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 16118)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 16317)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 16516)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 16715)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 16914)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 17113)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 17312)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 17511)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 17710)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 17909)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 18108)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 18307)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 18506)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 18705)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 18904)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 19103)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 19302)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 19501)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 19700)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 19899)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 20098)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 20297)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 20496)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 20695)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 20894)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 21093)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 21292)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 21491)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 21690)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 21889)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 22088)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 22287)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 22486)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 22685)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 22884)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 23083)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 23282)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 23481)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 23680)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 23879)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 24078)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 24277)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 24476)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 24675)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 24874)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 25073)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 25272)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 25471)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 25670)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 25869)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 26068)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 26267)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 26466)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 26665)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 26864)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 27063)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 27262)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 27461)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 27660)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 27859)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 28058)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 28257)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 28456)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 28655)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 28854)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 29053)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 29252)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 29451)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 29650)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 29849)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 30048)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 30247)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 30446)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 30645)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 30844)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 31043)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 31242)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 31441)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 31640)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 31839)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 32038)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 32237)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 32436)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 32635)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 32834)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 33033)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 33232)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 33431)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 33630)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 33829)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 34028)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 34227)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 34426)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 34625)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 34824)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 35023)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 35222)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 35421)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 35620)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 35819)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 36018)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 36217)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 36416)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 36615)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 36814)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 37013)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 37212)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 37411)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 37610)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 37809)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 38008)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 38207)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 38406)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 38605)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 38804)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 39003)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 39202)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 39401)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 39600)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 39799)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 39998)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 40197)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 40396)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 40595)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 40794)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 40993)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 41192)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 41391)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 41590)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 41789)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 41988)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 42187)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 42386)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 42585)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 42784)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 42983)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 43182)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 43381)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 43580)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 43779)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 43978)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 44177)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 44376)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 44575)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 44774)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 44973)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 45172)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 45371)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 45570)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 45769)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 45968)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 46167)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 46366)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 46565)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 46764)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 46963)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 47162)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 47361)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 47560)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 47759)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 47958)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 48157)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 48356)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 48555)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 48754)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 48953)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 49152)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 49351)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 49550)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 49749)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 49948)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 50147)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 50346)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 50545)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 50744)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 50943)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 51142)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 51341)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 51540)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 51739)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 51938)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 52137)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 52336)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 52535)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 52734)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 52933)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 53132)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 53331)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 53530)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 53729)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 53928)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 54127)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 54326)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 54525)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 54724)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 54923)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 55122)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 55321)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 55520)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 55719)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 55918)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 56117)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 56316)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 56515)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 56714)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 56913)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 57112)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 57311)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 57510)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 57709)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 57908)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 58107)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 58306)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 58505)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 58704)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 58903)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 59102)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 59301)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 59500)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 59699)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 59898)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 60097)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 60296)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 60495)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 60694)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 60893)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 61092)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 61291)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 61440)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 61441)) (i32.const 1)) +(assert_return (invoke "load8_u" (i32.const 61442)) (i32.const 2)) +(assert_return (invoke "load8_u" (i32.const 61443)) (i32.const 3)) +(assert_return (invoke "load8_u" (i32.const 61444)) (i32.const 4)) +(assert_return (invoke "load8_u" (i32.const 61445)) (i32.const 5)) +(assert_return (invoke "load8_u" (i32.const 61446)) (i32.const 6)) +(assert_return (invoke "load8_u" (i32.const 61447)) (i32.const 7)) +(assert_return (invoke "load8_u" (i32.const 61448)) (i32.const 8)) +(assert_return (invoke "load8_u" (i32.const 61449)) (i32.const 9)) +(assert_return (invoke "load8_u" (i32.const 61450)) (i32.const 10)) +(assert_return (invoke "load8_u" (i32.const 61451)) (i32.const 11)) +(assert_return (invoke "load8_u" (i32.const 61452)) (i32.const 12)) +(assert_return (invoke "load8_u" (i32.const 61453)) (i32.const 13)) +(assert_return (invoke "load8_u" (i32.const 61454)) (i32.const 14)) +(assert_return (invoke "load8_u" (i32.const 61455)) (i32.const 15)) +(assert_return (invoke "load8_u" (i32.const 61456)) (i32.const 16)) +(assert_return (invoke "load8_u" (i32.const 61457)) (i32.const 17)) +(assert_return (invoke "load8_u" (i32.const 61458)) (i32.const 18)) +(assert_return (invoke "load8_u" (i32.const 61459)) (i32.const 19)) +(assert_return (invoke "load8_u" (i32.const 61510)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 61709)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 61908)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 62107)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 62306)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 62505)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 62704)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 62903)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 63102)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 63301)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 63500)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 63699)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 63898)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 64097)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 64296)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 64495)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 64694)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 64893)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 65092)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 65291)) (i32.const 0)) +(assert_return (invoke "load8_u" (i32.const 65490)) (i32.const 0)) + +(assert_invalid + (module + (func (export "testfn") + (memory.copy (i64.const 10) (i64.const 20) (i64.const 30)))) + "unknown memory 0") + +(assert_invalid + (module + (memory i64 1 1) + (func (export "testfn") + (memory.copy (i32.const 10) (i32.const 20) (i32.const 30)))) + "type mismatch") + +(assert_invalid + (module + (memory i64 1 1) + (func (export "testfn") + (memory.copy (i32.const 10) (i32.const 20) (f32.const 30)))) + "type mismatch") + +(assert_invalid + (module + (memory i64 1 1) + (func (export "testfn") + (memory.copy (i32.const 10) (i32.const 20) (i64.const 30)))) + "type mismatch") + +(assert_invalid + (module + (memory i64 1 1) + (func (export "testfn") + (memory.copy (i32.const 10) (i32.const 20) (f64.const 30)))) + "type mismatch") + +(assert_invalid + (module + (memory i64 1 1) + (func (export "testfn") + (memory.copy (i32.const 10) (f32.const 20) (i32.const 30)))) + "type mismatch") + +(assert_invalid + (module + (memory i64 1 1) + (func (export "testfn") + (memory.copy (i32.const 10) (f32.const 20) (f32.const 30)))) + "type mismatch") + +(assert_invalid + (module + (memory i64 1 1) + (func (export "testfn") + (memory.copy (i32.const 10) (f32.const 20) (i64.const 30)))) + "type mismatch") + +(assert_invalid + (module + (memory i64 1 1) + (func (export "testfn") + (memory.copy (i32.const 10) (f32.const 20) (f64.const 30)))) + "type mismatch") + +(assert_invalid + (module + (memory i64 1 1) + (func (export "testfn") + (memory.copy (i32.const 10) (i64.const 20) (i32.const 30)))) + "type mismatch") + +(assert_invalid + (module + (memory i64 1 1) + (func (export "testfn") + (memory.copy (i32.const 10) (i64.const 20) (f32.const 30)))) + "type mismatch") + +(assert_invalid + (module + (memory i64 1 1) + (func (export "testfn") + (memory.copy (i32.const 10) (i64.const 20) (i64.const 30)))) + "type mismatch") + +(assert_invalid + (module + (memory i64 1 1) + (func (export "testfn") + (memory.copy (i32.const 10) (i64.const 20) (f64.const 30)))) + "type mismatch") + +(assert_invalid + (module + (memory i64 1 1) + (func (export "testfn") + (memory.copy (i32.const 10) (f64.const 20) (i32.const 30)))) + "type mismatch") + +(assert_invalid + (module + (memory i64 1 1) + (func (export "testfn") + (memory.copy (i32.const 10) (f64.const 20) (f32.const 30)))) + "type mismatch") + +(assert_invalid + (module + (memory i64 1 1) + (func (export "testfn") + (memory.copy (i32.const 10) (f64.const 20) (i64.const 30)))) + "type mismatch") + +(assert_invalid + (module + (memory i64 1 1) + (func (export "testfn") + (memory.copy (i32.const 10) (f64.const 20) (f64.const 30)))) + "type mismatch") + +(assert_invalid + (module + (memory i64 1 1) + (func (export "testfn") + (memory.copy (f32.const 10) (i32.const 20) (i32.const 30)))) + "type mismatch") + +(assert_invalid + (module + (memory i64 1 1) + (func (export "testfn") + (memory.copy (f32.const 10) (i32.const 20) (f32.const 30)))) + "type mismatch") + +(assert_invalid + (module + (memory i64 1 1) + (func (export "testfn") + (memory.copy (f32.const 10) (i32.const 20) (i64.const 30)))) + "type mismatch") + +(assert_invalid + (module + (memory i64 1 1) + (func (export "testfn") + (memory.copy (f32.const 10) (i32.const 20) (f64.const 30)))) + "type mismatch") + +(assert_invalid + (module + (memory i64 1 1) + (func (export "testfn") + (memory.copy (f32.const 10) (f32.const 20) (i32.const 30)))) + "type mismatch") + +(assert_invalid + (module + (memory i64 1 1) + (func (export "testfn") + (memory.copy (f32.const 10) (f32.const 20) (f32.const 30)))) + "type mismatch") + +(assert_invalid + (module + (memory i64 1 1) + (func (export "testfn") + (memory.copy (f32.const 10) (f32.const 20) (i64.const 30)))) + "type mismatch") + +(assert_invalid + (module + (memory i64 1 1) + (func (export "testfn") + (memory.copy (f32.const 10) (f32.const 20) (f64.const 30)))) + "type mismatch") + +(assert_invalid + (module + (memory i64 1 1) + (func (export "testfn") + (memory.copy (f32.const 10) (i64.const 20) (i32.const 30)))) + "type mismatch") + +(assert_invalid + (module + (memory i64 1 1) + (func (export "testfn") + (memory.copy (f32.const 10) (i64.const 20) (f32.const 30)))) + "type mismatch") + +(assert_invalid + (module + (memory i64 1 1) + (func (export "testfn") + (memory.copy (f32.const 10) (i64.const 20) (i64.const 30)))) + "type mismatch") + +(assert_invalid + (module + (memory i64 1 1) + (func (export "testfn") + (memory.copy (f32.const 10) (i64.const 20) (f64.const 30)))) + "type mismatch") + +(assert_invalid + (module + (memory i64 1 1) + (func (export "testfn") + (memory.copy (f32.const 10) (f64.const 20) (i32.const 30)))) + "type mismatch") + +(assert_invalid + (module + (memory i64 1 1) + (func (export "testfn") + (memory.copy (f32.const 10) (f64.const 20) (f32.const 30)))) + "type mismatch") + +(assert_invalid + (module + (memory i64 1 1) + (func (export "testfn") + (memory.copy (f32.const 10) (f64.const 20) (i64.const 30)))) + "type mismatch") + +(assert_invalid + (module + (memory i64 1 1) + (func (export "testfn") + (memory.copy (f32.const 10) (f64.const 20) (f64.const 30)))) + "type mismatch") + +(assert_invalid + (module + (memory i64 1 1) + (func (export "testfn") + (memory.copy (i64.const 10) (i32.const 20) (i32.const 30)))) + "type mismatch") + +(assert_invalid + (module + (memory i64 1 1) + (func (export "testfn") + (memory.copy (i64.const 10) (i32.const 20) (f32.const 30)))) + "type mismatch") + +(assert_invalid + (module + (memory i64 1 1) + (func (export "testfn") + (memory.copy (i64.const 10) (i32.const 20) (i64.const 30)))) + "type mismatch") + +(assert_invalid + (module + (memory i64 1 1) + (func (export "testfn") + (memory.copy (i64.const 10) (i32.const 20) (f64.const 30)))) + "type mismatch") + +(assert_invalid + (module + (memory i64 1 1) + (func (export "testfn") + (memory.copy (i64.const 10) (f32.const 20) (i32.const 30)))) + "type mismatch") + +(assert_invalid + (module + (memory i64 1 1) + (func (export "testfn") + (memory.copy (i64.const 10) (f32.const 20) (f32.const 30)))) + "type mismatch") + +(assert_invalid + (module + (memory i64 1 1) + (func (export "testfn") + (memory.copy (i64.const 10) (f32.const 20) (i64.const 30)))) + "type mismatch") + +(assert_invalid + (module + (memory i64 1 1) + (func (export "testfn") + (memory.copy (i64.const 10) (f32.const 20) (f64.const 30)))) + "type mismatch") + +(assert_invalid + (module + (memory i64 1 1) + (func (export "testfn") + (memory.copy (i64.const 10) (i64.const 20) (i32.const 30)))) + "type mismatch") + +(assert_invalid + (module + (memory i64 1 1) + (func (export "testfn") + (memory.copy (i64.const 10) (i64.const 20) (f32.const 30)))) + "type mismatch") + +(assert_invalid + (module + (memory i64 1 1) + (func (export "testfn") + (memory.copy (i64.const 10) (i64.const 20) (f64.const 30)))) + "type mismatch") + +(assert_invalid + (module + (memory i64 1 1) + (func (export "testfn") + (memory.copy (i64.const 10) (f64.const 20) (i32.const 30)))) + "type mismatch") + +(assert_invalid + (module + (memory i64 1 1) + (func (export "testfn") + (memory.copy (i64.const 10) (f64.const 20) (f32.const 30)))) + "type mismatch") + +(assert_invalid + (module + (memory i64 1 1) + (func (export "testfn") + (memory.copy (i64.const 10) (f64.const 20) (i64.const 30)))) + "type mismatch") + +(assert_invalid + (module + (memory i64 1 1) + (func (export "testfn") + (memory.copy (i64.const 10) (f64.const 20) (f64.const 30)))) + "type mismatch") + +(assert_invalid + (module + (memory i64 1 1) + (func (export "testfn") + (memory.copy (f64.const 10) (i32.const 20) (i32.const 30)))) + "type mismatch") + +(assert_invalid + (module + (memory i64 1 1) + (func (export "testfn") + (memory.copy (f64.const 10) (i32.const 20) (f32.const 30)))) + "type mismatch") + +(assert_invalid + (module + (memory i64 1 1) + (func (export "testfn") + (memory.copy (f64.const 10) (i32.const 20) (i64.const 30)))) + "type mismatch") + +(assert_invalid + (module + (memory i64 1 1) + (func (export "testfn") + (memory.copy (f64.const 10) (i32.const 20) (f64.const 30)))) + "type mismatch") + +(assert_invalid + (module + (memory i64 1 1) + (func (export "testfn") + (memory.copy (f64.const 10) (f32.const 20) (i32.const 30)))) + "type mismatch") + +(assert_invalid + (module + (memory i64 1 1) + (func (export "testfn") + (memory.copy (f64.const 10) (f32.const 20) (f32.const 30)))) + "type mismatch") + +(assert_invalid + (module + (memory i64 1 1) + (func (export "testfn") + (memory.copy (f64.const 10) (f32.const 20) (i64.const 30)))) + "type mismatch") + +(assert_invalid + (module + (memory i64 1 1) + (func (export "testfn") + (memory.copy (f64.const 10) (f32.const 20) (f64.const 30)))) + "type mismatch") + +(assert_invalid + (module + (memory i64 1 1) + (func (export "testfn") + (memory.copy (f64.const 10) (i64.const 20) (i32.const 30)))) + "type mismatch") + +(assert_invalid + (module + (memory i64 1 1) + (func (export "testfn") + (memory.copy (f64.const 10) (i64.const 20) (f32.const 30)))) + "type mismatch") + +(assert_invalid + (module + (memory i64 1 1) + (func (export "testfn") + (memory.copy (f64.const 10) (i64.const 20) (i64.const 30)))) + "type mismatch") + +(assert_invalid + (module + (memory i64 1 1) + (func (export "testfn") + (memory.copy (f64.const 10) (i64.const 20) (f64.const 30)))) + "type mismatch") + +(assert_invalid + (module + (memory i64 1 1) + (func (export "testfn") + (memory.copy (f64.const 10) (f64.const 20) (i32.const 30)))) + "type mismatch") + +(assert_invalid + (module + (memory i64 1 1) + (func (export "testfn") + (memory.copy (f64.const 10) (f64.const 20) (f32.const 30)))) + "type mismatch") + +(assert_invalid + (module + (memory i64 1 1) + (func (export "testfn") + (memory.copy (f64.const 10) (f64.const 20) (i64.const 30)))) + "type mismatch") + +(assert_invalid + (module + (memory i64 1 1) + (func (export "testfn") + (memory.copy (f64.const 10) (f64.const 20) (f64.const 30)))) + "type mismatch") + + +(module + (memory i64 1 1) + (func (export "test") + (memory.fill (i64.const 10) (i32.const 0x55) (i64.const 10)) + (memory.copy (i64.const 9) (i64.const 10) (i64.const 5))) + + (func (export "checkRange") (param $from i64) (param $to i64) (param $expected i32) (result i64) + (loop $cont + (if (i64.eq (local.get $from) (local.get $to)) + (then + (return (i64.const -1)))) + (if (i32.eq (i32.load8_u (local.get $from)) (local.get $expected)) + (then + (local.set $from (i64.add (local.get $from) (i64.const 1))) + (br $cont)))) + (return (local.get $from))) +) +(invoke "test") + +(assert_return (invoke "checkRange" (i64.const 0) (i64.const 9) (i32.const 0)) + (i64.const -1)) +(assert_return (invoke "checkRange" (i64.const 9) (i64.const 20) (i32.const 85)) + (i64.const -1)) +(assert_return (invoke "checkRange" (i64.const 20) (i64.const 65536) (i32.const 0)) + (i64.const -1)) + +(module + (memory i64 1 1) + (func (export "test") + (memory.fill (i64.const 10) (i32.const 0x55) (i64.const 10)) + (memory.copy (i64.const 16) (i64.const 15) (i64.const 5))) + + (func (export "checkRange") (param $from i64) (param $to i64) (param $expected i32) (result i64) + (loop $cont + (if (i64.eq (local.get $from) (local.get $to)) + (then + (return (i64.const -1)))) + (if (i32.eq (i32.load8_u (local.get $from)) (local.get $expected)) + (then + (local.set $from (i64.add (local.get $from) (i64.const 1))) + (br $cont)))) + (return (local.get $from))) +) +(invoke "test") + +(assert_return (invoke "checkRange" (i64.const 0) (i64.const 10) (i32.const 0)) + (i64.const -1)) +(assert_return (invoke "checkRange" (i64.const 10) (i64.const 21) (i32.const 85)) + (i64.const -1)) +(assert_return (invoke "checkRange" (i64.const 21) (i64.const 65536) (i32.const 0)) + (i64.const -1)) + +(module + (memory i64 1 1) + (func (export "test") + (memory.copy (i64.const 0xFF00) (i64.const 0x8000) (i64.const 257)))) +(assert_trap (invoke "test") "out of bounds memory access") + +(module + (memory i64 1 1) + (func (export "test") + (memory.copy (i64.const 0xFFFFFF00) (i64.const 0x4000) (i64.const 257)))) +(assert_trap (invoke "test") "out of bounds memory access") + +(module + (memory i64 1 1) + (func (export "test") + (memory.copy (i64.const 0x8000) (i64.const 0xFF00) (i64.const 257)))) +(assert_trap (invoke "test") "out of bounds memory access") + +(module + (memory i64 1 1) + (func (export "test") + (memory.copy (i64.const 0x4000) (i64.const 0xFFFFFF00) (i64.const 257)))) +(assert_trap (invoke "test") "out of bounds memory access") + +(module + (memory i64 1 1) + (func (export "test") + (memory.fill (i64.const 0x0000) (i32.const 0x55) (i64.const 0x8000)) + (memory.fill (i64.const 0x8000) (i32.const 0xAA) (i64.const 0x8000)) + (memory.copy (i64.const 0x9000) (i64.const 0x7000) (i64.const 0))) + + (func (export "checkRange") (param $from i64) (param $to i64) (param $expected i32) (result i64) + (loop $cont + (if (i64.eq (local.get $from) (local.get $to)) + (then + (return (i64.const -1)))) + (if (i32.eq (i32.load8_u (local.get $from)) (local.get $expected)) + (then + (local.set $from (i64.add (local.get $from) (i64.const 1))) + (br $cont)))) + (return (local.get $from))) +) +(invoke "test") + +(assert_return (invoke "checkRange" (i64.const 0) (i64.const 32768) (i32.const 85)) + (i64.const -1)) +(assert_return (invoke "checkRange" (i64.const 32768) (i64.const 65536) (i32.const 170)) + (i64.const -1)) +(module + (memory i64 1 1) + (func (export "test") + (memory.copy (i64.const 0x10000) (i64.const 0x7000) (i64.const 0)))) +(invoke "test") + +(module + (memory i64 1 1) + (func (export "test") + (memory.copy (i64.const 0x20000) (i64.const 0x7000) (i64.const 0)))) +(assert_trap (invoke "test") "out of bounds memory access") + +(module + (memory i64 1 1) + (func (export "test") + (memory.copy (i64.const 0x9000) (i64.const 0x10000) (i64.const 0)))) +(invoke "test") + +(module + (memory i64 1 1) + (func (export "test") + (memory.copy (i64.const 0x9000) (i64.const 0x20000) (i64.const 0)))) +(assert_trap (invoke "test") "out of bounds memory access") + +(module + (memory i64 1 1) + (func (export "test") + (memory.copy (i64.const 0x10000) (i64.const 0x10000) (i64.const 0)))) +(invoke "test") + +(module + (memory i64 1 1) + (func (export "test") + (memory.copy (i64.const 0x20000) (i64.const 0x20000) (i64.const 0)))) +(assert_trap (invoke "test") "out of bounds memory access") + +(module + (memory i64 1 1) + (func (export "test") + (memory.fill (i64.const 17767) (i32.const 1) (i64.const 1344)) + (memory.fill (i64.const 39017) (i32.const 2) (i64.const 1055)) + (memory.fill (i64.const 56401) (i32.const 3) (i64.const 988)) + (memory.fill (i64.const 37962) (i32.const 4) (i64.const 322)) + (memory.fill (i64.const 7977) (i32.const 5) (i64.const 1994)) + (memory.fill (i64.const 22714) (i32.const 6) (i64.const 3036)) + (memory.fill (i64.const 16882) (i32.const 7) (i64.const 2372)) + (memory.fill (i64.const 43491) (i32.const 8) (i64.const 835)) + (memory.fill (i64.const 124) (i32.const 9) (i64.const 1393)) + (memory.fill (i64.const 2132) (i32.const 10) (i64.const 2758)) + (memory.fill (i64.const 8987) (i32.const 11) (i64.const 3098)) + (memory.fill (i64.const 52711) (i32.const 12) (i64.const 741)) + (memory.fill (i64.const 3958) (i32.const 13) (i64.const 2823)) + (memory.fill (i64.const 49715) (i32.const 14) (i64.const 1280)) + (memory.fill (i64.const 50377) (i32.const 15) (i64.const 1466)) + (memory.fill (i64.const 20493) (i32.const 16) (i64.const 3158)) + (memory.fill (i64.const 47665) (i32.const 17) (i64.const 544)) + (memory.fill (i64.const 12451) (i32.const 18) (i64.const 2669)) + (memory.fill (i64.const 24869) (i32.const 19) (i64.const 2651)) + (memory.fill (i64.const 45317) (i32.const 20) (i64.const 1570)) + (memory.fill (i64.const 43096) (i32.const 21) (i64.const 1691)) + (memory.fill (i64.const 33886) (i32.const 22) (i64.const 646)) + (memory.fill (i64.const 48555) (i32.const 23) (i64.const 1858)) + (memory.fill (i64.const 53453) (i32.const 24) (i64.const 2657)) + (memory.fill (i64.const 30363) (i32.const 25) (i64.const 981)) + (memory.fill (i64.const 9300) (i32.const 26) (i64.const 1807)) + (memory.fill (i64.const 50190) (i32.const 27) (i64.const 487)) + (memory.fill (i64.const 62753) (i32.const 28) (i64.const 530)) + (memory.fill (i64.const 36316) (i32.const 29) (i64.const 943)) + (memory.fill (i64.const 6768) (i32.const 30) (i64.const 381)) + (memory.fill (i64.const 51262) (i32.const 31) (i64.const 3089)) + (memory.fill (i64.const 49729) (i32.const 32) (i64.const 658)) + (memory.fill (i64.const 44540) (i32.const 33) (i64.const 1702)) + (memory.fill (i64.const 33342) (i32.const 34) (i64.const 1092)) + (memory.fill (i64.const 50814) (i32.const 35) (i64.const 1410)) + (memory.fill (i64.const 47594) (i32.const 36) (i64.const 2204)) + (memory.fill (i64.const 54123) (i32.const 37) (i64.const 2394)) + (memory.fill (i64.const 55183) (i32.const 38) (i64.const 250)) + (memory.fill (i64.const 22620) (i32.const 39) (i64.const 2097)) + (memory.fill (i64.const 17132) (i32.const 40) (i64.const 3264)) + (memory.fill (i64.const 54331) (i32.const 41) (i64.const 3299)) + (memory.fill (i64.const 39474) (i32.const 42) (i64.const 2796)) + (memory.fill (i64.const 36156) (i32.const 43) (i64.const 2070)) + (memory.fill (i64.const 35308) (i32.const 44) (i64.const 2763)) + (memory.fill (i64.const 32731) (i32.const 45) (i64.const 312)) + (memory.fill (i64.const 63746) (i32.const 46) (i64.const 192)) + (memory.fill (i64.const 30974) (i32.const 47) (i64.const 596)) + (memory.fill (i64.const 16635) (i32.const 48) (i64.const 501)) + (memory.fill (i64.const 57002) (i32.const 49) (i64.const 686)) + (memory.fill (i64.const 34299) (i32.const 50) (i64.const 385)) + (memory.fill (i64.const 60881) (i32.const 51) (i64.const 903)) + (memory.fill (i64.const 61445) (i32.const 52) (i64.const 2390)) + (memory.fill (i64.const 46972) (i32.const 53) (i64.const 1441)) + (memory.fill (i64.const 25973) (i32.const 54) (i64.const 3162)) + (memory.fill (i64.const 5566) (i32.const 55) (i64.const 2135)) + (memory.fill (i64.const 35977) (i32.const 56) (i64.const 519)) + (memory.fill (i64.const 44892) (i32.const 57) (i64.const 3280)) + (memory.fill (i64.const 46760) (i32.const 58) (i64.const 1678)) + (memory.fill (i64.const 46607) (i32.const 59) (i64.const 3168)) + (memory.fill (i64.const 22449) (i32.const 60) (i64.const 1441)) + (memory.fill (i64.const 58609) (i32.const 61) (i64.const 663)) + (memory.fill (i64.const 32261) (i32.const 62) (i64.const 1671)) + (memory.fill (i64.const 3063) (i32.const 63) (i64.const 721)) + (memory.fill (i64.const 34025) (i32.const 64) (i64.const 84)) + (memory.fill (i64.const 33338) (i32.const 65) (i64.const 2029)) + (memory.fill (i64.const 36810) (i32.const 66) (i64.const 29)) + (memory.fill (i64.const 19147) (i32.const 67) (i64.const 3034)) + (memory.fill (i64.const 12616) (i32.const 68) (i64.const 1043)) + (memory.fill (i64.const 18276) (i32.const 69) (i64.const 3324)) + (memory.fill (i64.const 4639) (i32.const 70) (i64.const 1091)) + (memory.fill (i64.const 16158) (i32.const 71) (i64.const 1997)) + (memory.fill (i64.const 18204) (i32.const 72) (i64.const 2259)) + (memory.fill (i64.const 50532) (i32.const 73) (i64.const 3189)) + (memory.fill (i64.const 11028) (i32.const 74) (i64.const 1968)) + (memory.fill (i64.const 15962) (i32.const 75) (i64.const 1455)) + (memory.fill (i64.const 45406) (i32.const 76) (i64.const 1177)) + (memory.fill (i64.const 54137) (i32.const 77) (i64.const 1568)) + (memory.fill (i64.const 33083) (i32.const 78) (i64.const 1642)) + (memory.fill (i64.const 61028) (i32.const 79) (i64.const 3284)) + (memory.fill (i64.const 51729) (i32.const 80) (i64.const 223)) + (memory.fill (i64.const 4361) (i32.const 81) (i64.const 2171)) + (memory.fill (i64.const 57514) (i32.const 82) (i64.const 1322)) + (memory.fill (i64.const 55724) (i32.const 83) (i64.const 2648)) + (memory.fill (i64.const 24091) (i32.const 84) (i64.const 1045)) + (memory.fill (i64.const 43183) (i32.const 85) (i64.const 3097)) + (memory.fill (i64.const 32307) (i32.const 86) (i64.const 2796)) + (memory.fill (i64.const 3811) (i32.const 87) (i64.const 2010)) + (memory.fill (i64.const 54856) (i32.const 88) (i64.const 0)) + (memory.fill (i64.const 49941) (i32.const 89) (i64.const 2069)) + (memory.fill (i64.const 20411) (i32.const 90) (i64.const 2896)) + (memory.fill (i64.const 33826) (i32.const 91) (i64.const 192)) + (memory.fill (i64.const 9402) (i32.const 92) (i64.const 2195)) + (memory.fill (i64.const 12413) (i32.const 93) (i64.const 24)) + (memory.fill (i64.const 14091) (i32.const 94) (i64.const 577)) + (memory.fill (i64.const 44058) (i32.const 95) (i64.const 2089)) + (memory.fill (i64.const 36735) (i32.const 96) (i64.const 3436)) + (memory.fill (i64.const 23288) (i32.const 97) (i64.const 2765)) + (memory.fill (i64.const 6392) (i32.const 98) (i64.const 830)) + (memory.fill (i64.const 33307) (i32.const 99) (i64.const 1938)) + (memory.fill (i64.const 21941) (i32.const 100) (i64.const 2750)) + (memory.copy (i64.const 59214) (i64.const 54248) (i64.const 2098)) + (memory.copy (i64.const 63026) (i64.const 39224) (i64.const 230)) + (memory.copy (i64.const 51833) (i64.const 23629) (i64.const 2300)) + (memory.copy (i64.const 6708) (i64.const 23996) (i64.const 639)) + (memory.copy (i64.const 6990) (i64.const 33399) (i64.const 1097)) + (memory.copy (i64.const 19403) (i64.const 10348) (i64.const 3197)) + (memory.copy (i64.const 27308) (i64.const 54406) (i64.const 100)) + (memory.copy (i64.const 27221) (i64.const 43682) (i64.const 1717)) + (memory.copy (i64.const 60528) (i64.const 8629) (i64.const 119)) + (memory.copy (i64.const 5947) (i64.const 2308) (i64.const 658)) + (memory.copy (i64.const 4787) (i64.const 51631) (i64.const 2269)) + (memory.copy (i64.const 12617) (i64.const 19197) (i64.const 833)) + (memory.copy (i64.const 11854) (i64.const 46505) (i64.const 3300)) + (memory.copy (i64.const 11376) (i64.const 45012) (i64.const 2281)) + (memory.copy (i64.const 34186) (i64.const 6697) (i64.const 2572)) + (memory.copy (i64.const 4936) (i64.const 1690) (i64.const 1328)) + (memory.copy (i64.const 63164) (i64.const 7637) (i64.const 1670)) + (memory.copy (i64.const 44568) (i64.const 18344) (i64.const 33)) + (memory.copy (i64.const 43918) (i64.const 22348) (i64.const 1427)) + (memory.copy (i64.const 46637) (i64.const 49819) (i64.const 1434)) + (memory.copy (i64.const 63684) (i64.const 8755) (i64.const 834)) + (memory.copy (i64.const 33485) (i64.const 20131) (i64.const 3317)) + (memory.copy (i64.const 40575) (i64.const 54317) (i64.const 3201)) + (memory.copy (i64.const 25812) (i64.const 59254) (i64.const 2452)) + (memory.copy (i64.const 19678) (i64.const 56882) (i64.const 346)) + (memory.copy (i64.const 15852) (i64.const 35914) (i64.const 2430)) + (memory.copy (i64.const 11824) (i64.const 35574) (i64.const 300)) + (memory.copy (i64.const 59427) (i64.const 13957) (i64.const 3153)) + (memory.copy (i64.const 34299) (i64.const 60594) (i64.const 1281)) + (memory.copy (i64.const 8964) (i64.const 12276) (i64.const 943)) + (memory.copy (i64.const 2827) (i64.const 10425) (i64.const 1887)) + (memory.copy (i64.const 43194) (i64.const 43910) (i64.const 738)) + (memory.copy (i64.const 63038) (i64.const 18949) (i64.const 122)) + (memory.copy (i64.const 24044) (i64.const 44761) (i64.const 1755)) + (memory.copy (i64.const 22608) (i64.const 14755) (i64.const 702)) + (memory.copy (i64.const 11284) (i64.const 26579) (i64.const 1830)) + (memory.copy (i64.const 23092) (i64.const 20471) (i64.const 1064)) + (memory.copy (i64.const 57248) (i64.const 54770) (i64.const 2631)) + (memory.copy (i64.const 25492) (i64.const 1025) (i64.const 3113)) + (memory.copy (i64.const 49588) (i64.const 44220) (i64.const 975)) + (memory.copy (i64.const 28280) (i64.const 41722) (i64.const 2336)) + (memory.copy (i64.const 61289) (i64.const 230) (i64.const 2872)) + (memory.copy (i64.const 22480) (i64.const 52506) (i64.const 2197)) + (memory.copy (i64.const 40553) (i64.const 9578) (i64.const 1958)) + (memory.copy (i64.const 29004) (i64.const 20862) (i64.const 2186)) + (memory.copy (i64.const 53029) (i64.const 43955) (i64.const 1037)) + (memory.copy (i64.const 25476) (i64.const 35667) (i64.const 1650)) + (memory.copy (i64.const 58516) (i64.const 45819) (i64.const 1986)) + (memory.copy (i64.const 38297) (i64.const 5776) (i64.const 1955)) + (memory.copy (i64.const 28503) (i64.const 55364) (i64.const 2368)) + (memory.copy (i64.const 62619) (i64.const 18108) (i64.const 1356)) + (memory.copy (i64.const 50149) (i64.const 13861) (i64.const 382)) + (memory.copy (i64.const 16904) (i64.const 36341) (i64.const 1900)) + (memory.copy (i64.const 48098) (i64.const 11358) (i64.const 2807)) + (memory.copy (i64.const 28512) (i64.const 40362) (i64.const 323)) + (memory.copy (i64.const 35506) (i64.const 27856) (i64.const 1670)) + (memory.copy (i64.const 62970) (i64.const 53332) (i64.const 1341)) + (memory.copy (i64.const 14133) (i64.const 46312) (i64.const 644)) + (memory.copy (i64.const 29030) (i64.const 19074) (i64.const 496)) + (memory.copy (i64.const 44952) (i64.const 47577) (i64.const 2784)) + (memory.copy (i64.const 39559) (i64.const 44661) (i64.const 1350)) + (memory.copy (i64.const 10352) (i64.const 29274) (i64.const 1475)) + (memory.copy (i64.const 46911) (i64.const 46178) (i64.const 1467)) + (memory.copy (i64.const 4905) (i64.const 28740) (i64.const 1895)) + (memory.copy (i64.const 38012) (i64.const 57253) (i64.const 1751)) + (memory.copy (i64.const 26446) (i64.const 27223) (i64.const 1127)) + (memory.copy (i64.const 58835) (i64.const 24657) (i64.const 1063)) + (memory.copy (i64.const 61356) (i64.const 38790) (i64.const 766)) + (memory.copy (i64.const 44160) (i64.const 2284) (i64.const 1520)) + (memory.copy (i64.const 32740) (i64.const 47237) (i64.const 3014)) + (memory.copy (i64.const 11148) (i64.const 21260) (i64.const 1011)) + (memory.copy (i64.const 7665) (i64.const 31612) (i64.const 3034)) + (memory.copy (i64.const 18044) (i64.const 12987) (i64.const 3320)) + (memory.copy (i64.const 57306) (i64.const 55905) (i64.const 308)) + (memory.copy (i64.const 24675) (i64.const 16815) (i64.const 1155)) + (memory.copy (i64.const 19900) (i64.const 10115) (i64.const 722)) + (memory.copy (i64.const 2921) (i64.const 5935) (i64.const 2370)) + (memory.copy (i64.const 32255) (i64.const 50095) (i64.const 2926)) + (memory.copy (i64.const 15126) (i64.const 17299) (i64.const 2607)) + (memory.copy (i64.const 45575) (i64.const 28447) (i64.const 2045)) + (memory.copy (i64.const 55149) (i64.const 36113) (i64.const 2596)) + (memory.copy (i64.const 28461) (i64.const 54157) (i64.const 1168)) + (memory.copy (i64.const 47951) (i64.const 53385) (i64.const 3137)) + (memory.copy (i64.const 30646) (i64.const 45155) (i64.const 2649)) + (memory.copy (i64.const 5057) (i64.const 4295) (i64.const 52)) + (memory.copy (i64.const 6692) (i64.const 24195) (i64.const 441)) + (memory.copy (i64.const 32984) (i64.const 27117) (i64.const 3445)) + (memory.copy (i64.const 32530) (i64.const 59372) (i64.const 2785)) + (memory.copy (i64.const 34361) (i64.const 8962) (i64.const 2406)) + (memory.copy (i64.const 17893) (i64.const 54538) (i64.const 3381)) + (memory.copy (i64.const 22685) (i64.const 44151) (i64.const 136)) + (memory.copy (i64.const 59089) (i64.const 7077) (i64.const 1045)) + (memory.copy (i64.const 42945) (i64.const 55028) (i64.const 2389)) + (memory.copy (i64.const 44693) (i64.const 20138) (i64.const 877)) + (memory.copy (i64.const 36810) (i64.const 25196) (i64.const 3447)) + (memory.copy (i64.const 45742) (i64.const 31888) (i64.const 854)) + (memory.copy (i64.const 24236) (i64.const 31866) (i64.const 1377)) + (memory.copy (i64.const 33778) (i64.const 692) (i64.const 1594)) + (memory.copy (i64.const 60618) (i64.const 18585) (i64.const 2987)) + (memory.copy (i64.const 50370) (i64.const 41271) (i64.const 1406)) + ) + + (func (export "checkRange") (param $from i64) (param $to i64) (param $expected i32) (result i64) + (loop $cont + (if (i64.eq (local.get $from) (local.get $to)) + (then + (return (i64.const -1)))) + (if (i32.eq (i32.load8_u (local.get $from)) (local.get $expected)) + (then + (local.set $from (i64.add (local.get $from) (i64.const 1))) + (br $cont)))) + (return (local.get $from))) +) +(invoke "test") + +(assert_return (invoke "checkRange" (i64.const 0) (i64.const 124) (i32.const 0)) + (i64.const -1)) +(assert_return (invoke "checkRange" (i64.const 124) (i64.const 1517) (i32.const 9)) + (i64.const -1)) +(assert_return (invoke "checkRange" (i64.const 1517) (i64.const 2132) (i32.const 0)) + (i64.const -1)) +(assert_return (invoke "checkRange" (i64.const 2132) (i64.const 2827) (i32.const 10)) + (i64.const -1)) +(assert_return (invoke "checkRange" (i64.const 2827) (i64.const 2921) (i32.const 92)) + (i64.const -1)) +(assert_return (invoke "checkRange" (i64.const 2921) (i64.const 3538) (i32.const 83)) + (i64.const -1)) +(assert_return (invoke "checkRange" (i64.const 3538) (i64.const 3786) (i32.const 77)) + (i64.const -1)) +(assert_return (invoke "checkRange" (i64.const 3786) (i64.const 4042) (i32.const 97)) + (i64.const -1)) +(assert_return (invoke "checkRange" (i64.const 4042) (i64.const 4651) (i32.const 99)) + (i64.const -1)) +(assert_return (invoke "checkRange" (i64.const 4651) (i64.const 5057) (i32.const 0)) + (i64.const -1)) +(assert_return (invoke "checkRange" (i64.const 5057) (i64.const 5109) (i32.const 99)) + (i64.const -1)) +(assert_return (invoke "checkRange" (i64.const 5109) (i64.const 5291) (i32.const 0)) + (i64.const -1)) +(assert_return (invoke "checkRange" (i64.const 5291) (i64.const 5524) (i32.const 72)) + (i64.const -1)) +(assert_return (invoke "checkRange" (i64.const 5524) (i64.const 5691) (i32.const 92)) + (i64.const -1)) +(assert_return (invoke "checkRange" (i64.const 5691) (i64.const 6552) (i32.const 83)) + (i64.const -1)) +(assert_return (invoke "checkRange" (i64.const 6552) (i64.const 7133) (i32.const 77)) + (i64.const -1)) +(assert_return (invoke "checkRange" (i64.const 7133) (i64.const 7665) (i32.const 99)) + (i64.const -1)) +(assert_return (invoke "checkRange" (i64.const 7665) (i64.const 8314) (i32.const 0)) + (i64.const -1)) +(assert_return (invoke "checkRange" (i64.const 8314) (i64.const 8360) (i32.const 62)) + (i64.const -1)) +(assert_return (invoke "checkRange" (i64.const 8360) (i64.const 8793) (i32.const 86)) + (i64.const -1)) +(assert_return (invoke "checkRange" (i64.const 8793) (i64.const 8979) (i32.const 83)) + (i64.const -1)) +(assert_return (invoke "checkRange" (i64.const 8979) (i64.const 9373) (i32.const 79)) + (i64.const -1)) +(assert_return (invoke "checkRange" (i64.const 9373) (i64.const 9518) (i32.const 95)) + (i64.const -1)) +(assert_return (invoke "checkRange" (i64.const 9518) (i64.const 9934) (i32.const 59)) + (i64.const -1)) +(assert_return (invoke "checkRange" (i64.const 9934) (i64.const 10087) (i32.const 77)) + (i64.const -1)) +(assert_return (invoke "checkRange" (i64.const 10087) (i64.const 10206) (i32.const 5)) + (i64.const -1)) +(assert_return (invoke "checkRange" (i64.const 10206) (i64.const 10230) (i32.const 77)) + (i64.const -1)) +(assert_return (invoke "checkRange" (i64.const 10230) (i64.const 10249) (i32.const 41)) + (i64.const -1)) +(assert_return (invoke "checkRange" (i64.const 10249) (i64.const 11148) (i32.const 83)) + (i64.const -1)) +(assert_return (invoke "checkRange" (i64.const 11148) (i64.const 11356) (i32.const 74)) + (i64.const -1)) +(assert_return (invoke "checkRange" (i64.const 11356) (i64.const 11380) (i32.const 93)) + (i64.const -1)) +(assert_return (invoke "checkRange" (i64.const 11380) (i64.const 11939) (i32.const 74)) + (i64.const -1)) +(assert_return (invoke "checkRange" (i64.const 11939) (i64.const 12159) (i32.const 68)) + (i64.const -1)) +(assert_return (invoke "checkRange" (i64.const 12159) (i64.const 12575) (i32.const 83)) + (i64.const -1)) +(assert_return (invoke "checkRange" (i64.const 12575) (i64.const 12969) (i32.const 79)) + (i64.const -1)) +(assert_return (invoke "checkRange" (i64.const 12969) (i64.const 13114) (i32.const 95)) + (i64.const -1)) +(assert_return (invoke "checkRange" (i64.const 13114) (i64.const 14133) (i32.const 59)) + (i64.const -1)) +(assert_return (invoke "checkRange" (i64.const 14133) (i64.const 14404) (i32.const 76)) + (i64.const -1)) +(assert_return (invoke "checkRange" (i64.const 14404) (i64.const 14428) (i32.const 57)) + (i64.const -1)) +(assert_return (invoke "checkRange" (i64.const 14428) (i64.const 14458) (i32.const 59)) + (i64.const -1)) +(assert_return (invoke "checkRange" (i64.const 14458) (i64.const 14580) (i32.const 32)) + (i64.const -1)) +(assert_return (invoke "checkRange" (i64.const 14580) (i64.const 14777) (i32.const 89)) + (i64.const -1)) +(assert_return (invoke "checkRange" (i64.const 14777) (i64.const 15124) (i32.const 59)) + (i64.const -1)) +(assert_return (invoke "checkRange" (i64.const 15124) (i64.const 15126) (i32.const 36)) + (i64.const -1)) +(assert_return (invoke "checkRange" (i64.const 15126) (i64.const 15192) (i32.const 100)) + (i64.const -1)) +(assert_return (invoke "checkRange" (i64.const 15192) (i64.const 15871) (i32.const 96)) + (i64.const -1)) +(assert_return (invoke "checkRange" (i64.const 15871) (i64.const 15998) (i32.const 95)) + (i64.const -1)) +(assert_return (invoke "checkRange" (i64.const 15998) (i64.const 17017) (i32.const 59)) + (i64.const -1)) +(assert_return (invoke "checkRange" (i64.const 17017) (i64.const 17288) (i32.const 76)) + (i64.const -1)) +(assert_return (invoke "checkRange" (i64.const 17288) (i64.const 17312) (i32.const 57)) + (i64.const -1)) +(assert_return (invoke "checkRange" (i64.const 17312) (i64.const 17342) (i32.const 59)) + (i64.const -1)) +(assert_return (invoke "checkRange" (i64.const 17342) (i64.const 17464) (i32.const 32)) + (i64.const -1)) +(assert_return (invoke "checkRange" (i64.const 17464) (i64.const 17661) (i32.const 89)) + (i64.const -1)) +(assert_return (invoke "checkRange" (i64.const 17661) (i64.const 17727) (i32.const 59)) + (i64.const -1)) +(assert_return (invoke "checkRange" (i64.const 17727) (i64.const 17733) (i32.const 5)) + (i64.const -1)) +(assert_return (invoke "checkRange" (i64.const 17733) (i64.const 17893) (i32.const 96)) + (i64.const -1)) +(assert_return (invoke "checkRange" (i64.const 17893) (i64.const 18553) (i32.const 77)) + (i64.const -1)) +(assert_return (invoke "checkRange" (i64.const 18553) (i64.const 18744) (i32.const 42)) + (i64.const -1)) +(assert_return (invoke "checkRange" (i64.const 18744) (i64.const 18801) (i32.const 76)) + (i64.const -1)) +(assert_return (invoke "checkRange" (i64.const 18801) (i64.const 18825) (i32.const 57)) + (i64.const -1)) +(assert_return (invoke "checkRange" (i64.const 18825) (i64.const 18876) (i32.const 59)) + (i64.const -1)) +(assert_return (invoke "checkRange" (i64.const 18876) (i64.const 18885) (i32.const 77)) + (i64.const -1)) +(assert_return (invoke "checkRange" (i64.const 18885) (i64.const 18904) (i32.const 41)) + (i64.const -1)) +(assert_return (invoke "checkRange" (i64.const 18904) (i64.const 19567) (i32.const 83)) + (i64.const -1)) +(assert_return (invoke "checkRange" (i64.const 19567) (i64.const 20403) (i32.const 96)) + (i64.const -1)) +(assert_return (invoke "checkRange" (i64.const 20403) (i64.const 21274) (i32.const 77)) + (i64.const -1)) +(assert_return (invoke "checkRange" (i64.const 21274) (i64.const 21364) (i32.const 100)) + (i64.const -1)) +(assert_return (invoke "checkRange" (i64.const 21364) (i64.const 21468) (i32.const 74)) + (i64.const -1)) +(assert_return (invoke "checkRange" (i64.const 21468) (i64.const 21492) (i32.const 93)) + (i64.const -1)) +(assert_return (invoke "checkRange" (i64.const 21492) (i64.const 22051) (i32.const 74)) + (i64.const -1)) +(assert_return (invoke "checkRange" (i64.const 22051) (i64.const 22480) (i32.const 68)) + (i64.const -1)) +(assert_return (invoke "checkRange" (i64.const 22480) (i64.const 22685) (i32.const 100)) + (i64.const -1)) +(assert_return (invoke "checkRange" (i64.const 22685) (i64.const 22694) (i32.const 68)) + (i64.const -1)) +(assert_return (invoke "checkRange" (i64.const 22694) (i64.const 22821) (i32.const 10)) + (i64.const -1)) +(assert_return (invoke "checkRange" (i64.const 22821) (i64.const 22869) (i32.const 100)) + (i64.const -1)) +(assert_return (invoke "checkRange" (i64.const 22869) (i64.const 24107) (i32.const 97)) + (i64.const -1)) +(assert_return (invoke "checkRange" (i64.const 24107) (i64.const 24111) (i32.const 37)) + (i64.const -1)) +(assert_return (invoke "checkRange" (i64.const 24111) (i64.const 24236) (i32.const 77)) + (i64.const -1)) +(assert_return (invoke "checkRange" (i64.const 24236) (i64.const 24348) (i32.const 72)) + (i64.const -1)) +(assert_return (invoke "checkRange" (i64.const 24348) (i64.const 24515) (i32.const 92)) + (i64.const -1)) +(assert_return (invoke "checkRange" (i64.const 24515) (i64.const 24900) (i32.const 83)) + (i64.const -1)) +(assert_return (invoke "checkRange" (i64.const 24900) (i64.const 25136) (i32.const 95)) + (i64.const -1)) +(assert_return (invoke "checkRange" (i64.const 25136) (i64.const 25182) (i32.const 85)) + (i64.const -1)) +(assert_return (invoke "checkRange" (i64.const 25182) (i64.const 25426) (i32.const 68)) + (i64.const -1)) +(assert_return (invoke "checkRange" (i64.const 25426) (i64.const 25613) (i32.const 89)) + (i64.const -1)) +(assert_return (invoke "checkRange" (i64.const 25613) (i64.const 25830) (i32.const 96)) + (i64.const -1)) +(assert_return (invoke "checkRange" (i64.const 25830) (i64.const 26446) (i32.const 100)) + (i64.const -1)) +(assert_return (invoke "checkRange" (i64.const 26446) (i64.const 26517) (i32.const 10)) + (i64.const -1)) +(assert_return (invoke "checkRange" (i64.const 26517) (i64.const 27468) (i32.const 92)) + (i64.const -1)) +(assert_return (invoke "checkRange" (i64.const 27468) (i64.const 27503) (i32.const 95)) + (i64.const -1)) +(assert_return (invoke "checkRange" (i64.const 27503) (i64.const 27573) (i32.const 77)) + (i64.const -1)) +(assert_return (invoke "checkRange" (i64.const 27573) (i64.const 28245) (i32.const 92)) + (i64.const -1)) +(assert_return (invoke "checkRange" (i64.const 28245) (i64.const 28280) (i32.const 95)) + (i64.const -1)) +(assert_return (invoke "checkRange" (i64.const 28280) (i64.const 29502) (i32.const 77)) + (i64.const -1)) +(assert_return (invoke "checkRange" (i64.const 29502) (i64.const 29629) (i32.const 42)) + (i64.const -1)) +(assert_return (invoke "checkRange" (i64.const 29629) (i64.const 30387) (i32.const 83)) + (i64.const -1)) +(assert_return (invoke "checkRange" (i64.const 30387) (i64.const 30646) (i32.const 77)) + (i64.const -1)) +(assert_return (invoke "checkRange" (i64.const 30646) (i64.const 31066) (i32.const 92)) + (i64.const -1)) +(assert_return (invoke "checkRange" (i64.const 31066) (i64.const 31131) (i32.const 77)) + (i64.const -1)) +(assert_return (invoke "checkRange" (i64.const 31131) (i64.const 31322) (i32.const 42)) + (i64.const -1)) +(assert_return (invoke "checkRange" (i64.const 31322) (i64.const 31379) (i32.const 76)) + (i64.const -1)) +(assert_return (invoke "checkRange" (i64.const 31379) (i64.const 31403) (i32.const 57)) + (i64.const -1)) +(assert_return (invoke "checkRange" (i64.const 31403) (i64.const 31454) (i32.const 59)) + (i64.const -1)) +(assert_return (invoke "checkRange" (i64.const 31454) (i64.const 31463) (i32.const 77)) + (i64.const -1)) +(assert_return (invoke "checkRange" (i64.const 31463) (i64.const 31482) (i32.const 41)) + (i64.const -1)) +(assert_return (invoke "checkRange" (i64.const 31482) (i64.const 31649) (i32.const 83)) + (i64.const -1)) +(assert_return (invoke "checkRange" (i64.const 31649) (i64.const 31978) (i32.const 72)) + (i64.const -1)) +(assert_return (invoke "checkRange" (i64.const 31978) (i64.const 32145) (i32.const 92)) + (i64.const -1)) +(assert_return (invoke "checkRange" (i64.const 32145) (i64.const 32530) (i32.const 83)) + (i64.const -1)) +(assert_return (invoke "checkRange" (i64.const 32530) (i64.const 32766) (i32.const 95)) + (i64.const -1)) +(assert_return (invoke "checkRange" (i64.const 32766) (i64.const 32812) (i32.const 85)) + (i64.const -1)) +(assert_return (invoke "checkRange" (i64.const 32812) (i64.const 33056) (i32.const 68)) + (i64.const -1)) +(assert_return (invoke "checkRange" (i64.const 33056) (i64.const 33660) (i32.const 89)) + (i64.const -1)) +(assert_return (invoke "checkRange" (i64.const 33660) (i64.const 33752) (i32.const 59)) + (i64.const -1)) +(assert_return (invoke "checkRange" (i64.const 33752) (i64.const 33775) (i32.const 36)) + (i64.const -1)) +(assert_return (invoke "checkRange" (i64.const 33775) (i64.const 33778) (i32.const 32)) + (i64.const -1)) +(assert_return (invoke "checkRange" (i64.const 33778) (i64.const 34603) (i32.const 9)) + (i64.const -1)) +(assert_return (invoke "checkRange" (i64.const 34603) (i64.const 35218) (i32.const 0)) + (i64.const -1)) +(assert_return (invoke "checkRange" (i64.const 35218) (i64.const 35372) (i32.const 10)) + (i64.const -1)) +(assert_return (invoke "checkRange" (i64.const 35372) (i64.const 35486) (i32.const 77)) + (i64.const -1)) +(assert_return (invoke "checkRange" (i64.const 35486) (i64.const 35605) (i32.const 5)) + (i64.const -1)) +(assert_return (invoke "checkRange" (i64.const 35605) (i64.const 35629) (i32.const 77)) + (i64.const -1)) +(assert_return (invoke "checkRange" (i64.const 35629) (i64.const 35648) (i32.const 41)) + (i64.const -1)) +(assert_return (invoke "checkRange" (i64.const 35648) (i64.const 36547) (i32.const 83)) + (i64.const -1)) +(assert_return (invoke "checkRange" (i64.const 36547) (i64.const 36755) (i32.const 74)) + (i64.const -1)) +(assert_return (invoke "checkRange" (i64.const 36755) (i64.const 36767) (i32.const 93)) + (i64.const -1)) +(assert_return (invoke "checkRange" (i64.const 36767) (i64.const 36810) (i32.const 83)) + (i64.const -1)) +(assert_return (invoke "checkRange" (i64.const 36810) (i64.const 36839) (i32.const 100)) + (i64.const -1)) +(assert_return (invoke "checkRange" (i64.const 36839) (i64.const 37444) (i32.const 96)) + (i64.const -1)) +(assert_return (invoke "checkRange" (i64.const 37444) (i64.const 38060) (i32.const 100)) + (i64.const -1)) +(assert_return (invoke "checkRange" (i64.const 38060) (i64.const 38131) (i32.const 10)) + (i64.const -1)) +(assert_return (invoke "checkRange" (i64.const 38131) (i64.const 39082) (i32.const 92)) + (i64.const -1)) +(assert_return (invoke "checkRange" (i64.const 39082) (i64.const 39117) (i32.const 95)) + (i64.const -1)) +(assert_return (invoke "checkRange" (i64.const 39117) (i64.const 39187) (i32.const 77)) + (i64.const -1)) +(assert_return (invoke "checkRange" (i64.const 39187) (i64.const 39859) (i32.const 92)) + (i64.const -1)) +(assert_return (invoke "checkRange" (i64.const 39859) (i64.const 39894) (i32.const 95)) + (i64.const -1)) +(assert_return (invoke "checkRange" (i64.const 39894) (i64.const 40257) (i32.const 77)) + (i64.const -1)) +(assert_return (invoke "checkRange" (i64.const 40257) (i64.const 40344) (i32.const 89)) + (i64.const -1)) +(assert_return (invoke "checkRange" (i64.const 40344) (i64.const 40371) (i32.const 59)) + (i64.const -1)) +(assert_return (invoke "checkRange" (i64.const 40371) (i64.const 40804) (i32.const 77)) + (i64.const -1)) +(assert_return (invoke "checkRange" (i64.const 40804) (i64.const 40909) (i32.const 5)) + (i64.const -1)) +(assert_return (invoke "checkRange" (i64.const 40909) (i64.const 42259) (i32.const 92)) + (i64.const -1)) +(assert_return (invoke "checkRange" (i64.const 42259) (i64.const 42511) (i32.const 77)) + (i64.const -1)) +(assert_return (invoke "checkRange" (i64.const 42511) (i64.const 42945) (i32.const 83)) + (i64.const -1)) +(assert_return (invoke "checkRange" (i64.const 42945) (i64.const 43115) (i32.const 77)) + (i64.const -1)) +(assert_return (invoke "checkRange" (i64.const 43115) (i64.const 43306) (i32.const 42)) + (i64.const -1)) +(assert_return (invoke "checkRange" (i64.const 43306) (i64.const 43363) (i32.const 76)) + (i64.const -1)) +(assert_return (invoke "checkRange" (i64.const 43363) (i64.const 43387) (i32.const 57)) + (i64.const -1)) +(assert_return (invoke "checkRange" (i64.const 43387) (i64.const 43438) (i32.const 59)) + (i64.const -1)) +(assert_return (invoke "checkRange" (i64.const 43438) (i64.const 43447) (i32.const 77)) + (i64.const -1)) +(assert_return (invoke "checkRange" (i64.const 43447) (i64.const 43466) (i32.const 41)) + (i64.const -1)) +(assert_return (invoke "checkRange" (i64.const 43466) (i64.const 44129) (i32.const 83)) + (i64.const -1)) +(assert_return (invoke "checkRange" (i64.const 44129) (i64.const 44958) (i32.const 96)) + (i64.const -1)) +(assert_return (invoke "checkRange" (i64.const 44958) (i64.const 45570) (i32.const 77)) + (i64.const -1)) +(assert_return (invoke "checkRange" (i64.const 45570) (i64.const 45575) (i32.const 92)) + (i64.const -1)) +(assert_return (invoke "checkRange" (i64.const 45575) (i64.const 45640) (i32.const 77)) + (i64.const -1)) +(assert_return (invoke "checkRange" (i64.const 45640) (i64.const 45742) (i32.const 42)) + (i64.const -1)) +(assert_return (invoke "checkRange" (i64.const 45742) (i64.const 45832) (i32.const 72)) + (i64.const -1)) +(assert_return (invoke "checkRange" (i64.const 45832) (i64.const 45999) (i32.const 92)) + (i64.const -1)) +(assert_return (invoke "checkRange" (i64.const 45999) (i64.const 46384) (i32.const 83)) + (i64.const -1)) +(assert_return (invoke "checkRange" (i64.const 46384) (i64.const 46596) (i32.const 95)) + (i64.const -1)) +(assert_return (invoke "checkRange" (i64.const 46596) (i64.const 46654) (i32.const 92)) + (i64.const -1)) +(assert_return (invoke "checkRange" (i64.const 46654) (i64.const 47515) (i32.const 83)) + (i64.const -1)) +(assert_return (invoke "checkRange" (i64.const 47515) (i64.const 47620) (i32.const 77)) + (i64.const -1)) +(assert_return (invoke "checkRange" (i64.const 47620) (i64.const 47817) (i32.const 79)) + (i64.const -1)) +(assert_return (invoke "checkRange" (i64.const 47817) (i64.const 47951) (i32.const 95)) + (i64.const -1)) +(assert_return (invoke "checkRange" (i64.const 47951) (i64.const 48632) (i32.const 100)) + (i64.const -1)) +(assert_return (invoke "checkRange" (i64.const 48632) (i64.const 48699) (i32.const 97)) + (i64.const -1)) +(assert_return (invoke "checkRange" (i64.const 48699) (i64.const 48703) (i32.const 37)) + (i64.const -1)) +(assert_return (invoke "checkRange" (i64.const 48703) (i64.const 49764) (i32.const 77)) + (i64.const -1)) +(assert_return (invoke "checkRange" (i64.const 49764) (i64.const 49955) (i32.const 42)) + (i64.const -1)) +(assert_return (invoke "checkRange" (i64.const 49955) (i64.const 50012) (i32.const 76)) + (i64.const -1)) +(assert_return (invoke "checkRange" (i64.const 50012) (i64.const 50036) (i32.const 57)) + (i64.const -1)) +(assert_return (invoke "checkRange" (i64.const 50036) (i64.const 50087) (i32.const 59)) + (i64.const -1)) +(assert_return (invoke "checkRange" (i64.const 50087) (i64.const 50096) (i32.const 77)) + (i64.const -1)) +(assert_return (invoke "checkRange" (i64.const 50096) (i64.const 50115) (i32.const 41)) + (i64.const -1)) +(assert_return (invoke "checkRange" (i64.const 50115) (i64.const 50370) (i32.const 83)) + (i64.const -1)) +(assert_return (invoke "checkRange" (i64.const 50370) (i64.const 51358) (i32.const 92)) + (i64.const -1)) +(assert_return (invoke "checkRange" (i64.const 51358) (i64.const 51610) (i32.const 77)) + (i64.const -1)) +(assert_return (invoke "checkRange" (i64.const 51610) (i64.const 51776) (i32.const 83)) + (i64.const -1)) +(assert_return (invoke "checkRange" (i64.const 51776) (i64.const 51833) (i32.const 89)) + (i64.const -1)) +(assert_return (invoke "checkRange" (i64.const 51833) (i64.const 52895) (i32.const 100)) + (i64.const -1)) +(assert_return (invoke "checkRange" (i64.const 52895) (i64.const 53029) (i32.const 97)) + (i64.const -1)) +(assert_return (invoke "checkRange" (i64.const 53029) (i64.const 53244) (i32.const 68)) + (i64.const -1)) +(assert_return (invoke "checkRange" (i64.const 53244) (i64.const 54066) (i32.const 100)) + (i64.const -1)) +(assert_return (invoke "checkRange" (i64.const 54066) (i64.const 54133) (i32.const 97)) + (i64.const -1)) +(assert_return (invoke "checkRange" (i64.const 54133) (i64.const 54137) (i32.const 37)) + (i64.const -1)) +(assert_return (invoke "checkRange" (i64.const 54137) (i64.const 55198) (i32.const 77)) + (i64.const -1)) +(assert_return (invoke "checkRange" (i64.const 55198) (i64.const 55389) (i32.const 42)) + (i64.const -1)) +(assert_return (invoke "checkRange" (i64.const 55389) (i64.const 55446) (i32.const 76)) + (i64.const -1)) +(assert_return (invoke "checkRange" (i64.const 55446) (i64.const 55470) (i32.const 57)) + (i64.const -1)) +(assert_return (invoke "checkRange" (i64.const 55470) (i64.const 55521) (i32.const 59)) + (i64.const -1)) +(assert_return (invoke "checkRange" (i64.const 55521) (i64.const 55530) (i32.const 77)) + (i64.const -1)) +(assert_return (invoke "checkRange" (i64.const 55530) (i64.const 55549) (i32.const 41)) + (i64.const -1)) +(assert_return (invoke "checkRange" (i64.const 55549) (i64.const 56212) (i32.const 83)) + (i64.const -1)) +(assert_return (invoke "checkRange" (i64.const 56212) (i64.const 57048) (i32.const 96)) + (i64.const -1)) +(assert_return (invoke "checkRange" (i64.const 57048) (i64.const 58183) (i32.const 77)) + (i64.const -1)) +(assert_return (invoke "checkRange" (i64.const 58183) (i64.const 58202) (i32.const 41)) + (i64.const -1)) +(assert_return (invoke "checkRange" (i64.const 58202) (i64.const 58516) (i32.const 83)) + (i64.const -1)) +(assert_return (invoke "checkRange" (i64.const 58516) (i64.const 58835) (i32.const 95)) + (i64.const -1)) +(assert_return (invoke "checkRange" (i64.const 58835) (i64.const 58855) (i32.const 77)) + (i64.const -1)) +(assert_return (invoke "checkRange" (i64.const 58855) (i64.const 59089) (i32.const 95)) + (i64.const -1)) +(assert_return (invoke "checkRange" (i64.const 59089) (i64.const 59145) (i32.const 77)) + (i64.const -1)) +(assert_return (invoke "checkRange" (i64.const 59145) (i64.const 59677) (i32.const 99)) + (i64.const -1)) +(assert_return (invoke "checkRange" (i64.const 59677) (i64.const 60134) (i32.const 0)) + (i64.const -1)) +(assert_return (invoke "checkRange" (i64.const 60134) (i64.const 60502) (i32.const 89)) + (i64.const -1)) +(assert_return (invoke "checkRange" (i64.const 60502) (i64.const 60594) (i32.const 59)) + (i64.const -1)) +(assert_return (invoke "checkRange" (i64.const 60594) (i64.const 60617) (i32.const 36)) + (i64.const -1)) +(assert_return (invoke "checkRange" (i64.const 60617) (i64.const 60618) (i32.const 32)) + (i64.const -1)) +(assert_return (invoke "checkRange" (i64.const 60618) (i64.const 60777) (i32.const 42)) + (i64.const -1)) +(assert_return (invoke "checkRange" (i64.const 60777) (i64.const 60834) (i32.const 76)) + (i64.const -1)) +(assert_return (invoke "checkRange" (i64.const 60834) (i64.const 60858) (i32.const 57)) + (i64.const -1)) +(assert_return (invoke "checkRange" (i64.const 60858) (i64.const 60909) (i32.const 59)) + (i64.const -1)) +(assert_return (invoke "checkRange" (i64.const 60909) (i64.const 60918) (i32.const 77)) + (i64.const -1)) +(assert_return (invoke "checkRange" (i64.const 60918) (i64.const 60937) (i32.const 41)) + (i64.const -1)) +(assert_return (invoke "checkRange" (i64.const 60937) (i64.const 61600) (i32.const 83)) + (i64.const -1)) +(assert_return (invoke "checkRange" (i64.const 61600) (i64.const 62436) (i32.const 96)) + (i64.const -1)) +(assert_return (invoke "checkRange" (i64.const 62436) (i64.const 63307) (i32.const 77)) + (i64.const -1)) +(assert_return (invoke "checkRange" (i64.const 63307) (i64.const 63397) (i32.const 100)) + (i64.const -1)) +(assert_return (invoke "checkRange" (i64.const 63397) (i64.const 63501) (i32.const 74)) + (i64.const -1)) +(assert_return (invoke "checkRange" (i64.const 63501) (i64.const 63525) (i32.const 93)) + (i64.const -1)) +(assert_return (invoke "checkRange" (i64.const 63525) (i64.const 63605) (i32.const 74)) + (i64.const -1)) +(assert_return (invoke "checkRange" (i64.const 63605) (i64.const 63704) (i32.const 100)) + (i64.const -1)) +(assert_return (invoke "checkRange" (i64.const 63704) (i64.const 63771) (i32.const 97)) + (i64.const -1)) +(assert_return (invoke "checkRange" (i64.const 63771) (i64.const 63775) (i32.const 37)) + (i64.const -1)) +(assert_return (invoke "checkRange" (i64.const 63775) (i64.const 64311) (i32.const 77)) + (i64.const -1)) +(assert_return (invoke "checkRange" (i64.const 64311) (i64.const 64331) (i32.const 26)) + (i64.const -1)) +(assert_return (invoke "checkRange" (i64.const 64331) (i64.const 64518) (i32.const 92)) + (i64.const -1)) +(assert_return (invoke "checkRange" (i64.const 64518) (i64.const 64827) (i32.const 11)) + (i64.const -1)) +(assert_return (invoke "checkRange" (i64.const 64827) (i64.const 64834) (i32.const 26)) + (i64.const -1)) +(assert_return (invoke "checkRange" (i64.const 64834) (i64.const 65536) (i32.const 0)) + (i64.const -1)) diff --git a/test/core/memory_fill.wast b/test/core/memory_fill.wast index 98374a1586..90c6b799fb 100644 --- a/test/core/memory_fill.wast +++ b/test/core/memory_fill.wast @@ -684,3 +684,685 @@ (assert_return (invoke "checkRange" (i32.const 0) (i32.const 1) (i32.const 0)) (i32.const -1)) + +(module + (memory i64 1 1) + + (func (export "checkRange") (param $from i64) (param $to i64) (param $expected i32) (result i64) + (loop $cont + (if (i64.eq (local.get $from) (local.get $to)) + (then + (return (i64.const -1)))) + (if (i32.eq (i32.load8_u (local.get $from)) (local.get $expected)) + (then + (local.set $from (i64.add (local.get $from) (i64.const 1))) + (br $cont)))) + (return (local.get $from))) + + (func (export "test") + (memory.fill (i64.const 0xFF00) (i32.const 0x55) (i64.const 256)))) +(invoke "test") + +(assert_return (invoke "checkRange" (i64.const 0) (i64.const 65280) (i32.const 0)) + (i64.const -1)) +(assert_return (invoke "checkRange" (i64.const 65280) (i64.const 65536) (i32.const 85)) + (i64.const -1)) +(module + (memory i64 1 1) + + (func (export "checkRange") (param $from i64) (param $to i64) (param $expected i32) (result i64) + (loop $cont + (if (i64.eq (local.get $from) (local.get $to)) + (then + (return (i64.const -1)))) + (if (i32.eq (i32.load8_u (local.get $from)) (local.get $expected)) + (then + (local.set $from (i64.add (local.get $from) (i64.const 1))) + (br $cont)))) + (return (local.get $from))) + + (func (export "test") + (memory.fill (i64.const 0xFF00) (i32.const 0x55) (i64.const 257)))) +(assert_trap (invoke "test") "out of bounds memory access") + +(module + (memory i64 1 1) + + (func (export "checkRange") (param $from i64) (param $to i64) (param $expected i32) (result i64) + (loop $cont + (if (i64.eq (local.get $from) (local.get $to)) + (then + (return (i64.const -1)))) + (if (i32.eq (i32.load8_u (local.get $from)) (local.get $expected)) + (then + (local.set $from (i64.add (local.get $from) (i64.const 1))) + (br $cont)))) + (return (local.get $from))) + + (func (export "test") + (memory.fill (i64.const 0xFFFFFF00) (i32.const 0x55) (i64.const 257)))) +(assert_trap (invoke "test") "out of bounds memory access") + +(module + (memory i64 1 1) + + (func (export "checkRange") (param $from i64) (param $to i64) (param $expected i32) (result i64) + (loop $cont + (if (i64.eq (local.get $from) (local.get $to)) + (then + (return (i64.const -1)))) + (if (i32.eq (i32.load8_u (local.get $from)) (local.get $expected)) + (then + (local.set $from (i64.add (local.get $from) (i64.const 1))) + (br $cont)))) + (return (local.get $from))) + + (func (export "test") + (memory.fill (i64.const 0x12) (i32.const 0x55) (i64.const 0)))) +(invoke "test") + +(assert_return (invoke "checkRange" (i64.const 0) (i64.const 65536) (i32.const 0)) + (i64.const -1)) +(module + (memory i64 1 1) + + (func (export "checkRange") (param $from i64) (param $to i64) (param $expected i32) (result i64) + (loop $cont + (if (i64.eq (local.get $from) (local.get $to)) + (then + (return (i64.const -1)))) + (if (i32.eq (i32.load8_u (local.get $from)) (local.get $expected)) + (then + (local.set $from (i64.add (local.get $from) (i64.const 1))) + (br $cont)))) + (return (local.get $from))) + + (func (export "test") + (memory.fill (i64.const 0x10000) (i32.const 0x55) (i64.const 0)))) +(invoke "test") + +(module + (memory i64 1 1) + + (func (export "checkRange") (param $from i64) (param $to i64) (param $expected i32) (result i64) + (loop $cont + (if (i64.eq (local.get $from) (local.get $to)) + (then + (return (i64.const -1)))) + (if (i32.eq (i32.load8_u (local.get $from)) (local.get $expected)) + (then + (local.set $from (i64.add (local.get $from) (i64.const 1))) + (br $cont)))) + (return (local.get $from))) + + (func (export "test") + (memory.fill (i64.const 0x20000) (i32.const 0x55) (i64.const 0)))) +(assert_trap (invoke "test") "out of bounds memory access") + +(module + (memory i64 1 1) + + (func (export "checkRange") (param $from i64) (param $to i64) (param $expected i32) (result i64) + (loop $cont + (if (i64.eq (local.get $from) (local.get $to)) + (then + (return (i64.const -1)))) + (if (i32.eq (i32.load8_u (local.get $from)) (local.get $expected)) + (then + (local.set $from (i64.add (local.get $from) (i64.const 1))) + (br $cont)))) + (return (local.get $from))) + + (func (export "test") + (memory.fill (i64.const 0x1) (i32.const 0xAA) (i64.const 0xFFFE)))) +(invoke "test") + +(assert_return (invoke "checkRange" (i64.const 0) (i64.const 1) (i32.const 0)) + (i64.const -1)) +(assert_return (invoke "checkRange" (i64.const 1) (i64.const 65535) (i32.const 170)) + (i64.const -1)) +(assert_return (invoke "checkRange" (i64.const 65535) (i64.const 65536) (i32.const 0)) + (i64.const -1)) + +(module + (memory i64 1 1) + + (func (export "checkRange") (param $from i64) (param $to i64) (param $expected i32) (result i64) + (loop $cont + (if (i64.eq (local.get $from) (local.get $to)) + (then + (return (i64.const -1)))) + (if (i32.eq (i32.load8_u (local.get $from)) (local.get $expected)) + (then + (local.set $from (i64.add (local.get $from) (i64.const 1))) + (br $cont)))) + (return (local.get $from))) + + (func (export "test") + (memory.fill (i64.const 0x12) (i32.const 0x55) (i64.const 10)) + (memory.fill (i64.const 0x15) (i32.const 0xAA) (i64.const 4)))) +(invoke "test") + +(assert_return (invoke "checkRange" (i64.const 0) (i64.const 18) (i32.const 0)) + (i64.const -1)) +(assert_return (invoke "checkRange" (i64.const 18) (i64.const 21) (i32.const 85)) + (i64.const -1)) +(assert_return (invoke "checkRange" (i64.const 21) (i64.const 25) (i32.const 170)) + (i64.const -1)) +(assert_return (invoke "checkRange" (i64.const 25) (i64.const 28) (i32.const 85)) + (i64.const -1)) +(assert_return (invoke "checkRange" (i64.const 28) (i64.const 65536) (i32.const 0)) + (i64.const -1)) +(assert_invalid + (module + (func (export "testfn") + (memory.fill (i64.const 10) (i32.const 20) (i64.const 30)))) + "unknown memory 0") + +(assert_invalid + (module + (memory i64 1 1) + (func (export "testfn") + (memory.fill (i32.const 10) (i32.const 20) (i32.const 30)))) + "type mismatch") + +(assert_invalid + (module + (memory i64 1 1) + (func (export "testfn") + (memory.fill (i32.const 10) (i32.const 20) (f32.const 30)))) + "type mismatch") + +(assert_invalid + (module + (memory i64 1 1) + (func (export "testfn") + (memory.fill (i32.const 10) (i32.const 20) (i64.const 30)))) + "type mismatch") + +(assert_invalid + (module + (memory i64 1 1) + (func (export "testfn") + (memory.fill (i32.const 10) (i32.const 20) (f64.const 30)))) + "type mismatch") + +(assert_invalid + (module + (memory i64 1 1) + (func (export "testfn") + (memory.fill (i32.const 10) (f32.const 20) (i32.const 30)))) + "type mismatch") + +(assert_invalid + (module + (memory i64 1 1) + (func (export "testfn") + (memory.fill (i32.const 10) (f32.const 20) (f32.const 30)))) + "type mismatch") + +(assert_invalid + (module + (memory i64 1 1) + (func (export "testfn") + (memory.fill (i32.const 10) (f32.const 20) (i64.const 30)))) + "type mismatch") + +(assert_invalid + (module + (memory i64 1 1) + (func (export "testfn") + (memory.fill (i32.const 10) (f32.const 20) (f64.const 30)))) + "type mismatch") + +(assert_invalid + (module + (memory i64 1 1) + (func (export "testfn") + (memory.fill (i32.const 10) (i64.const 20) (i32.const 30)))) + "type mismatch") + +(assert_invalid + (module + (memory i64 1 1) + (func (export "testfn") + (memory.fill (i32.const 10) (i64.const 20) (f32.const 30)))) + "type mismatch") + +(assert_invalid + (module + (memory i64 1 1) + (func (export "testfn") + (memory.fill (i32.const 10) (i64.const 20) (i64.const 30)))) + "type mismatch") + +(assert_invalid + (module + (memory i64 1 1) + (func (export "testfn") + (memory.fill (i32.const 10) (i64.const 20) (f64.const 30)))) + "type mismatch") + +(assert_invalid + (module + (memory i64 1 1) + (func (export "testfn") + (memory.fill (i32.const 10) (f64.const 20) (i32.const 30)))) + "type mismatch") + +(assert_invalid + (module + (memory i64 1 1) + (func (export "testfn") + (memory.fill (i32.const 10) (f64.const 20) (f32.const 30)))) + "type mismatch") + +(assert_invalid + (module + (memory i64 1 1) + (func (export "testfn") + (memory.fill (i32.const 10) (f64.const 20) (i64.const 30)))) + "type mismatch") + +(assert_invalid + (module + (memory i64 1 1) + (func (export "testfn") + (memory.fill (i32.const 10) (f64.const 20) (f64.const 30)))) + "type mismatch") + +(assert_invalid + (module + (memory i64 1 1) + (func (export "testfn") + (memory.fill (f32.const 10) (i32.const 20) (i32.const 30)))) + "type mismatch") + +(assert_invalid + (module + (memory i64 1 1) + (func (export "testfn") + (memory.fill (f32.const 10) (i32.const 20) (f32.const 30)))) + "type mismatch") + +(assert_invalid + (module + (memory i64 1 1) + (func (export "testfn") + (memory.fill (f32.const 10) (i32.const 20) (i64.const 30)))) + "type mismatch") + +(assert_invalid + (module + (memory i64 1 1) + (func (export "testfn") + (memory.fill (f32.const 10) (i32.const 20) (f64.const 30)))) + "type mismatch") + +(assert_invalid + (module + (memory i64 1 1) + (func (export "testfn") + (memory.fill (f32.const 10) (f32.const 20) (i32.const 30)))) + "type mismatch") + +(assert_invalid + (module + (memory i64 1 1) + (func (export "testfn") + (memory.fill (f32.const 10) (f32.const 20) (f32.const 30)))) + "type mismatch") + +(assert_invalid + (module + (memory i64 1 1) + (func (export "testfn") + (memory.fill (f32.const 10) (f32.const 20) (i64.const 30)))) + "type mismatch") + +(assert_invalid + (module + (memory i64 1 1) + (func (export "testfn") + (memory.fill (f32.const 10) (f32.const 20) (f64.const 30)))) + "type mismatch") + +(assert_invalid + (module + (memory i64 1 1) + (func (export "testfn") + (memory.fill (f32.const 10) (i64.const 20) (i32.const 30)))) + "type mismatch") + +(assert_invalid + (module + (memory i64 1 1) + (func (export "testfn") + (memory.fill (f32.const 10) (i64.const 20) (f32.const 30)))) + "type mismatch") + +(assert_invalid + (module + (memory i64 1 1) + (func (export "testfn") + (memory.fill (f32.const 10) (i64.const 20) (i64.const 30)))) + "type mismatch") + +(assert_invalid + (module + (memory i64 1 1) + (func (export "testfn") + (memory.fill (f32.const 10) (i64.const 20) (f64.const 30)))) + "type mismatch") + +(assert_invalid + (module + (memory i64 1 1) + (func (export "testfn") + (memory.fill (f32.const 10) (f64.const 20) (i32.const 30)))) + "type mismatch") + +(assert_invalid + (module + (memory i64 1 1) + (func (export "testfn") + (memory.fill (f32.const 10) (f64.const 20) (f32.const 30)))) + "type mismatch") + +(assert_invalid + (module + (memory i64 1 1) + (func (export "testfn") + (memory.fill (f32.const 10) (f64.const 20) (i64.const 30)))) + "type mismatch") + +(assert_invalid + (module + (memory i64 1 1) + (func (export "testfn") + (memory.fill (f32.const 10) (f64.const 20) (f64.const 30)))) + "type mismatch") + +(assert_invalid + (module + (memory i64 1 1) + (func (export "testfn") + (memory.fill (i64.const 10) (i32.const 20) (i32.const 30)))) + "type mismatch") + +(assert_invalid + (module + (memory i64 1 1) + (func (export "testfn") + (memory.fill (i64.const 10) (i32.const 20) (f32.const 30)))) + "type mismatch") + +(assert_invalid + (module + (memory i64 1 1) + (func (export "testfn") + (memory.fill (i64.const 10) (i32.const 20) (f64.const 30)))) + "type mismatch") + +(assert_invalid + (module + (memory i64 1 1) + (func (export "testfn") + (memory.fill (i64.const 10) (f32.const 20) (i32.const 30)))) + "type mismatch") + +(assert_invalid + (module + (memory i64 1 1) + (func (export "testfn") + (memory.fill (i64.const 10) (f32.const 20) (f32.const 30)))) + "type mismatch") + +(assert_invalid + (module + (memory i64 1 1) + (func (export "testfn") + (memory.fill (i64.const 10) (f32.const 20) (i64.const 30)))) + "type mismatch") + +(assert_invalid + (module + (memory i64 1 1) + (func (export "testfn") + (memory.fill (i64.const 10) (f32.const 20) (f64.const 30)))) + "type mismatch") + +(assert_invalid + (module + (memory i64 1 1) + (func (export "testfn") + (memory.fill (i64.const 10) (i64.const 20) (i32.const 30)))) + "type mismatch") + +(assert_invalid + (module + (memory i64 1 1) + (func (export "testfn") + (memory.fill (i64.const 10) (i64.const 20) (f32.const 30)))) + "type mismatch") + +(assert_invalid + (module + (memory i64 1 1) + (func (export "testfn") + (memory.fill (i64.const 10) (i64.const 20) (i64.const 30)))) + "type mismatch") + +(assert_invalid + (module + (memory i64 1 1) + (func (export "testfn") + (memory.fill (i64.const 10) (i64.const 20) (f64.const 30)))) + "type mismatch") + +(assert_invalid + (module + (memory i64 1 1) + (func (export "testfn") + (memory.fill (i64.const 10) (f64.const 20) (i32.const 30)))) + "type mismatch") + +(assert_invalid + (module + (memory i64 1 1) + (func (export "testfn") + (memory.fill (i64.const 10) (f64.const 20) (f32.const 30)))) + "type mismatch") + +(assert_invalid + (module + (memory i64 1 1) + (func (export "testfn") + (memory.fill (i64.const 10) (f64.const 20) (i64.const 30)))) + "type mismatch") + +(assert_invalid + (module + (memory i64 1 1) + (func (export "testfn") + (memory.fill (i64.const 10) (f64.const 20) (f64.const 30)))) + "type mismatch") + +(assert_invalid + (module + (memory i64 1 1) + (func (export "testfn") + (memory.fill (f64.const 10) (i32.const 20) (i32.const 30)))) + "type mismatch") + +(assert_invalid + (module + (memory i64 1 1) + (func (export "testfn") + (memory.fill (f64.const 10) (i32.const 20) (f32.const 30)))) + "type mismatch") + +(assert_invalid + (module + (memory i64 1 1) + (func (export "testfn") + (memory.fill (f64.const 10) (i32.const 20) (i64.const 30)))) + "type mismatch") + +(assert_invalid + (module + (memory i64 1 1) + (func (export "testfn") + (memory.fill (f64.const 10) (i32.const 20) (f64.const 30)))) + "type mismatch") + +(assert_invalid + (module + (memory i64 1 1) + (func (export "testfn") + (memory.fill (f64.const 10) (f32.const 20) (i32.const 30)))) + "type mismatch") + +(assert_invalid + (module + (memory i64 1 1) + (func (export "testfn") + (memory.fill (f64.const 10) (f32.const 20) (f32.const 30)))) + "type mismatch") + +(assert_invalid + (module + (memory i64 1 1) + (func (export "testfn") + (memory.fill (f64.const 10) (f32.const 20) (i64.const 30)))) + "type mismatch") + +(assert_invalid + (module + (memory i64 1 1) + (func (export "testfn") + (memory.fill (f64.const 10) (f32.const 20) (f64.const 30)))) + "type mismatch") + +(assert_invalid + (module + (memory i64 1 1) + (func (export "testfn") + (memory.fill (f64.const 10) (i64.const 20) (i32.const 30)))) + "type mismatch") + +(assert_invalid + (module + (memory i64 1 1) + (func (export "testfn") + (memory.fill (f64.const 10) (i64.const 20) (f32.const 30)))) + "type mismatch") + +(assert_invalid + (module + (memory i64 1 1) + (func (export "testfn") + (memory.fill (f64.const 10) (i64.const 20) (i64.const 30)))) + "type mismatch") + +(assert_invalid + (module + (memory i64 1 1) + (func (export "testfn") + (memory.fill (f64.const 10) (i64.const 20) (f64.const 30)))) + "type mismatch") + +(assert_invalid + (module + (memory i64 1 1) + (func (export "testfn") + (memory.fill (f64.const 10) (f64.const 20) (i32.const 30)))) + "type mismatch") + +(assert_invalid + (module + (memory i64 1 1) + (func (export "testfn") + (memory.fill (f64.const 10) (f64.const 20) (f32.const 30)))) + "type mismatch") + +(assert_invalid + (module + (memory i64 1 1) + (func (export "testfn") + (memory.fill (f64.const 10) (f64.const 20) (i64.const 30)))) + "type mismatch") + +(assert_invalid + (module + (memory i64 1 1) + (func (export "testfn") + (memory.fill (f64.const 10) (f64.const 20) (f64.const 30)))) + "type mismatch") + +(module + (memory i64 1 1 ) + + (func (export "checkRange") (param $from i64) (param $to i64) (param $expected i32) (result i64) + (loop $cont + (if (i64.eq (local.get $from) (local.get $to)) + (then + (return (i64.const -1)))) + (if (i32.eq (i32.load8_u (local.get $from)) (local.get $expected)) + (then + (local.set $from (i64.add (local.get $from) (i64.const 1))) + (br $cont)))) + (return (local.get $from))) + + (func (export "run") (param $offs i64) (param $val i32) (param $len i64) + (memory.fill (local.get $offs) (local.get $val) (local.get $len)))) + +(assert_trap (invoke "run" (i64.const 65280) (i32.const 37) (i64.const 512)) + "out of bounds memory access") + +(assert_return (invoke "checkRange" (i64.const 0) (i64.const 1) (i32.const 0)) + (i64.const -1)) +(module + (memory i64 1 1 ) + + (func (export "checkRange") (param $from i64) (param $to i64) (param $expected i32) (result i64) + (loop $cont + (if (i64.eq (local.get $from) (local.get $to)) + (then + (return (i64.const -1)))) + (if (i32.eq (i32.load8_u (local.get $from)) (local.get $expected)) + (then + (local.set $from (i64.add (local.get $from) (i64.const 1))) + (br $cont)))) + (return (local.get $from))) + + (func (export "run") (param $offs i64) (param $val i32) (param $len i64) + (memory.fill (local.get $offs) (local.get $val) (local.get $len)))) + +(assert_trap (invoke "run" (i64.const 65279) (i32.const 37) (i64.const 514)) + "out of bounds memory access") + +(assert_return (invoke "checkRange" (i64.const 0) (i64.const 1) (i32.const 0)) + (i64.const -1)) +(module + (memory i64 1 1 ) + + (func (export "checkRange") (param $from i64) (param $to i64) (param $expected i32) (result i64) + (loop $cont + (if (i64.eq (local.get $from) (local.get $to)) + (then + (return (i64.const -1)))) + (if (i32.eq (i32.load8_u (local.get $from)) (local.get $expected)) + (then + (local.set $from (i64.add (local.get $from) (i64.const 1))) + (br $cont)))) + (return (local.get $from))) + + (func (export "run") (param $offs i64) (param $val i32) (param $len i64) + (memory.fill (local.get $offs) (local.get $val) (local.get $len)))) + +(assert_trap (invoke "run" (i64.const 65279) (i32.const 37) (i64.const 4294967295)) + "out of bounds memory access") + +(assert_return (invoke "checkRange" (i64.const 0) (i64.const 1) (i32.const 0)) + (i64.const -1)) diff --git a/test/core/memory_grow64.wast b/test/core/memory_grow64.wast new file mode 100644 index 0000000000..90d8de6075 --- /dev/null +++ b/test/core/memory_grow64.wast @@ -0,0 +1,95 @@ +(module + (memory i64 0) + + (func (export "load_at_zero") (result i32) (i32.load (i64.const 0))) + (func (export "store_at_zero") (i32.store (i64.const 0) (i32.const 2))) + + (func (export "load_at_page_size") (result i32) (i32.load (i64.const 0x10000))) + (func (export "store_at_page_size") (i32.store (i64.const 0x10000) (i32.const 3))) + + (func (export "grow") (param $sz i64) (result i64) (memory.grow (local.get $sz))) + (func (export "size") (result i64) (memory.size)) +) + +(assert_return (invoke "size") (i64.const 0)) +(assert_trap (invoke "store_at_zero") "out of bounds memory access") +(assert_trap (invoke "load_at_zero") "out of bounds memory access") +(assert_trap (invoke "store_at_page_size") "out of bounds memory access") +(assert_trap (invoke "load_at_page_size") "out of bounds memory access") +(assert_return (invoke "grow" (i64.const 1)) (i64.const 0)) +(assert_return (invoke "size") (i64.const 1)) +(assert_return (invoke "load_at_zero") (i32.const 0)) +(assert_return (invoke "store_at_zero")) +(assert_return (invoke "load_at_zero") (i32.const 2)) +(assert_trap (invoke "store_at_page_size") "out of bounds memory access") +(assert_trap (invoke "load_at_page_size") "out of bounds memory access") +(assert_return (invoke "grow" (i64.const 4)) (i64.const 1)) +(assert_return (invoke "size") (i64.const 5)) +(assert_return (invoke "load_at_zero") (i32.const 2)) +(assert_return (invoke "store_at_zero")) +(assert_return (invoke "load_at_zero") (i32.const 2)) +(assert_return (invoke "load_at_page_size") (i32.const 0)) +(assert_return (invoke "store_at_page_size")) +(assert_return (invoke "load_at_page_size") (i32.const 3)) + + +(module + (memory i64 0) + (func (export "grow") (param i64) (result i64) (memory.grow (local.get 0))) +) + +(assert_return (invoke "grow" (i64.const 0)) (i64.const 0)) +(assert_return (invoke "grow" (i64.const 1)) (i64.const 0)) +(assert_return (invoke "grow" (i64.const 0)) (i64.const 1)) +(assert_return (invoke "grow" (i64.const 2)) (i64.const 1)) +(assert_return (invoke "grow" (i64.const 800)) (i64.const 3)) +(assert_return (invoke "grow" (i64.const 1)) (i64.const 803)) + +(module + (memory i64 0 10) + (func (export "grow") (param i64) (result i64) (memory.grow (local.get 0))) +) + +(assert_return (invoke "grow" (i64.const 0)) (i64.const 0)) +(assert_return (invoke "grow" (i64.const 1)) (i64.const 0)) +(assert_return (invoke "grow" (i64.const 1)) (i64.const 1)) +(assert_return (invoke "grow" (i64.const 2)) (i64.const 2)) +(assert_return (invoke "grow" (i64.const 6)) (i64.const 4)) +(assert_return (invoke "grow" (i64.const 0)) (i64.const 10)) +(assert_return (invoke "grow" (i64.const 1)) (i64.const -1)) +(assert_return (invoke "grow" (i64.const 0x10000)) (i64.const -1)) + +;; Test that newly allocated memory (program start and memory.grow) is zeroed + +(module + (memory i64 1) + (func (export "grow") (param i64) (result i64) + (memory.grow (local.get 0)) + ) + (func (export "check-memory-zero") (param i64 i64) (result i32) + (local i32) + (local.set 2 (i32.const 1)) + (block + (loop + (local.set 2 (i32.load8_u (local.get 0))) + (br_if 1 (i32.ne (local.get 2) (i32.const 0))) + (br_if 1 (i64.ge_u (local.get 0) (local.get 1))) + (local.set 0 (i64.add (local.get 0) (i64.const 1))) + (br_if 0 (i64.le_u (local.get 0) (local.get 1))) + ) + ) + (local.get 2) + ) +) + +(assert_return (invoke "check-memory-zero" (i64.const 0) (i64.const 0xffff)) (i32.const 0)) +(assert_return (invoke "grow" (i64.const 1)) (i64.const 1)) +(assert_return (invoke "check-memory-zero" (i64.const 0x10000) (i64.const 0x1_ffff)) (i32.const 0)) +(assert_return (invoke "grow" (i64.const 1)) (i64.const 2)) +(assert_return (invoke "check-memory-zero" (i64.const 0x20000) (i64.const 0x2_ffff)) (i32.const 0)) +(assert_return (invoke "grow" (i64.const 1)) (i64.const 3)) +(assert_return (invoke "check-memory-zero" (i64.const 0x30000) (i64.const 0x3_ffff)) (i32.const 0)) +(assert_return (invoke "grow" (i64.const 1)) (i64.const 4)) +(assert_return (invoke "check-memory-zero" (i64.const 0x40000) (i64.const 0x4_ffff)) (i32.const 0)) +(assert_return (invoke "grow" (i64.const 1)) (i64.const 5)) +(assert_return (invoke "check-memory-zero" (i64.const 0x50000) (i64.const 0x5_ffff)) (i32.const 0)) diff --git a/test/core/memory_init.wast b/test/core/memory_init.wast index 672b1c5013..8a3ddbe333 100644 --- a/test/core/memory_init.wast +++ b/test/core/memory_init.wast @@ -965,3 +965,966 @@ (data "") (data "") (data "") (data "") (data "") (data "") (data "") (data "") (data "") (func (memory.init 64 (i32.const 0) (i32.const 0) (i32.const 0)))) + +(module + (memory (export "memory0") i64 1 1) + (data (i64.const 2) "\03\01\04\01") + (data "\02\07\01\08") + (data (i64.const 12) "\07\05\02\03\06") + (data "\05\09\02\07\06") + (func (export "test") + (nop)) + (func (export "load8_u") (param i64) (result i32) + (i32.load8_u (local.get 0)))) + +(invoke "test") + +(assert_return (invoke "load8_u" (i64.const 0)) (i32.const 0)) +(assert_return (invoke "load8_u" (i64.const 1)) (i32.const 0)) +(assert_return (invoke "load8_u" (i64.const 2)) (i32.const 3)) +(assert_return (invoke "load8_u" (i64.const 3)) (i32.const 1)) +(assert_return (invoke "load8_u" (i64.const 4)) (i32.const 4)) +(assert_return (invoke "load8_u" (i64.const 5)) (i32.const 1)) +(assert_return (invoke "load8_u" (i64.const 6)) (i32.const 0)) +(assert_return (invoke "load8_u" (i64.const 7)) (i32.const 0)) +(assert_return (invoke "load8_u" (i64.const 8)) (i32.const 0)) +(assert_return (invoke "load8_u" (i64.const 9)) (i32.const 0)) +(assert_return (invoke "load8_u" (i64.const 10)) (i32.const 0)) +(assert_return (invoke "load8_u" (i64.const 11)) (i32.const 0)) +(assert_return (invoke "load8_u" (i64.const 12)) (i32.const 7)) +(assert_return (invoke "load8_u" (i64.const 13)) (i32.const 5)) +(assert_return (invoke "load8_u" (i64.const 14)) (i32.const 2)) +(assert_return (invoke "load8_u" (i64.const 15)) (i32.const 3)) +(assert_return (invoke "load8_u" (i64.const 16)) (i32.const 6)) +(assert_return (invoke "load8_u" (i64.const 17)) (i32.const 0)) +(assert_return (invoke "load8_u" (i64.const 18)) (i32.const 0)) +(assert_return (invoke "load8_u" (i64.const 19)) (i32.const 0)) +(assert_return (invoke "load8_u" (i64.const 20)) (i32.const 0)) +(assert_return (invoke "load8_u" (i64.const 21)) (i32.const 0)) +(assert_return (invoke "load8_u" (i64.const 22)) (i32.const 0)) +(assert_return (invoke "load8_u" (i64.const 23)) (i32.const 0)) +(assert_return (invoke "load8_u" (i64.const 24)) (i32.const 0)) +(assert_return (invoke "load8_u" (i64.const 25)) (i32.const 0)) +(assert_return (invoke "load8_u" (i64.const 26)) (i32.const 0)) +(assert_return (invoke "load8_u" (i64.const 27)) (i32.const 0)) +(assert_return (invoke "load8_u" (i64.const 28)) (i32.const 0)) +(assert_return (invoke "load8_u" (i64.const 29)) (i32.const 0)) + +(module + (memory (export "memory0") i64 1 1) + (data (i64.const 2) "\03\01\04\01") + (data "\02\07\01\08") + (data (i64.const 12) "\07\05\02\03\06") + (data "\05\09\02\07\06") + (func (export "test") + (memory.init 1 (i64.const 7) (i32.const 0) (i32.const 4))) + (func (export "load8_u") (param i64) (result i32) + (i32.load8_u (local.get 0)))) + +(invoke "test") + +(assert_return (invoke "load8_u" (i64.const 0)) (i32.const 0)) +(assert_return (invoke "load8_u" (i64.const 1)) (i32.const 0)) +(assert_return (invoke "load8_u" (i64.const 2)) (i32.const 3)) +(assert_return (invoke "load8_u" (i64.const 3)) (i32.const 1)) +(assert_return (invoke "load8_u" (i64.const 4)) (i32.const 4)) +(assert_return (invoke "load8_u" (i64.const 5)) (i32.const 1)) +(assert_return (invoke "load8_u" (i64.const 6)) (i32.const 0)) +(assert_return (invoke "load8_u" (i64.const 7)) (i32.const 2)) +(assert_return (invoke "load8_u" (i64.const 8)) (i32.const 7)) +(assert_return (invoke "load8_u" (i64.const 9)) (i32.const 1)) +(assert_return (invoke "load8_u" (i64.const 10)) (i32.const 8)) +(assert_return (invoke "load8_u" (i64.const 11)) (i32.const 0)) +(assert_return (invoke "load8_u" (i64.const 12)) (i32.const 7)) +(assert_return (invoke "load8_u" (i64.const 13)) (i32.const 5)) +(assert_return (invoke "load8_u" (i64.const 14)) (i32.const 2)) +(assert_return (invoke "load8_u" (i64.const 15)) (i32.const 3)) +(assert_return (invoke "load8_u" (i64.const 16)) (i32.const 6)) +(assert_return (invoke "load8_u" (i64.const 17)) (i32.const 0)) +(assert_return (invoke "load8_u" (i64.const 18)) (i32.const 0)) +(assert_return (invoke "load8_u" (i64.const 19)) (i32.const 0)) +(assert_return (invoke "load8_u" (i64.const 20)) (i32.const 0)) +(assert_return (invoke "load8_u" (i64.const 21)) (i32.const 0)) +(assert_return (invoke "load8_u" (i64.const 22)) (i32.const 0)) +(assert_return (invoke "load8_u" (i64.const 23)) (i32.const 0)) +(assert_return (invoke "load8_u" (i64.const 24)) (i32.const 0)) +(assert_return (invoke "load8_u" (i64.const 25)) (i32.const 0)) +(assert_return (invoke "load8_u" (i64.const 26)) (i32.const 0)) +(assert_return (invoke "load8_u" (i64.const 27)) (i32.const 0)) +(assert_return (invoke "load8_u" (i64.const 28)) (i32.const 0)) +(assert_return (invoke "load8_u" (i64.const 29)) (i32.const 0)) + +(module + (memory (export "memory0") i64 1 1) + (data (i64.const 2) "\03\01\04\01") + (data "\02\07\01\08") + (data (i64.const 12) "\07\05\02\03\06") + (data "\05\09\02\07\06") + (func (export "test") + (memory.init 3 (i64.const 15) (i32.const 1) (i32.const 3))) + (func (export "load8_u") (param i64) (result i32) + (i32.load8_u (local.get 0)))) + +(invoke "test") + +(assert_return (invoke "load8_u" (i64.const 0)) (i32.const 0)) +(assert_return (invoke "load8_u" (i64.const 1)) (i32.const 0)) +(assert_return (invoke "load8_u" (i64.const 2)) (i32.const 3)) +(assert_return (invoke "load8_u" (i64.const 3)) (i32.const 1)) +(assert_return (invoke "load8_u" (i64.const 4)) (i32.const 4)) +(assert_return (invoke "load8_u" (i64.const 5)) (i32.const 1)) +(assert_return (invoke "load8_u" (i64.const 6)) (i32.const 0)) +(assert_return (invoke "load8_u" (i64.const 7)) (i32.const 0)) +(assert_return (invoke "load8_u" (i64.const 8)) (i32.const 0)) +(assert_return (invoke "load8_u" (i64.const 9)) (i32.const 0)) +(assert_return (invoke "load8_u" (i64.const 10)) (i32.const 0)) +(assert_return (invoke "load8_u" (i64.const 11)) (i32.const 0)) +(assert_return (invoke "load8_u" (i64.const 12)) (i32.const 7)) +(assert_return (invoke "load8_u" (i64.const 13)) (i32.const 5)) +(assert_return (invoke "load8_u" (i64.const 14)) (i32.const 2)) +(assert_return (invoke "load8_u" (i64.const 15)) (i32.const 9)) +(assert_return (invoke "load8_u" (i64.const 16)) (i32.const 2)) +(assert_return (invoke "load8_u" (i64.const 17)) (i32.const 7)) +(assert_return (invoke "load8_u" (i64.const 18)) (i32.const 0)) +(assert_return (invoke "load8_u" (i64.const 19)) (i32.const 0)) +(assert_return (invoke "load8_u" (i64.const 20)) (i32.const 0)) +(assert_return (invoke "load8_u" (i64.const 21)) (i32.const 0)) +(assert_return (invoke "load8_u" (i64.const 22)) (i32.const 0)) +(assert_return (invoke "load8_u" (i64.const 23)) (i32.const 0)) +(assert_return (invoke "load8_u" (i64.const 24)) (i32.const 0)) +(assert_return (invoke "load8_u" (i64.const 25)) (i32.const 0)) +(assert_return (invoke "load8_u" (i64.const 26)) (i32.const 0)) +(assert_return (invoke "load8_u" (i64.const 27)) (i32.const 0)) +(assert_return (invoke "load8_u" (i64.const 28)) (i32.const 0)) +(assert_return (invoke "load8_u" (i64.const 29)) (i32.const 0)) + +(module + (memory (export "memory0") i64 1 1) + (data (i64.const 2) "\03\01\04\01") + (data "\02\07\01\08") + (data (i64.const 12) "\07\05\02\03\06") + (data "\05\09\02\07\06") + (func (export "test") + (memory.init 1 (i64.const 7) (i32.const 0) (i32.const 4)) + (data.drop 1) + (memory.init 3 (i64.const 15) (i32.const 1) (i32.const 3)) + (data.drop 3) + (memory.copy (i64.const 20) (i64.const 15) (i64.const 5)) + (memory.copy (i64.const 21) (i64.const 29) (i64.const 1)) + (memory.copy (i64.const 24) (i64.const 10) (i64.const 1)) + (memory.copy (i64.const 13) (i64.const 11) (i64.const 4)) + (memory.copy (i64.const 19) (i64.const 20) (i64.const 5))) + (func (export "load8_u") (param i64) (result i32) + (i32.load8_u (local.get 0)))) + +(invoke "test") + +(assert_return (invoke "load8_u" (i64.const 0)) (i32.const 0)) +(assert_return (invoke "load8_u" (i64.const 1)) (i32.const 0)) +(assert_return (invoke "load8_u" (i64.const 2)) (i32.const 3)) +(assert_return (invoke "load8_u" (i64.const 3)) (i32.const 1)) +(assert_return (invoke "load8_u" (i64.const 4)) (i32.const 4)) +(assert_return (invoke "load8_u" (i64.const 5)) (i32.const 1)) +(assert_return (invoke "load8_u" (i64.const 6)) (i32.const 0)) +(assert_return (invoke "load8_u" (i64.const 7)) (i32.const 2)) +(assert_return (invoke "load8_u" (i64.const 8)) (i32.const 7)) +(assert_return (invoke "load8_u" (i64.const 9)) (i32.const 1)) +(assert_return (invoke "load8_u" (i64.const 10)) (i32.const 8)) +(assert_return (invoke "load8_u" (i64.const 11)) (i32.const 0)) +(assert_return (invoke "load8_u" (i64.const 12)) (i32.const 7)) +(assert_return (invoke "load8_u" (i64.const 13)) (i32.const 0)) +(assert_return (invoke "load8_u" (i64.const 14)) (i32.const 7)) +(assert_return (invoke "load8_u" (i64.const 15)) (i32.const 5)) +(assert_return (invoke "load8_u" (i64.const 16)) (i32.const 2)) +(assert_return (invoke "load8_u" (i64.const 17)) (i32.const 7)) +(assert_return (invoke "load8_u" (i64.const 18)) (i32.const 0)) +(assert_return (invoke "load8_u" (i64.const 19)) (i32.const 9)) +(assert_return (invoke "load8_u" (i64.const 20)) (i32.const 0)) +(assert_return (invoke "load8_u" (i64.const 21)) (i32.const 7)) +(assert_return (invoke "load8_u" (i64.const 22)) (i32.const 0)) +(assert_return (invoke "load8_u" (i64.const 23)) (i32.const 8)) +(assert_return (invoke "load8_u" (i64.const 24)) (i32.const 8)) +(assert_return (invoke "load8_u" (i64.const 25)) (i32.const 0)) +(assert_return (invoke "load8_u" (i64.const 26)) (i32.const 0)) +(assert_return (invoke "load8_u" (i64.const 27)) (i32.const 0)) +(assert_return (invoke "load8_u" (i64.const 28)) (i32.const 0)) +(assert_return (invoke "load8_u" (i64.const 29)) (i32.const 0)) +(assert_invalid + (module + (func (export "test") + (data.drop 0))) + "unknown data segment") + +(assert_invalid + (module + (memory i64 1) + (data "\37") + (func (export "test") + (data.drop 4))) + "unknown data segment") + +(module + (memory i64 1) + (data "\37") + (func (export "test") + (data.drop 0) + (data.drop 0))) +(invoke "test") + +(module + (memory i64 1) + (data "\37") + (func (export "test") + (data.drop 0) + (memory.init 0 (i64.const 1234) (i32.const 1) (i32.const 1)))) +(assert_trap (invoke "test") "out of bounds memory access") + +(module + (memory i64 1) + (data (i64.const 0) "\37") + (func (export "test") + (memory.init 0 (i64.const 1234) (i32.const 1) (i32.const 1)))) +(assert_trap (invoke "test") "out of bounds memory access") + +(assert_invalid + (module + (func (export "test") + (memory.init 1 (i64.const 1234) (i32.const 1) (i32.const 1)))) + "unknown memory 0") + +(assert_invalid + (module + (memory i64 1) + (data "\37") + (func (export "test") + (memory.init 1 (i64.const 1234) (i32.const 1) (i32.const 1)))) + "unknown data segment 1") + +(module + (memory i64 1) + (data "\37") + (func (export "test") + (memory.init 0 (i64.const 1) (i32.const 0) (i32.const 1)) + (memory.init 0 (i64.const 1) (i32.const 0) (i32.const 1)))) +(invoke "test") + +(module + (memory i64 1) + (data "\37") + (func (export "test") + (memory.init 0 (i64.const 1234) (i32.const 0) (i32.const 5)))) +(assert_trap (invoke "test") "out of bounds memory access") + +(module + (memory i64 1) + (data "\37") + (func (export "test") + (memory.init 0 (i64.const 1234) (i32.const 2) (i32.const 3)))) +(assert_trap (invoke "test") "out of bounds memory access") + +(module + (memory i64 1) + (data "\37") + (func (export "test") + (memory.init 0 (i64.const 0xFFFE) (i32.const 1) (i32.const 3)))) +(assert_trap (invoke "test") "out of bounds memory access") + +(module + (memory i64 1) + (data "\37") + (func (export "test") + (memory.init 0 (i64.const 1234) (i32.const 4) (i32.const 0)))) +(assert_trap (invoke "test") "out of bounds memory access") + +(module + (memory i64 1) + (data "\37") + (func (export "test") + (memory.init 0 (i64.const 1234) (i32.const 1) (i32.const 0)))) +(invoke "test") + +(module + (memory i64 1) + (data "\37") + (func (export "test") + (memory.init 0 (i64.const 0x10001) (i32.const 0) (i32.const 0)))) +(assert_trap (invoke "test") "out of bounds memory access") + +(module + (memory i64 1) + (data "\37") + (func (export "test") + (memory.init 0 (i64.const 0x10000) (i32.const 0) (i32.const 0)))) +(invoke "test") + +(module + (memory i64 1) + (data "\37") + (func (export "test") + (memory.init 0 (i64.const 0x10000) (i32.const 1) (i32.const 0)))) +(invoke "test") + +(module + (memory i64 1) + (data "\37") + (func (export "test") + (memory.init 0 (i64.const 0x10001) (i32.const 4) (i32.const 0)))) +(assert_trap (invoke "test") "out of bounds memory access") + +(assert_invalid + (module + (memory i64 1) + (data "\37") + (func (export "test") + (memory.init 0 (i32.const 1) (i32.const 1) (i32.const 1)))) + "type mismatch") + +(assert_invalid + (module + (memory i64 1) + (data "\37") + (func (export "test") + (memory.init 0 (i32.const 1) (i32.const 1) (f32.const 1)))) + "type mismatch") + +(assert_invalid + (module + (memory i64 1) + (data "\37") + (func (export "test") + (memory.init 0 (i32.const 1) (i32.const 1) (i64.const 1)))) + "type mismatch") + +(assert_invalid + (module + (memory i64 1) + (data "\37") + (func (export "test") + (memory.init 0 (i32.const 1) (i32.const 1) (f64.const 1)))) + "type mismatch") + +(assert_invalid + (module + (memory i64 1) + (data "\37") + (func (export "test") + (memory.init 0 (i32.const 1) (f32.const 1) (i32.const 1)))) + "type mismatch") + +(assert_invalid + (module + (memory i64 1) + (data "\37") + (func (export "test") + (memory.init 0 (i32.const 1) (f32.const 1) (f32.const 1)))) + "type mismatch") + +(assert_invalid + (module + (memory i64 1) + (data "\37") + (func (export "test") + (memory.init 0 (i32.const 1) (f32.const 1) (i64.const 1)))) + "type mismatch") + +(assert_invalid + (module + (memory i64 1) + (data "\37") + (func (export "test") + (memory.init 0 (i32.const 1) (f32.const 1) (f64.const 1)))) + "type mismatch") + +(assert_invalid + (module + (memory i64 1) + (data "\37") + (func (export "test") + (memory.init 0 (i32.const 1) (i64.const 1) (i32.const 1)))) + "type mismatch") + +(assert_invalid + (module + (memory i64 1) + (data "\37") + (func (export "test") + (memory.init 0 (i32.const 1) (i64.const 1) (f32.const 1)))) + "type mismatch") + +(assert_invalid + (module + (memory i64 1) + (data "\37") + (func (export "test") + (memory.init 0 (i32.const 1) (i64.const 1) (i64.const 1)))) + "type mismatch") + +(assert_invalid + (module + (memory i64 1) + (data "\37") + (func (export "test") + (memory.init 0 (i32.const 1) (i64.const 1) (f64.const 1)))) + "type mismatch") + +(assert_invalid + (module + (memory i64 1) + (data "\37") + (func (export "test") + (memory.init 0 (i32.const 1) (f64.const 1) (i32.const 1)))) + "type mismatch") + +(assert_invalid + (module + (memory i64 1) + (data "\37") + (func (export "test") + (memory.init 0 (i32.const 1) (f64.const 1) (f32.const 1)))) + "type mismatch") + +(assert_invalid + (module + (memory i64 1) + (data "\37") + (func (export "test") + (memory.init 0 (i32.const 1) (f64.const 1) (i64.const 1)))) + "type mismatch") + +(assert_invalid + (module + (memory i64 1) + (data "\37") + (func (export "test") + (memory.init 0 (i32.const 1) (f64.const 1) (f64.const 1)))) + "type mismatch") + +(assert_invalid + (module + (memory i64 1) + (data "\37") + (func (export "test") + (memory.init 0 (f32.const 1) (i32.const 1) (i32.const 1)))) + "type mismatch") + +(assert_invalid + (module + (memory i64 1) + (data "\37") + (func (export "test") + (memory.init 0 (f32.const 1) (i32.const 1) (f32.const 1)))) + "type mismatch") + +(assert_invalid + (module + (memory i64 1) + (data "\37") + (func (export "test") + (memory.init 0 (f32.const 1) (i32.const 1) (i64.const 1)))) + "type mismatch") + +(assert_invalid + (module + (memory i64 1) + (data "\37") + (func (export "test") + (memory.init 0 (f32.const 1) (i32.const 1) (f64.const 1)))) + "type mismatch") + +(assert_invalid + (module + (memory i64 1) + (data "\37") + (func (export "test") + (memory.init 0 (f32.const 1) (f32.const 1) (i32.const 1)))) + "type mismatch") + +(assert_invalid + (module + (memory i64 1) + (data "\37") + (func (export "test") + (memory.init 0 (f32.const 1) (f32.const 1) (f32.const 1)))) + "type mismatch") + +(assert_invalid + (module + (memory i64 1) + (data "\37") + (func (export "test") + (memory.init 0 (f32.const 1) (f32.const 1) (i64.const 1)))) + "type mismatch") + +(assert_invalid + (module + (memory i64 1) + (data "\37") + (func (export "test") + (memory.init 0 (f32.const 1) (f32.const 1) (f64.const 1)))) + "type mismatch") + +(assert_invalid + (module + (memory i64 1) + (data "\37") + (func (export "test") + (memory.init 0 (f32.const 1) (i64.const 1) (i32.const 1)))) + "type mismatch") + +(assert_invalid + (module + (memory i64 1) + (data "\37") + (func (export "test") + (memory.init 0 (f32.const 1) (i64.const 1) (f32.const 1)))) + "type mismatch") + +(assert_invalid + (module + (memory i64 1) + (data "\37") + (func (export "test") + (memory.init 0 (f32.const 1) (i64.const 1) (i64.const 1)))) + "type mismatch") + +(assert_invalid + (module + (memory i64 1) + (data "\37") + (func (export "test") + (memory.init 0 (f32.const 1) (i64.const 1) (f64.const 1)))) + "type mismatch") + +(assert_invalid + (module + (memory i64 1) + (data "\37") + (func (export "test") + (memory.init 0 (f32.const 1) (f64.const 1) (i32.const 1)))) + "type mismatch") + +(assert_invalid + (module + (memory i64 1) + (data "\37") + (func (export "test") + (memory.init 0 (f32.const 1) (f64.const 1) (f32.const 1)))) + "type mismatch") + +(assert_invalid + (module + (memory i64 1) + (data "\37") + (func (export "test") + (memory.init 0 (f32.const 1) (f64.const 1) (i64.const 1)))) + "type mismatch") + +(assert_invalid + (module + (memory i64 1) + (data "\37") + (func (export "test") + (memory.init 0 (f32.const 1) (f64.const 1) (f64.const 1)))) + "type mismatch") + +(assert_invalid + (module + (memory i64 1) + (data "\37") + (func (export "test") + (memory.init 0 (i64.const 1) (i32.const 1) (f32.const 1)))) + "type mismatch") + +(assert_invalid + (module + (memory i64 1) + (data "\37") + (func (export "test") + (memory.init 0 (i64.const 1) (i32.const 1) (i64.const 1)))) + "type mismatch") + +(assert_invalid + (module + (memory i64 1) + (data "\37") + (func (export "test") + (memory.init 0 (i64.const 1) (i32.const 1) (f64.const 1)))) + "type mismatch") + +(assert_invalid + (module + (memory i64 1) + (data "\37") + (func (export "test") + (memory.init 0 (i64.const 1) (f32.const 1) (i32.const 1)))) + "type mismatch") + +(assert_invalid + (module + (memory i64 1) + (data "\37") + (func (export "test") + (memory.init 0 (i64.const 1) (f32.const 1) (f32.const 1)))) + "type mismatch") + +(assert_invalid + (module + (memory i64 1) + (data "\37") + (func (export "test") + (memory.init 0 (i64.const 1) (f32.const 1) (i64.const 1)))) + "type mismatch") + +(assert_invalid + (module + (memory i64 1) + (data "\37") + (func (export "test") + (memory.init 0 (i64.const 1) (f32.const 1) (f64.const 1)))) + "type mismatch") + +(assert_invalid + (module + (memory i64 1) + (data "\37") + (func (export "test") + (memory.init 0 (i64.const 1) (i64.const 1) (i32.const 1)))) + "type mismatch") + +(assert_invalid + (module + (memory i64 1) + (data "\37") + (func (export "test") + (memory.init 0 (i64.const 1) (i64.const 1) (f32.const 1)))) + "type mismatch") + +(assert_invalid + (module + (memory i64 1) + (data "\37") + (func (export "test") + (memory.init 0 (i64.const 1) (i64.const 1) (i64.const 1)))) + "type mismatch") + +(assert_invalid + (module + (memory i64 1) + (data "\37") + (func (export "test") + (memory.init 0 (i64.const 1) (i64.const 1) (f64.const 1)))) + "type mismatch") + +(assert_invalid + (module + (memory i64 1) + (data "\37") + (func (export "test") + (memory.init 0 (i64.const 1) (f64.const 1) (i32.const 1)))) + "type mismatch") + +(assert_invalid + (module + (memory i64 1) + (data "\37") + (func (export "test") + (memory.init 0 (i64.const 1) (f64.const 1) (f32.const 1)))) + "type mismatch") + +(assert_invalid + (module + (memory i64 1) + (data "\37") + (func (export "test") + (memory.init 0 (i64.const 1) (f64.const 1) (i64.const 1)))) + "type mismatch") + +(assert_invalid + (module + (memory i64 1) + (data "\37") + (func (export "test") + (memory.init 0 (i64.const 1) (f64.const 1) (f64.const 1)))) + "type mismatch") + +(assert_invalid + (module + (memory i64 1) + (data "\37") + (func (export "test") + (memory.init 0 (f64.const 1) (i32.const 1) (i32.const 1)))) + "type mismatch") + +(assert_invalid + (module + (memory i64 1) + (data "\37") + (func (export "test") + (memory.init 0 (f64.const 1) (i32.const 1) (f32.const 1)))) + "type mismatch") + +(assert_invalid + (module + (memory i64 1) + (data "\37") + (func (export "test") + (memory.init 0 (f64.const 1) (i32.const 1) (i64.const 1)))) + "type mismatch") + +(assert_invalid + (module + (memory i64 1) + (data "\37") + (func (export "test") + (memory.init 0 (f64.const 1) (i32.const 1) (f64.const 1)))) + "type mismatch") + +(assert_invalid + (module + (memory i64 1) + (data "\37") + (func (export "test") + (memory.init 0 (f64.const 1) (f32.const 1) (i32.const 1)))) + "type mismatch") + +(assert_invalid + (module + (memory i64 1) + (data "\37") + (func (export "test") + (memory.init 0 (f64.const 1) (f32.const 1) (f32.const 1)))) + "type mismatch") + +(assert_invalid + (module + (memory i64 1) + (data "\37") + (func (export "test") + (memory.init 0 (f64.const 1) (f32.const 1) (i64.const 1)))) + "type mismatch") + +(assert_invalid + (module + (memory i64 1) + (data "\37") + (func (export "test") + (memory.init 0 (f64.const 1) (f32.const 1) (f64.const 1)))) + "type mismatch") + +(assert_invalid + (module + (memory i64 1) + (data "\37") + (func (export "test") + (memory.init 0 (f64.const 1) (i64.const 1) (i32.const 1)))) + "type mismatch") + +(assert_invalid + (module + (memory i64 1) + (data "\37") + (func (export "test") + (memory.init 0 (f64.const 1) (i64.const 1) (f32.const 1)))) + "type mismatch") + +(assert_invalid + (module + (memory i64 1) + (data "\37") + (func (export "test") + (memory.init 0 (f64.const 1) (i64.const 1) (i64.const 1)))) + "type mismatch") + +(assert_invalid + (module + (memory i64 1) + (data "\37") + (func (export "test") + (memory.init 0 (f64.const 1) (i64.const 1) (f64.const 1)))) + "type mismatch") + +(assert_invalid + (module + (memory i64 1) + (data "\37") + (func (export "test") + (memory.init 0 (f64.const 1) (f64.const 1) (i32.const 1)))) + "type mismatch") + +(assert_invalid + (module + (memory i64 1) + (data "\37") + (func (export "test") + (memory.init 0 (f64.const 1) (f64.const 1) (f32.const 1)))) + "type mismatch") + +(assert_invalid + (module + (memory i64 1) + (data "\37") + (func (export "test") + (memory.init 0 (f64.const 1) (f64.const 1) (i64.const 1)))) + "type mismatch") + +(assert_invalid + (module + (memory i64 1) + (data "\37") + (func (export "test") + (memory.init 0 (f64.const 1) (f64.const 1) (f64.const 1)))) + "type mismatch") + +(module + (memory i64 1 1 ) + (data "\42\42\42\42\42\42\42\42\42\42\42\42\42\42\42\42") + + (func (export "checkRange") (param $from i64) (param $to i64) (param $expected i32) (result i64) + (loop $cont + (if (i64.eq (local.get $from) (local.get $to)) + (then + (return (i64.const -1)))) + (if (i32.eq (i32.load8_u (local.get $from)) (local.get $expected)) + (then + (local.set $from (i64.add (local.get $from) (i64.const 1))) + (br $cont)))) + (return (local.get $from))) + + (func (export "run") (param $offs i64) (param $len i32) + (memory.init 0 (local.get $offs) (i32.const 0) (local.get $len)))) + +(assert_trap (invoke "run" (i64.const 65528) (i32.const 16)) + "out of bounds memory access") + +(assert_return (invoke "checkRange" (i64.const 0) (i64.const 1) (i32.const 0)) + (i64.const -1)) +(module + (memory i64 1 1 ) + (data "\42\42\42\42\42\42\42\42\42\42\42\42\42\42\42\42") + + (func (export "checkRange") (param $from i64) (param $to i64) (param $expected i32) (result i64) + (loop $cont + (if (i64.eq (local.get $from) (local.get $to)) + (then + (return (i64.const -1)))) + (if (i32.eq (i32.load8_u (local.get $from)) (local.get $expected)) + (then + (local.set $from (i64.add (local.get $from) (i64.const 1))) + (br $cont)))) + (return (local.get $from))) + + (func (export "run") (param $offs i64) (param $len i32) + (memory.init 0 (local.get $offs) (i32.const 0) (local.get $len)))) + +(assert_trap (invoke "run" (i64.const 65527) (i32.const 16)) + "out of bounds memory access") + +(assert_return (invoke "checkRange" (i64.const 0) (i64.const 1) (i32.const 0)) + (i64.const -1)) +(module + (memory i64 1 1 ) + (data "\42\42\42\42\42\42\42\42\42\42\42\42\42\42\42\42") + + (func (export "checkRange") (param $from i64) (param $to i64) (param $expected i32) (result i64) + (loop $cont + (if (i64.eq (local.get $from) (local.get $to)) + (then + (return (i64.const -1)))) + (if (i32.eq (i32.load8_u (local.get $from)) (local.get $expected)) + (then + (local.set $from (i64.add (local.get $from) (i64.const 1))) + (br $cont)))) + (return (local.get $from))) + + (func (export "run") (param $offs i64) (param $len i32) + (memory.init 0 (local.get $offs) (i32.const 0) (local.get $len)))) + +(assert_trap (invoke "run" (i64.const 65472) (i32.const 30)) + "out of bounds memory access") + +(assert_return (invoke "checkRange" (i64.const 0) (i64.const 1) (i32.const 0)) + (i64.const -1)) +(module + (memory i64 1 1 ) + (data "\42\42\42\42\42\42\42\42\42\42\42\42\42\42\42\42") + + (func (export "checkRange") (param $from i64) (param $to i64) (param $expected i32) (result i64) + (loop $cont + (if (i64.eq (local.get $from) (local.get $to)) + (then + (return (i64.const -1)))) + (if (i32.eq (i32.load8_u (local.get $from)) (local.get $expected)) + (then + (local.set $from (i64.add (local.get $from) (i64.const 1))) + (br $cont)))) + (return (local.get $from))) + + (func (export "run") (param $offs i64) (param $len i32) + (memory.init 0 (local.get $offs) (i32.const 0) (local.get $len)))) + +(assert_trap (invoke "run" (i64.const 65473) (i32.const 31)) + "out of bounds memory access") + +(assert_return (invoke "checkRange" (i64.const 0) (i64.const 1) (i32.const 0)) + (i64.const -1)) +(module + (memory i64 1 ) + (data "\42\42\42\42\42\42\42\42\42\42\42\42\42\42\42\42") + + (func (export "checkRange") (param $from i64) (param $to i64) (param $expected i32) (result i64) + (loop $cont + (if (i64.eq (local.get $from) (local.get $to)) + (then + (return (i64.const -1)))) + (if (i32.eq (i32.load8_u (local.get $from)) (local.get $expected)) + (then + (local.set $from (i64.add (local.get $from) (i64.const 1))) + (br $cont)))) + (return (local.get $from))) + + (func (export "run") (param $offs i64) (param $len i32) + (memory.init 0 (local.get $offs) (i32.const 0) (local.get $len)))) + +(assert_trap (invoke "run" (i64.const 65528) (i32.const 4294967040)) + "out of bounds memory access") + +(assert_return (invoke "checkRange" (i64.const 0) (i64.const 1) (i32.const 0)) + (i64.const -1)) +(module + (memory i64 1 ) + (data "\42\42\42\42\42\42\42\42\42\42\42\42\42\42\42\42") + + (func (export "checkRange") (param $from i64) (param $to i64) (param $expected i32) (result i64) + (loop $cont + (if (i64.eq (local.get $from) (local.get $to)) + (then + (return (i64.const -1)))) + (if (i32.eq (i32.load8_u (local.get $from)) (local.get $expected)) + (then + (local.set $from (i64.add (local.get $from) (i64.const 1))) + (br $cont)))) + (return (local.get $from))) + + (func (export "run") (param $offs i64) (param $len i32) + (memory.init 0 (local.get $offs) (i32.const 0) (local.get $len)))) + +(assert_trap (invoke "run" (i64.const 0) (i32.const 4294967292)) + "out of bounds memory access") + +(assert_return (invoke "checkRange" (i64.const 0) (i64.const 1) (i32.const 0)) + (i64.const -1)) + +(module + (memory i64 1) + ;; 65 data segments. 64 is the smallest positive number that is encoded + ;; differently as a signed LEB. + (data "") (data "") (data "") (data "") (data "") (data "") (data "") (data "") + (data "") (data "") (data "") (data "") (data "") (data "") (data "") (data "") + (data "") (data "") (data "") (data "") (data "") (data "") (data "") (data "") + (data "") (data "") (data "") (data "") (data "") (data "") (data "") (data "") + (data "") (data "") (data "") (data "") (data "") (data "") (data "") (data "") + (data "") (data "") (data "") (data "") (data "") (data "") (data "") (data "") + (data "") (data "") (data "") (data "") (data "") (data "") (data "") (data "") + (data "") (data "") (data "") (data "") (data "") (data "") (data "") (data "") + (data "") + (func (memory.init 64 (i64.const 0) (i32.const 0) (i32.const 0)))) diff --git a/test/core/memory_redundancy64.wast b/test/core/memory_redundancy64.wast new file mode 100644 index 0000000000..4aa1ebac1c --- /dev/null +++ b/test/core/memory_redundancy64.wast @@ -0,0 +1,65 @@ +;; Test that optimizers don't do redundant-load, store-to-load, or dead-store +;; optimizations when there are interfering stores, even of different types +;; and to non-identical addresses. + +(module + (memory i64 1 1) + + (func (export "zero_everything") + (i32.store (i64.const 0) (i32.const 0)) + (i32.store (i64.const 4) (i32.const 0)) + (i32.store (i64.const 8) (i32.const 0)) + (i32.store (i64.const 12) (i32.const 0)) + ) + + (func (export "test_store_to_load") (result i32) + (i32.store (i64.const 8) (i32.const 0)) + (f32.store (i64.const 5) (f32.const -0.0)) + (i32.load (i64.const 8)) + ) + + (func (export "test_redundant_load") (result i32) + (local $t i32) + (local $s i32) + (local.set $t (i32.load (i64.const 8))) + (i32.store (i64.const 5) (i32.const 0x80000000)) + (local.set $s (i32.load (i64.const 8))) + (i32.add (local.get $t) (local.get $s)) + ) + + (func (export "test_dead_store") (result f32) + (local $t f32) + (i32.store (i64.const 8) (i32.const 0x23232323)) + (local.set $t (f32.load (i64.const 11))) + (i32.store (i64.const 8) (i32.const 0)) + (local.get $t) + ) + + ;; A function named "malloc" which implementations nonetheless shouldn't + ;; assume behaves like C malloc. + (func $malloc (export "malloc") + (param $size i64) + (result i64) + (i64.const 16) + ) + + ;; Call malloc twice, but unlike C malloc, we don't get non-aliasing pointers. + (func (export "malloc_aliasing") + (result i32) + (local $x i64) + (local $y i64) + (local.set $x (call $malloc (i64.const 4))) + (local.set $y (call $malloc (i64.const 4))) + (i32.store (local.get $x) (i32.const 42)) + (i32.store (local.get $y) (i32.const 43)) + (i32.load (local.get $x)) + ) +) + +(assert_return (invoke "test_store_to_load") (i32.const 0x00000080)) +(invoke "zero_everything") +(assert_return (invoke "test_redundant_load") (i32.const 0x00000080)) +(invoke "zero_everything") +(assert_return (invoke "test_dead_store") (f32.const 0x1.18p-144)) +(invoke "zero_everything") +(assert_return (invoke "malloc_aliasing") (i32.const 43)) diff --git a/test/core/memory_trap64.wast b/test/core/memory_trap64.wast new file mode 100644 index 0000000000..78d39d87be --- /dev/null +++ b/test/core/memory_trap64.wast @@ -0,0 +1,269 @@ +(module + (memory i64 1) + + (func $addr_limit (result i64) + (i64.mul (memory.size) (i64.const 0x10000)) + ) + + (func (export "store") (param $i i64) (param $v i32) + (i32.store (i64.add (call $addr_limit) (local.get $i)) (local.get $v)) + ) + + (func (export "load") (param $i i64) (result i32) + (i32.load (i64.add (call $addr_limit) (local.get $i))) + ) + + (func (export "memory.grow") (param i64) (result i64) + (memory.grow (local.get 0)) + ) +) + +(assert_return (invoke "store" (i64.const -4) (i32.const 42))) +(assert_return (invoke "load" (i64.const -4)) (i32.const 42)) +(assert_trap (invoke "store" (i64.const -3) (i32.const 13)) "out of bounds memory access") +(assert_trap (invoke "load" (i64.const -3)) "out of bounds memory access") +(assert_trap (invoke "store" (i64.const -2) (i32.const 13)) "out of bounds memory access") +(assert_trap (invoke "load" (i64.const -2)) "out of bounds memory access") +(assert_trap (invoke "store" (i64.const -1) (i32.const 13)) "out of bounds memory access") +(assert_trap (invoke "load" (i64.const -1)) "out of bounds memory access") +(assert_trap (invoke "store" (i64.const 0) (i32.const 13)) "out of bounds memory access") +(assert_trap (invoke "load" (i64.const 0)) "out of bounds memory access") +(assert_trap (invoke "store" (i64.const 0x80000000) (i32.const 13)) "out of bounds memory access") +(assert_trap (invoke "load" (i64.const 0x80000000)) "out of bounds memory access") + +(module + (memory i64 1) + (data (i64.const 0) "abcdefgh") + (data (i64.const 0xfff8) "abcdefgh") + + (func (export "i32.load") (param $a i64) (result i32) + (i32.load (local.get $a)) + ) + (func (export "i64.load") (param $a i64) (result i64) + (i64.load (local.get $a)) + ) + (func (export "f32.load") (param $a i64) (result f32) + (f32.load (local.get $a)) + ) + (func (export "f64.load") (param $a i64) (result f64) + (f64.load (local.get $a)) + ) + (func (export "i32.load8_s") (param $a i64) (result i32) + (i32.load8_s (local.get $a)) + ) + (func (export "i32.load8_u") (param $a i64) (result i32) + (i32.load8_u (local.get $a)) + ) + (func (export "i32.load16_s") (param $a i64) (result i32) + (i32.load16_s (local.get $a)) + ) + (func (export "i32.load16_u") (param $a i64) (result i32) + (i32.load16_u (local.get $a)) + ) + (func (export "i64.load8_s") (param $a i64) (result i64) + (i64.load8_s (local.get $a)) + ) + (func (export "i64.load8_u") (param $a i64) (result i64) + (i64.load8_u (local.get $a)) + ) + (func (export "i64.load16_s") (param $a i64) (result i64) + (i64.load16_s (local.get $a)) + ) + (func (export "i64.load16_u") (param $a i64) (result i64) + (i64.load16_u (local.get $a)) + ) + (func (export "i64.load32_s") (param $a i64) (result i64) + (i64.load32_s (local.get $a)) + ) + (func (export "i64.load32_u") (param $a i64) (result i64) + (i64.load32_u (local.get $a)) + ) + (func (export "i32.store") (param $a i64) (param $v i32) + (i32.store (local.get $a) (local.get $v)) + ) + (func (export "i64.store") (param $a i64) (param $v i64) + (i64.store (local.get $a) (local.get $v)) + ) + (func (export "f32.store") (param $a i64) (param $v f32) + (f32.store (local.get $a) (local.get $v)) + ) + (func (export "f64.store") (param $a i64) (param $v f64) + (f64.store (local.get $a) (local.get $v)) + ) + (func (export "i32.store8") (param $a i64) (param $v i32) + (i32.store8 (local.get $a) (local.get $v)) + ) + (func (export "i32.store16") (param $a i64) (param $v i32) + (i32.store16 (local.get $a) (local.get $v)) + ) + (func (export "i64.store8") (param $a i64) (param $v i64) + (i64.store8 (local.get $a) (local.get $v)) + ) + (func (export "i64.store16") (param $a i64) (param $v i64) + (i64.store16 (local.get $a) (local.get $v)) + ) + (func (export "i64.store32") (param $a i64) (param $v i64) + (i64.store32 (local.get $a) (local.get $v)) + ) +) + +(assert_trap (invoke "i32.store" (i64.const 0x10000) (i32.const 0)) "out of bounds memory access") +(assert_trap (invoke "i32.store" (i64.const 0xffff) (i32.const 0)) "out of bounds memory access") +(assert_trap (invoke "i32.store" (i64.const 0xfffe) (i32.const 0)) "out of bounds memory access") +(assert_trap (invoke "i32.store" (i64.const 0xfffd) (i32.const 0)) "out of bounds memory access") +(assert_trap (invoke "i32.store" (i64.const -1) (i32.const 0)) "out of bounds memory access") +(assert_trap (invoke "i32.store" (i64.const -2) (i32.const 0)) "out of bounds memory access") +(assert_trap (invoke "i32.store" (i64.const -3) (i32.const 0)) "out of bounds memory access") +(assert_trap (invoke "i32.store" (i64.const -4) (i32.const 0)) "out of bounds memory access") +(assert_trap (invoke "i64.store" (i64.const 0x10000) (i64.const 0)) "out of bounds memory access") +(assert_trap (invoke "i64.store" (i64.const 0xffff) (i64.const 0)) "out of bounds memory access") +(assert_trap (invoke "i64.store" (i64.const 0xfffe) (i64.const 0)) "out of bounds memory access") +(assert_trap (invoke "i64.store" (i64.const 0xfffd) (i64.const 0)) "out of bounds memory access") +(assert_trap (invoke "i64.store" (i64.const 0xfffc) (i64.const 0)) "out of bounds memory access") +(assert_trap (invoke "i64.store" (i64.const 0xfffb) (i64.const 0)) "out of bounds memory access") +(assert_trap (invoke "i64.store" (i64.const 0xfffa) (i64.const 0)) "out of bounds memory access") +(assert_trap (invoke "i64.store" (i64.const 0xfff9) (i64.const 0)) "out of bounds memory access") +(assert_trap (invoke "i64.store" (i64.const -1) (i64.const 0)) "out of bounds memory access") +(assert_trap (invoke "i64.store" (i64.const -2) (i64.const 0)) "out of bounds memory access") +(assert_trap (invoke "i64.store" (i64.const -3) (i64.const 0)) "out of bounds memory access") +(assert_trap (invoke "i64.store" (i64.const -4) (i64.const 0)) "out of bounds memory access") +(assert_trap (invoke "i64.store" (i64.const -5) (i64.const 0)) "out of bounds memory access") +(assert_trap (invoke "i64.store" (i64.const -6) (i64.const 0)) "out of bounds memory access") +(assert_trap (invoke "i64.store" (i64.const -7) (i64.const 0)) "out of bounds memory access") +(assert_trap (invoke "i64.store" (i64.const -8) (i64.const 0)) "out of bounds memory access") +(assert_trap (invoke "f32.store" (i64.const 0x10000) (f32.const 0)) "out of bounds memory access") +(assert_trap (invoke "f32.store" (i64.const 0xffff) (f32.const 0)) "out of bounds memory access") +(assert_trap (invoke "f32.store" (i64.const 0xfffe) (f32.const 0)) "out of bounds memory access") +(assert_trap (invoke "f32.store" (i64.const 0xfffd) (f32.const 0)) "out of bounds memory access") +(assert_trap (invoke "f32.store" (i64.const -1) (f32.const 0)) "out of bounds memory access") +(assert_trap (invoke "f32.store" (i64.const -2) (f32.const 0)) "out of bounds memory access") +(assert_trap (invoke "f32.store" (i64.const -3) (f32.const 0)) "out of bounds memory access") +(assert_trap (invoke "f32.store" (i64.const -4) (f32.const 0)) "out of bounds memory access") +(assert_trap (invoke "f64.store" (i64.const 0x10000) (f64.const 0)) "out of bounds memory access") +(assert_trap (invoke "f64.store" (i64.const 0xffff) (f64.const 0)) "out of bounds memory access") +(assert_trap (invoke "f64.store" (i64.const 0xfffe) (f64.const 0)) "out of bounds memory access") +(assert_trap (invoke "f64.store" (i64.const 0xfffd) (f64.const 0)) "out of bounds memory access") +(assert_trap (invoke "f64.store" (i64.const 0xfffc) (f64.const 0)) "out of bounds memory access") +(assert_trap (invoke "f64.store" (i64.const 0xfffb) (f64.const 0)) "out of bounds memory access") +(assert_trap (invoke "f64.store" (i64.const 0xfffa) (f64.const 0)) "out of bounds memory access") +(assert_trap (invoke "f64.store" (i64.const 0xfff9) (f64.const 0)) "out of bounds memory access") +(assert_trap (invoke "f64.store" (i64.const -1) (f64.const 0)) "out of bounds memory access") +(assert_trap (invoke "f64.store" (i64.const -2) (f64.const 0)) "out of bounds memory access") +(assert_trap (invoke "f64.store" (i64.const -3) (f64.const 0)) "out of bounds memory access") +(assert_trap (invoke "f64.store" (i64.const -4) (f64.const 0)) "out of bounds memory access") +(assert_trap (invoke "f64.store" (i64.const -5) (f64.const 0)) "out of bounds memory access") +(assert_trap (invoke "f64.store" (i64.const -6) (f64.const 0)) "out of bounds memory access") +(assert_trap (invoke "f64.store" (i64.const -7) (f64.const 0)) "out of bounds memory access") +(assert_trap (invoke "f64.store" (i64.const -8) (f64.const 0)) "out of bounds memory access") +(assert_trap (invoke "i32.store8" (i64.const 0x10000) (i32.const 0)) "out of bounds memory access") +(assert_trap (invoke "i32.store8" (i64.const -1) (i32.const 0)) "out of bounds memory access") +(assert_trap (invoke "i32.store16" (i64.const 0x10000) (i32.const 0)) "out of bounds memory access") +(assert_trap (invoke "i32.store16" (i64.const 0xffff) (i32.const 0)) "out of bounds memory access") +(assert_trap (invoke "i32.store16" (i64.const -1) (i32.const 0)) "out of bounds memory access") +(assert_trap (invoke "i32.store16" (i64.const -2) (i32.const 0)) "out of bounds memory access") +(assert_trap (invoke "i64.store8" (i64.const 0x10000) (i64.const 0)) "out of bounds memory access") +(assert_trap (invoke "i64.store8" (i64.const -1) (i64.const 0)) "out of bounds memory access") +(assert_trap (invoke "i64.store16" (i64.const 0x10000) (i64.const 0)) "out of bounds memory access") +(assert_trap (invoke "i64.store16" (i64.const 0xffff) (i64.const 0)) "out of bounds memory access") +(assert_trap (invoke "i64.store16" (i64.const -1) (i64.const 0)) "out of bounds memory access") +(assert_trap (invoke "i64.store16" (i64.const -2) (i64.const 0)) "out of bounds memory access") +(assert_trap (invoke "i64.store32" (i64.const 0x10000) (i64.const 0)) "out of bounds memory access") +(assert_trap (invoke "i64.store32" (i64.const 0xffff) (i64.const 0)) "out of bounds memory access") +(assert_trap (invoke "i64.store32" (i64.const 0xfffe) (i64.const 0)) "out of bounds memory access") +(assert_trap (invoke "i64.store32" (i64.const 0xfffd) (i64.const 0)) "out of bounds memory access") +(assert_trap (invoke "i64.store32" (i64.const -1) (i64.const 0)) "out of bounds memory access") +(assert_trap (invoke "i64.store32" (i64.const -2) (i64.const 0)) "out of bounds memory access") +(assert_trap (invoke "i64.store32" (i64.const -3) (i64.const 0)) "out of bounds memory access") +(assert_trap (invoke "i64.store32" (i64.const -4) (i64.const 0)) "out of bounds memory access") +(assert_trap (invoke "i32.load" (i64.const 0x10000)) "out of bounds memory access") +(assert_trap (invoke "i32.load" (i64.const 0xffff)) "out of bounds memory access") +(assert_trap (invoke "i32.load" (i64.const 0xfffe)) "out of bounds memory access") +(assert_trap (invoke "i32.load" (i64.const 0xfffd)) "out of bounds memory access") +(assert_trap (invoke "i32.load" (i64.const -1)) "out of bounds memory access") +(assert_trap (invoke "i32.load" (i64.const -2)) "out of bounds memory access") +(assert_trap (invoke "i32.load" (i64.const -3)) "out of bounds memory access") +(assert_trap (invoke "i32.load" (i64.const -4)) "out of bounds memory access") +(assert_trap (invoke "i64.load" (i64.const 0x10000)) "out of bounds memory access") +(assert_trap (invoke "i64.load" (i64.const 0xffff)) "out of bounds memory access") +(assert_trap (invoke "i64.load" (i64.const 0xfffe)) "out of bounds memory access") +(assert_trap (invoke "i64.load" (i64.const 0xfffd)) "out of bounds memory access") +(assert_trap (invoke "i64.load" (i64.const 0xfffc)) "out of bounds memory access") +(assert_trap (invoke "i64.load" (i64.const 0xfffb)) "out of bounds memory access") +(assert_trap (invoke "i64.load" (i64.const 0xfffa)) "out of bounds memory access") +(assert_trap (invoke "i64.load" (i64.const 0xfff9)) "out of bounds memory access") +(assert_trap (invoke "i64.load" (i64.const -1)) "out of bounds memory access") +(assert_trap (invoke "i64.load" (i64.const -2)) "out of bounds memory access") +(assert_trap (invoke "i64.load" (i64.const -3)) "out of bounds memory access") +(assert_trap (invoke "i64.load" (i64.const -4)) "out of bounds memory access") +(assert_trap (invoke "i64.load" (i64.const -5)) "out of bounds memory access") +(assert_trap (invoke "i64.load" (i64.const -6)) "out of bounds memory access") +(assert_trap (invoke "i64.load" (i64.const -7)) "out of bounds memory access") +(assert_trap (invoke "i64.load" (i64.const -8)) "out of bounds memory access") +(assert_trap (invoke "f32.load" (i64.const 0x10000)) "out of bounds memory access") +(assert_trap (invoke "f32.load" (i64.const 0xffff)) "out of bounds memory access") +(assert_trap (invoke "f32.load" (i64.const 0xfffe)) "out of bounds memory access") +(assert_trap (invoke "f32.load" (i64.const 0xfffd)) "out of bounds memory access") +(assert_trap (invoke "f32.load" (i64.const -1)) "out of bounds memory access") +(assert_trap (invoke "f32.load" (i64.const -2)) "out of bounds memory access") +(assert_trap (invoke "f32.load" (i64.const -3)) "out of bounds memory access") +(assert_trap (invoke "f32.load" (i64.const -4)) "out of bounds memory access") +(assert_trap (invoke "f64.load" (i64.const 0x10000)) "out of bounds memory access") +(assert_trap (invoke "f64.load" (i64.const 0xffff)) "out of bounds memory access") +(assert_trap (invoke "f64.load" (i64.const 0xfffe)) "out of bounds memory access") +(assert_trap (invoke "f64.load" (i64.const 0xfffd)) "out of bounds memory access") +(assert_trap (invoke "f64.load" (i64.const 0xfffc)) "out of bounds memory access") +(assert_trap (invoke "f64.load" (i64.const 0xfffb)) "out of bounds memory access") +(assert_trap (invoke "f64.load" (i64.const 0xfffa)) "out of bounds memory access") +(assert_trap (invoke "f64.load" (i64.const 0xfff9)) "out of bounds memory access") +(assert_trap (invoke "f64.load" (i64.const -1)) "out of bounds memory access") +(assert_trap (invoke "f64.load" (i64.const -2)) "out of bounds memory access") +(assert_trap (invoke "f64.load" (i64.const -3)) "out of bounds memory access") +(assert_trap (invoke "f64.load" (i64.const -4)) "out of bounds memory access") +(assert_trap (invoke "f64.load" (i64.const -5)) "out of bounds memory access") +(assert_trap (invoke "f64.load" (i64.const -6)) "out of bounds memory access") +(assert_trap (invoke "f64.load" (i64.const -7)) "out of bounds memory access") +(assert_trap (invoke "f64.load" (i64.const -8)) "out of bounds memory access") +(assert_trap (invoke "i32.load8_s" (i64.const 0x10000)) "out of bounds memory access") +(assert_trap (invoke "i32.load8_s" (i64.const -1)) "out of bounds memory access") +(assert_trap (invoke "i32.load8_u" (i64.const 0x10000)) "out of bounds memory access") +(assert_trap (invoke "i32.load8_u" (i64.const -1)) "out of bounds memory access") +(assert_trap (invoke "i32.load16_s" (i64.const 0x10000)) "out of bounds memory access") +(assert_trap (invoke "i32.load16_s" (i64.const 0xffff)) "out of bounds memory access") +(assert_trap (invoke "i32.load16_s" (i64.const -1)) "out of bounds memory access") +(assert_trap (invoke "i32.load16_s" (i64.const -2)) "out of bounds memory access") +(assert_trap (invoke "i32.load16_u" (i64.const 0x10000)) "out of bounds memory access") +(assert_trap (invoke "i32.load16_u" (i64.const 0xffff)) "out of bounds memory access") +(assert_trap (invoke "i32.load16_u" (i64.const -1)) "out of bounds memory access") +(assert_trap (invoke "i32.load16_u" (i64.const -2)) "out of bounds memory access") +(assert_trap (invoke "i64.load8_s" (i64.const 0x10000)) "out of bounds memory access") +(assert_trap (invoke "i64.load8_s" (i64.const -1)) "out of bounds memory access") +(assert_trap (invoke "i64.load8_u" (i64.const 0x10000)) "out of bounds memory access") +(assert_trap (invoke "i64.load8_u" (i64.const -1)) "out of bounds memory access") +(assert_trap (invoke "i64.load16_s" (i64.const 0x10000)) "out of bounds memory access") +(assert_trap (invoke "i64.load16_s" (i64.const 0xffff)) "out of bounds memory access") +(assert_trap (invoke "i64.load16_s" (i64.const -1)) "out of bounds memory access") +(assert_trap (invoke "i64.load16_s" (i64.const -2)) "out of bounds memory access") +(assert_trap (invoke "i64.load16_u" (i64.const 0x10000)) "out of bounds memory access") +(assert_trap (invoke "i64.load16_u" (i64.const 0xffff)) "out of bounds memory access") +(assert_trap (invoke "i64.load16_u" (i64.const -1)) "out of bounds memory access") +(assert_trap (invoke "i64.load16_u" (i64.const -2)) "out of bounds memory access") +(assert_trap (invoke "i64.load32_s" (i64.const 0x10000)) "out of bounds memory access") +(assert_trap (invoke "i64.load32_s" (i64.const 0xffff)) "out of bounds memory access") +(assert_trap (invoke "i64.load32_s" (i64.const 0xfffe)) "out of bounds memory access") +(assert_trap (invoke "i64.load32_s" (i64.const 0xfffd)) "out of bounds memory access") +(assert_trap (invoke "i64.load32_s" (i64.const -1)) "out of bounds memory access") +(assert_trap (invoke "i64.load32_s" (i64.const -2)) "out of bounds memory access") +(assert_trap (invoke "i64.load32_s" (i64.const -3)) "out of bounds memory access") +(assert_trap (invoke "i64.load32_s" (i64.const -4)) "out of bounds memory access") +(assert_trap (invoke "i64.load32_u" (i64.const 0x10000)) "out of bounds memory access") +(assert_trap (invoke "i64.load32_u" (i64.const 0xffff)) "out of bounds memory access") +(assert_trap (invoke "i64.load32_u" (i64.const 0xfffe)) "out of bounds memory access") +(assert_trap (invoke "i64.load32_u" (i64.const 0xfffd)) "out of bounds memory access") +(assert_trap (invoke "i64.load32_u" (i64.const -1)) "out of bounds memory access") +(assert_trap (invoke "i64.load32_u" (i64.const -2)) "out of bounds memory access") +(assert_trap (invoke "i64.load32_u" (i64.const -3)) "out of bounds memory access") +(assert_trap (invoke "i64.load32_u" (i64.const -4)) "out of bounds memory access") + +;; No memory was changed +(assert_return (invoke "i64.load" (i64.const 0xfff8)) (i64.const 0x6867666564636261)) +(assert_return (invoke "i64.load" (i64.const 0)) (i64.const 0x6867666564636261)) diff --git a/test/core/multi-memory/binary0.wast b/test/core/multi-memory/binary0.wast index ff441120f8..88270ac9e8 100644 --- a/test/core/multi-memory/binary0.wast +++ b/test/core/multi-memory/binary0.wast @@ -47,9 +47,9 @@ (assert_malformed (module binary "\00asm" "\01\00\00\00" - "\05\0a\02" ;; Memory section with 2 entries + "\05\10\02" ;; Memory section with 2 entries "\00\01" ;; no max, minimum 1 - "\00\82\80\80\80\80\00" ;; no max, minimum 2 with one byte too many + "\00\82\80\80\80\80\80\80\80\80\80\80\00" ;; no max, minimum 2 with one byte too many ) "integer representation too long" ) diff --git a/test/core/run.py b/test/core/run.py index d153799775..1404929fc0 100755 --- a/test/core/run.py +++ b/test/core/run.py @@ -36,7 +36,8 @@ relaxed_simd_test_files = glob.glob(os.path.join(inputDir, "relaxed-simd", "*.wast")) gc_test_files = glob.glob(os.path.join(inputDir, "gc", "*.wast")) multi_memory_test_files = glob.glob(os.path.join(inputDir, "multi-memory", "*.wast")) -all_test_files = main_test_files + simd_test_files + relaxed_simd_test_files + gc_test_files + multi_memory_test_files +stack_switching_test_files = glob.glob(os.path.join(inputDir, "stack-switching", "*.wast")) +all_test_files = main_test_files + simd_test_files + relaxed_simd_test_files + gc_test_files + multi_memory_test_files + stack_switching_test_files wasmExec = arguments.wasm wasmCommand = wasmExec + " " + arguments.opts diff --git a/test/core/simd/simd_address.wast b/test/core/simd/simd_address.wast index 9e023008bb..56a5e4567d 100644 --- a/test/core/simd/simd_address.wast +++ b/test/core/simd/simd_address.wast @@ -140,18 +140,18 @@ ;; Offset constant out of range -(assert_malformed +(assert_invalid (module quote "(memory 1)" "(func (drop (v128.load offset=4294967296 (i32.const 0))))" ) - "i32 constant" + "offset out of range" ) -(assert_malformed +(assert_invalid (module quote "(memory 1)" "(func (v128.store offset=4294967296 (i32.const 0) (v128.const i32x4 0 0 0 0)))" ) - "i32 constant" + "offset out of range" ) diff --git a/test/core/stack-switching/cont.wast b/test/core/stack-switching/cont.wast index cc84061ff0..91c4ba0cb3 100644 --- a/test/core/stack-switching/cont.wast +++ b/test/core/stack-switching/cont.wast @@ -925,4 +925,145 @@ (elem declare func $even $odd) ) -(assert_return (invoke "main") (i32.const 10)) \ No newline at end of file +(assert_return (invoke "main") (i32.const 10)) + +;; Syntax: check unfolded forms +(module + (type $ft (func)) + (type $ct (cont $ft)) + (rec + (type $ft2 (func (param (ref null $ct2)))) + (type $ct2 (cont $ft2))) + + (tag $yield (param i32)) + (tag $swap) + + ;; Check cont.new + (func (result (ref $ct)) + ref.null $ft + block (param (ref null $ft)) (result (ref $ct)) + cont.new $ct + end + ) + ;; Check cont.bind + (func (param (ref $ct)) (result (ref $ct)) + local.get 0 + block (param (ref $ct)) (result (ref $ct)) + cont.bind $ct $ct + end + ) + ;; Check suspend + (func + block + suspend $swap + end + ) + ;; Check resume + (func (param $k (ref $ct)) (result i32) + (local.get $k) + block $on_yield (param (ref $ct)) (result i32 (ref $ct)) + resume $ct (on $yield $on_yield) + i32.const 42 + return + end + local.set $k + ) + ;; Check resume_throw + (func (param $k (ref $ct)) (result i32) + block $on_yield (result i32 (ref $ct)) + i32.const 42 + local.get $k + resume_throw $ct $yield + i32.const 42 + return + end + local.set $k + ) + ;; Check switch + (func (param $k (ref $ct2)) + local.get $k + block (param (ref $ct2)) (result (ref null $ct2)) + switch $ct2 $swap + end + drop + ) +) + +;; Syntax: check instructions in tail position in unfolded form +(module + (type $ft (func)) + (type $ct (cont $ft)) + (rec + (type $ft2 (func (param (ref null $ct2)))) + (type $ct2 (cont $ft2))) + + (tag $yield (param i32)) + (tag $swap) + + ;; Check cont.new + (func (result (ref $ct)) + ref.null $ft + cont.new $ct + ) + ;; Check cont.bind + (func (param (ref $ct)) (result (ref $ct)) + local.get 0 + cont.bind $ct $ct + ) + + ;; Check resume + (func (;2;) (param $k (ref $ct)) + local.get $k + resume $ct + ) + ;; Check resume_throw + (func (param $k (ref $ct)) + i32.const 42 + local.get $k + resume_throw $ct $yield + ) + ;; Check switch + (func (param $k (ref $ct2)) (result (ref null $ct2)) + local.get $k + switch $ct2 $swap + ) + ;; Check suspend + (func + suspend $swap + ) +) + +(module + (type $ft0 (func)) + (type $ct0 (cont $ft0)) + + (type $ft1 (func (param (ref $ct0)))) + (type $ct1 (cont $ft1)) + + (tag $t) + + (func $f + (cont.new $ct1 (ref.func $g)) + (switch $ct1 $t) + ) + (elem declare func $f) + + (func $g (param (ref $ct0))) + (elem declare func $g) + + (func $entry + (cont.new $ct0 (ref.func $f)) + (resume $ct0 (on $t switch)) + ) +) + +(assert_invalid + (module + (rec + (type $ft (func (param (ref $ct)))) + (type $ct (cont $ft))) + (tag $t (param i32)) + + (func (param $k (ref $ct)) + (switch $ct $t))) + "type mismatch in switch tag") diff --git a/test/core/table.wast b/test/core/table.wast index 9180162424..c993ca76b3 100644 --- a/test/core/table.wast +++ b/test/core/table.wast @@ -22,7 +22,6 @@ (assert_invalid (module (elem (i32.const 0))) "unknown table") (assert_invalid (module (elem (i32.const 0) $f) (func $f)) "unknown table") - (assert_invalid (module (table 1 0 funcref)) "size minimum must not be greater than maximum" @@ -32,19 +31,46 @@ "size minimum must not be greater than maximum" ) -(assert_malformed +(assert_invalid (module quote "(table 0x1_0000_0000 funcref)") - "i32 constant out of range" + "table size" ) -(assert_malformed +(assert_invalid (module quote "(table 0x1_0000_0000 0x1_0000_0000 funcref)") - "i32 constant out of range" + "table size" ) -(assert_malformed +(assert_invalid (module quote "(table 0 0x1_0000_0000 funcref)") - "i32 constant out of range" + "table size" ) +;; Same as above but with i64 address types + +(module (table i64 0 funcref)) +(module (table i64 1 funcref)) +(module (table i64 0 0 funcref)) +(module (table i64 0 1 funcref)) +(module (table i64 1 256 funcref)) +(module (table i64 0 65536 funcref)) +(module (table i64 0 0xffff_ffff funcref)) + +(module (table i64 0 funcref) (table i64 0 funcref)) +(module (table (import "spectest" "table64") i64 0 funcref) (table i64 0 funcref)) + +(assert_invalid + (module (table i64 1 0 funcref)) + "size minimum must not be greater than maximum" +) +(assert_invalid + (module (table i64 0xffff_ffff 0 funcref)) + "size minimum must not be greater than maximum" +) + +;; Elem segments with no table + +(assert_invalid (module (elem (i32.const 0))) "unknown table") +(assert_invalid (module (elem (i32.const 0) $f) (func $f)) "unknown table") + (assert_invalid (module (table 1 (ref null func) (i32.const 0))) "type mismatch" diff --git a/test/core/table_copy.wast b/test/core/table_copy.wast index 380e84ee59..613fc5295e 100644 --- a/test/core/table_copy.wast +++ b/test/core/table_copy.wast @@ -2218,6 +2218,556 @@ (assert_trap (invoke "test") "out of bounds table access") +(module + (table $t0 i64 30 30 funcref) + (table $t1 i64 30 30 funcref) + (elem (table $t0) (i64.const 2) func 3 1 4 1) + (elem funcref + (ref.func 2) (ref.func 7) (ref.func 1) (ref.func 8)) + (elem (table $t0) (i64.const 12) func 7 5 2 3 6) + (elem funcref + (ref.func 5) (ref.func 9) (ref.func 2) (ref.func 7) (ref.func 6)) + (func (result i32) (i32.const 0)) + (func (result i32) (i32.const 1)) + (func (result i32) (i32.const 2)) + (func (result i32) (i32.const 3)) + (func (result i32) (i32.const 4)) + (func (result i32) (i32.const 5)) + (func (result i32) (i32.const 6)) + (func (result i32) (i32.const 7)) + (func (result i32) (i32.const 8)) + (func (result i32) (i32.const 9)) + (func (export "test") + (table.copy $t0 $t0 (i64.const 28) (i64.const 1) (i64.const 3)) + )) + +(assert_trap (invoke "test") "out of bounds table access") + +(module + (table $t0 i64 30 30 funcref) + (table $t1 i64 30 30 funcref) + (elem (table $t0) (i64.const 2) func 3 1 4 1) + (elem funcref + (ref.func 2) (ref.func 7) (ref.func 1) (ref.func 8)) + (elem (table $t0) (i64.const 12) func 7 5 2 3 6) + (elem funcref + (ref.func 5) (ref.func 9) (ref.func 2) (ref.func 7) (ref.func 6)) + (func (result i32) (i32.const 0)) + (func (result i32) (i32.const 1)) + (func (result i32) (i32.const 2)) + (func (result i32) (i32.const 3)) + (func (result i32) (i32.const 4)) + (func (result i32) (i32.const 5)) + (func (result i32) (i32.const 6)) + (func (result i32) (i32.const 7)) + (func (result i32) (i32.const 8)) + (func (result i32) (i32.const 9)) + (func (export "test") + (table.copy $t0 $t0 (i64.const 0xFFFFFFFE) (i64.const 1) (i64.const 2)) + )) + +(assert_trap (invoke "test") "out of bounds table access") + +(module + (table $t0 i64 30 30 funcref) + (table $t1 i64 30 30 funcref) + (elem (table $t0) (i64.const 2) func 3 1 4 1) + (elem funcref + (ref.func 2) (ref.func 7) (ref.func 1) (ref.func 8)) + (elem (table $t0) (i64.const 12) func 7 5 2 3 6) + (elem funcref + (ref.func 5) (ref.func 9) (ref.func 2) (ref.func 7) (ref.func 6)) + (func (result i32) (i32.const 0)) + (func (result i32) (i32.const 1)) + (func (result i32) (i32.const 2)) + (func (result i32) (i32.const 3)) + (func (result i32) (i32.const 4)) + (func (result i32) (i32.const 5)) + (func (result i32) (i32.const 6)) + (func (result i32) (i32.const 7)) + (func (result i32) (i32.const 8)) + (func (result i32) (i32.const 9)) + (func (export "test") + (table.copy $t0 $t0 (i64.const 15) (i64.const 25) (i64.const 6)) + )) + +(assert_trap (invoke "test") "out of bounds table access") + +(module + (table $t0 i64 30 30 funcref) + (table $t1 i64 30 30 funcref) + (elem (table $t0) (i64.const 2) func 3 1 4 1) + (elem funcref + (ref.func 2) (ref.func 7) (ref.func 1) (ref.func 8)) + (elem (table $t0) (i64.const 12) func 7 5 2 3 6) + (elem funcref + (ref.func 5) (ref.func 9) (ref.func 2) (ref.func 7) (ref.func 6)) + (func (result i32) (i32.const 0)) + (func (result i32) (i32.const 1)) + (func (result i32) (i32.const 2)) + (func (result i32) (i32.const 3)) + (func (result i32) (i32.const 4)) + (func (result i32) (i32.const 5)) + (func (result i32) (i32.const 6)) + (func (result i32) (i32.const 7)) + (func (result i32) (i32.const 8)) + (func (result i32) (i32.const 9)) + (func (export "test") + (table.copy $t0 $t0 (i64.const 15) (i64.const 0xFFFFFFFE) (i64.const 2)) + )) + +(assert_trap (invoke "test") "out of bounds table access") + +(module + (table $t0 i64 30 30 funcref) + (table $t1 i64 30 30 funcref) + (elem (table $t0) (i64.const 2) func 3 1 4 1) + (elem funcref + (ref.func 2) (ref.func 7) (ref.func 1) (ref.func 8)) + (elem (table $t0) (i64.const 12) func 7 5 2 3 6) + (elem funcref + (ref.func 5) (ref.func 9) (ref.func 2) (ref.func 7) (ref.func 6)) + (func (result i32) (i32.const 0)) + (func (result i32) (i32.const 1)) + (func (result i32) (i32.const 2)) + (func (result i32) (i32.const 3)) + (func (result i32) (i32.const 4)) + (func (result i32) (i32.const 5)) + (func (result i32) (i32.const 6)) + (func (result i32) (i32.const 7)) + (func (result i32) (i32.const 8)) + (func (result i32) (i32.const 9)) + (func (export "test") + (table.copy $t0 $t0 (i64.const 15) (i64.const 25) (i64.const 0)) + )) + +(invoke "test") + +(module + (table $t0 i64 30 30 funcref) + (table $t1 i64 30 30 funcref) + (elem (table $t0) (i64.const 2) func 3 1 4 1) + (elem funcref + (ref.func 2) (ref.func 7) (ref.func 1) (ref.func 8)) + (elem (table $t0) (i64.const 12) func 7 5 2 3 6) + (elem funcref + (ref.func 5) (ref.func 9) (ref.func 2) (ref.func 7) (ref.func 6)) + (func (result i32) (i32.const 0)) + (func (result i32) (i32.const 1)) + (func (result i32) (i32.const 2)) + (func (result i32) (i32.const 3)) + (func (result i32) (i32.const 4)) + (func (result i32) (i32.const 5)) + (func (result i32) (i32.const 6)) + (func (result i32) (i32.const 7)) + (func (result i32) (i32.const 8)) + (func (result i32) (i32.const 9)) + (func (export "test") + (table.copy $t0 $t0 (i64.const 30) (i64.const 15) (i64.const 0)) + )) + +(invoke "test") + +(module + (table $t0 i64 30 30 funcref) + (table $t1 i64 30 30 funcref) + (elem (table $t0) (i64.const 2) func 3 1 4 1) + (elem funcref + (ref.func 2) (ref.func 7) (ref.func 1) (ref.func 8)) + (elem (table $t0) (i64.const 12) func 7 5 2 3 6) + (elem funcref + (ref.func 5) (ref.func 9) (ref.func 2) (ref.func 7) (ref.func 6)) + (func (result i32) (i32.const 0)) + (func (result i32) (i32.const 1)) + (func (result i32) (i32.const 2)) + (func (result i32) (i32.const 3)) + (func (result i32) (i32.const 4)) + (func (result i32) (i32.const 5)) + (func (result i32) (i32.const 6)) + (func (result i32) (i32.const 7)) + (func (result i32) (i32.const 8)) + (func (result i32) (i32.const 9)) + (func (export "test") + (table.copy $t0 $t0 (i64.const 31) (i64.const 15) (i64.const 0)) + )) + +(assert_trap (invoke "test") "out of bounds table access") + +(module + (table $t0 i64 30 30 funcref) + (table $t1 i64 30 30 funcref) + (elem (table $t0) (i64.const 2) func 3 1 4 1) + (elem funcref + (ref.func 2) (ref.func 7) (ref.func 1) (ref.func 8)) + (elem (table $t0) (i64.const 12) func 7 5 2 3 6) + (elem funcref + (ref.func 5) (ref.func 9) (ref.func 2) (ref.func 7) (ref.func 6)) + (func (result i32) (i32.const 0)) + (func (result i32) (i32.const 1)) + (func (result i32) (i32.const 2)) + (func (result i32) (i32.const 3)) + (func (result i32) (i32.const 4)) + (func (result i32) (i32.const 5)) + (func (result i32) (i32.const 6)) + (func (result i32) (i32.const 7)) + (func (result i32) (i32.const 8)) + (func (result i32) (i32.const 9)) + (func (export "test") + (table.copy $t0 $t0 (i64.const 15) (i64.const 30) (i64.const 0)) + )) + +(invoke "test") + +(module + (table $t0 i64 30 30 funcref) + (table $t1 i64 30 30 funcref) + (elem (table $t0) (i64.const 2) func 3 1 4 1) + (elem funcref + (ref.func 2) (ref.func 7) (ref.func 1) (ref.func 8)) + (elem (table $t0) (i64.const 12) func 7 5 2 3 6) + (elem funcref + (ref.func 5) (ref.func 9) (ref.func 2) (ref.func 7) (ref.func 6)) + (func (result i32) (i32.const 0)) + (func (result i32) (i32.const 1)) + (func (result i32) (i32.const 2)) + (func (result i32) (i32.const 3)) + (func (result i32) (i32.const 4)) + (func (result i32) (i32.const 5)) + (func (result i32) (i32.const 6)) + (func (result i32) (i32.const 7)) + (func (result i32) (i32.const 8)) + (func (result i32) (i32.const 9)) + (func (export "test") + (table.copy $t0 $t0 (i64.const 15) (i64.const 31) (i64.const 0)) + )) + +(assert_trap (invoke "test") "out of bounds table access") + +(module + (table $t0 i64 30 30 funcref) + (table $t1 i64 30 30 funcref) + (elem (table $t0) (i64.const 2) func 3 1 4 1) + (elem funcref + (ref.func 2) (ref.func 7) (ref.func 1) (ref.func 8)) + (elem (table $t0) (i64.const 12) func 7 5 2 3 6) + (elem funcref + (ref.func 5) (ref.func 9) (ref.func 2) (ref.func 7) (ref.func 6)) + (func (result i32) (i32.const 0)) + (func (result i32) (i32.const 1)) + (func (result i32) (i32.const 2)) + (func (result i32) (i32.const 3)) + (func (result i32) (i32.const 4)) + (func (result i32) (i32.const 5)) + (func (result i32) (i32.const 6)) + (func (result i32) (i32.const 7)) + (func (result i32) (i32.const 8)) + (func (result i32) (i32.const 9)) + (func (export "test") + (table.copy $t0 $t0 (i64.const 30) (i64.const 30) (i64.const 0)) + )) + +(invoke "test") + +(module + (table $t0 i64 30 30 funcref) + (table $t1 i64 30 30 funcref) + (elem (table $t0) (i64.const 2) func 3 1 4 1) + (elem funcref + (ref.func 2) (ref.func 7) (ref.func 1) (ref.func 8)) + (elem (table $t0) (i64.const 12) func 7 5 2 3 6) + (elem funcref + (ref.func 5) (ref.func 9) (ref.func 2) (ref.func 7) (ref.func 6)) + (func (result i32) (i32.const 0)) + (func (result i32) (i32.const 1)) + (func (result i32) (i32.const 2)) + (func (result i32) (i32.const 3)) + (func (result i32) (i32.const 4)) + (func (result i32) (i32.const 5)) + (func (result i32) (i32.const 6)) + (func (result i32) (i32.const 7)) + (func (result i32) (i32.const 8)) + (func (result i32) (i32.const 9)) + (func (export "test") + (table.copy $t0 $t0 (i64.const 31) (i64.const 31) (i64.const 0)) + )) + +(assert_trap (invoke "test") "out of bounds table access") + +(module + (table $t0 i64 30 30 funcref) + (table $t1 i64 30 30 funcref) + (elem (table $t0) (i64.const 2) func 3 1 4 1) + (elem funcref + (ref.func 2) (ref.func 7) (ref.func 1) (ref.func 8)) + (elem (table $t0) (i64.const 12) func 7 5 2 3 6) + (elem funcref + (ref.func 5) (ref.func 9) (ref.func 2) (ref.func 7) (ref.func 6)) + (func (result i32) (i32.const 0)) + (func (result i32) (i32.const 1)) + (func (result i32) (i32.const 2)) + (func (result i32) (i32.const 3)) + (func (result i32) (i32.const 4)) + (func (result i32) (i32.const 5)) + (func (result i32) (i32.const 6)) + (func (result i32) (i32.const 7)) + (func (result i32) (i32.const 8)) + (func (result i32) (i32.const 9)) + (func (export "test") + (table.copy $t1 $t0 (i64.const 28) (i64.const 1) (i64.const 3)) + )) + +(assert_trap (invoke "test") "out of bounds table access") + +(module + (table $t0 i64 30 30 funcref) + (table $t1 i64 30 30 funcref) + (elem (table $t0) (i64.const 2) func 3 1 4 1) + (elem funcref + (ref.func 2) (ref.func 7) (ref.func 1) (ref.func 8)) + (elem (table $t0) (i64.const 12) func 7 5 2 3 6) + (elem funcref + (ref.func 5) (ref.func 9) (ref.func 2) (ref.func 7) (ref.func 6)) + (func (result i32) (i32.const 0)) + (func (result i32) (i32.const 1)) + (func (result i32) (i32.const 2)) + (func (result i32) (i32.const 3)) + (func (result i32) (i32.const 4)) + (func (result i32) (i32.const 5)) + (func (result i32) (i32.const 6)) + (func (result i32) (i32.const 7)) + (func (result i32) (i32.const 8)) + (func (result i32) (i32.const 9)) + (func (export "test") + (table.copy $t1 $t0 (i64.const 0xFFFFFFFE) (i64.const 1) (i64.const 2)) + )) + +(assert_trap (invoke "test") "out of bounds table access") + +(module + (table $t0 i64 30 30 funcref) + (table $t1 i64 30 30 funcref) + (elem (table $t0) (i64.const 2) func 3 1 4 1) + (elem funcref + (ref.func 2) (ref.func 7) (ref.func 1) (ref.func 8)) + (elem (table $t0) (i64.const 12) func 7 5 2 3 6) + (elem funcref + (ref.func 5) (ref.func 9) (ref.func 2) (ref.func 7) (ref.func 6)) + (func (result i32) (i32.const 0)) + (func (result i32) (i32.const 1)) + (func (result i32) (i32.const 2)) + (func (result i32) (i32.const 3)) + (func (result i32) (i32.const 4)) + (func (result i32) (i32.const 5)) + (func (result i32) (i32.const 6)) + (func (result i32) (i32.const 7)) + (func (result i32) (i32.const 8)) + (func (result i32) (i32.const 9)) + (func (export "test") + (table.copy $t1 $t0 (i64.const 15) (i64.const 25) (i64.const 6)) + )) + +(assert_trap (invoke "test") "out of bounds table access") + +(module + (table $t0 i64 30 30 funcref) + (table $t1 i64 30 30 funcref) + (elem (table $t0) (i64.const 2) func 3 1 4 1) + (elem funcref + (ref.func 2) (ref.func 7) (ref.func 1) (ref.func 8)) + (elem (table $t0) (i64.const 12) func 7 5 2 3 6) + (elem funcref + (ref.func 5) (ref.func 9) (ref.func 2) (ref.func 7) (ref.func 6)) + (func (result i32) (i32.const 0)) + (func (result i32) (i32.const 1)) + (func (result i32) (i32.const 2)) + (func (result i32) (i32.const 3)) + (func (result i32) (i32.const 4)) + (func (result i32) (i32.const 5)) + (func (result i32) (i32.const 6)) + (func (result i32) (i32.const 7)) + (func (result i32) (i32.const 8)) + (func (result i32) (i32.const 9)) + (func (export "test") + (table.copy $t1 $t0 (i64.const 15) (i64.const 0xFFFFFFFE) (i64.const 2)) + )) + +(assert_trap (invoke "test") "out of bounds table access") + +(module + (table $t0 i64 30 30 funcref) + (table $t1 i64 30 30 funcref) + (elem (table $t0) (i64.const 2) func 3 1 4 1) + (elem funcref + (ref.func 2) (ref.func 7) (ref.func 1) (ref.func 8)) + (elem (table $t0) (i64.const 12) func 7 5 2 3 6) + (elem funcref + (ref.func 5) (ref.func 9) (ref.func 2) (ref.func 7) (ref.func 6)) + (func (result i32) (i32.const 0)) + (func (result i32) (i32.const 1)) + (func (result i32) (i32.const 2)) + (func (result i32) (i32.const 3)) + (func (result i32) (i32.const 4)) + (func (result i32) (i32.const 5)) + (func (result i32) (i32.const 6)) + (func (result i32) (i32.const 7)) + (func (result i32) (i32.const 8)) + (func (result i32) (i32.const 9)) + (func (export "test") + (table.copy $t1 $t0 (i64.const 15) (i64.const 25) (i64.const 0)) + )) + +(invoke "test") + +(module + (table $t0 i64 30 30 funcref) + (table $t1 i64 30 30 funcref) + (elem (table $t0) (i64.const 2) func 3 1 4 1) + (elem funcref + (ref.func 2) (ref.func 7) (ref.func 1) (ref.func 8)) + (elem (table $t0) (i64.const 12) func 7 5 2 3 6) + (elem funcref + (ref.func 5) (ref.func 9) (ref.func 2) (ref.func 7) (ref.func 6)) + (func (result i32) (i32.const 0)) + (func (result i32) (i32.const 1)) + (func (result i32) (i32.const 2)) + (func (result i32) (i32.const 3)) + (func (result i32) (i32.const 4)) + (func (result i32) (i32.const 5)) + (func (result i32) (i32.const 6)) + (func (result i32) (i32.const 7)) + (func (result i32) (i32.const 8)) + (func (result i32) (i32.const 9)) + (func (export "test") + (table.copy $t1 $t0 (i64.const 30) (i64.const 15) (i64.const 0)) + )) + +(invoke "test") + +(module + (table $t0 i64 30 30 funcref) + (table $t1 i64 30 30 funcref) + (elem (table $t0) (i64.const 2) func 3 1 4 1) + (elem funcref + (ref.func 2) (ref.func 7) (ref.func 1) (ref.func 8)) + (elem (table $t0) (i64.const 12) func 7 5 2 3 6) + (elem funcref + (ref.func 5) (ref.func 9) (ref.func 2) (ref.func 7) (ref.func 6)) + (func (result i32) (i32.const 0)) + (func (result i32) (i32.const 1)) + (func (result i32) (i32.const 2)) + (func (result i32) (i32.const 3)) + (func (result i32) (i32.const 4)) + (func (result i32) (i32.const 5)) + (func (result i32) (i32.const 6)) + (func (result i32) (i32.const 7)) + (func (result i32) (i32.const 8)) + (func (result i32) (i32.const 9)) + (func (export "test") + (table.copy $t1 $t0 (i64.const 31) (i64.const 15) (i64.const 0)) + )) + +(assert_trap (invoke "test") "out of bounds table access") + +(module + (table $t0 i64 30 30 funcref) + (table $t1 i64 30 30 funcref) + (elem (table $t0) (i64.const 2) func 3 1 4 1) + (elem funcref + (ref.func 2) (ref.func 7) (ref.func 1) (ref.func 8)) + (elem (table $t0) (i64.const 12) func 7 5 2 3 6) + (elem funcref + (ref.func 5) (ref.func 9) (ref.func 2) (ref.func 7) (ref.func 6)) + (func (result i32) (i32.const 0)) + (func (result i32) (i32.const 1)) + (func (result i32) (i32.const 2)) + (func (result i32) (i32.const 3)) + (func (result i32) (i32.const 4)) + (func (result i32) (i32.const 5)) + (func (result i32) (i32.const 6)) + (func (result i32) (i32.const 7)) + (func (result i32) (i32.const 8)) + (func (result i32) (i32.const 9)) + (func (export "test") + (table.copy $t1 $t0 (i64.const 15) (i64.const 30) (i64.const 0)) + )) + +(invoke "test") + +(module + (table $t0 i64 30 30 funcref) + (table $t1 i64 30 30 funcref) + (elem (table $t0) (i64.const 2) func 3 1 4 1) + (elem funcref + (ref.func 2) (ref.func 7) (ref.func 1) (ref.func 8)) + (elem (table $t0) (i64.const 12) func 7 5 2 3 6) + (elem funcref + (ref.func 5) (ref.func 9) (ref.func 2) (ref.func 7) (ref.func 6)) + (func (result i32) (i32.const 0)) + (func (result i32) (i32.const 1)) + (func (result i32) (i32.const 2)) + (func (result i32) (i32.const 3)) + (func (result i32) (i32.const 4)) + (func (result i32) (i32.const 5)) + (func (result i32) (i32.const 6)) + (func (result i32) (i32.const 7)) + (func (result i32) (i32.const 8)) + (func (result i32) (i32.const 9)) + (func (export "test") + (table.copy $t1 $t0 (i64.const 15) (i64.const 31) (i64.const 0)) + )) + +(assert_trap (invoke "test") "out of bounds table access") + +(module + (table $t0 i64 30 30 funcref) + (table $t1 i64 30 30 funcref) + (elem (table $t0) (i64.const 2) func 3 1 4 1) + (elem funcref + (ref.func 2) (ref.func 7) (ref.func 1) (ref.func 8)) + (elem (table $t0) (i64.const 12) func 7 5 2 3 6) + (elem funcref + (ref.func 5) (ref.func 9) (ref.func 2) (ref.func 7) (ref.func 6)) + (func (result i32) (i32.const 0)) + (func (result i32) (i32.const 1)) + (func (result i32) (i32.const 2)) + (func (result i32) (i32.const 3)) + (func (result i32) (i32.const 4)) + (func (result i32) (i32.const 5)) + (func (result i32) (i32.const 6)) + (func (result i32) (i32.const 7)) + (func (result i32) (i32.const 8)) + (func (result i32) (i32.const 9)) + (func (export "test") + (table.copy $t1 $t0 (i64.const 30) (i64.const 30) (i64.const 0)) + )) + +(invoke "test") + +(module + (table $t0 i64 30 30 funcref) + (table $t1 i64 30 30 funcref) + (elem (table $t0) (i64.const 2) func 3 1 4 1) + (elem funcref + (ref.func 2) (ref.func 7) (ref.func 1) (ref.func 8)) + (elem (table $t0) (i64.const 12) func 7 5 2 3 6) + (elem funcref + (ref.func 5) (ref.func 9) (ref.func 2) (ref.func 7) (ref.func 6)) + (func (result i32) (i32.const 0)) + (func (result i32) (i32.const 1)) + (func (result i32) (i32.const 2)) + (func (result i32) (i32.const 3)) + (func (result i32) (i32.const 4)) + (func (result i32) (i32.const 5)) + (func (result i32) (i32.const 6)) + (func (result i32) (i32.const 7)) + (func (result i32) (i32.const 8)) + (func (result i32) (i32.const 9)) + (func (export "test") + (table.copy $t1 $t0 (i64.const 31) (i64.const 31) (i64.const 0)) + )) + +(assert_trap (invoke "test") "out of bounds table access") + (module (type (func (result i32))) (table 32 64 funcref) diff --git a/test/core/table_copy_mixed.wast b/test/core/table_copy_mixed.wast new file mode 100644 index 0000000000..e34cde0d0b --- /dev/null +++ b/test/core/table_copy_mixed.wast @@ -0,0 +1,48 @@ +;; Valid cases +(module + (table $t32 30 30 funcref) + (table $t64 i64 30 30 funcref) + + (func (export "test32") + (table.copy $t32 $t32 (i32.const 13) (i32.const 2) (i32.const 3))) + + (func (export "test64") + (table.copy $t64 $t64 (i64.const 13) (i64.const 2) (i64.const 3))) + + (func (export "test_64to32") + (table.copy $t32 $t64 (i32.const 13) (i64.const 2) (i32.const 3))) + + (func (export "test_32to64") + (table.copy $t64 $t32 (i64.const 13) (i32.const 2) (i32.const 3))) +) + +;; Invalid cases +(assert_invalid (module + (table $t32 30 30 funcref) + (table $t64 i64 30 30 funcref) + + (func (export "bad_size_arg") + (table.copy $t32 $t64 (i32.const 13) (i64.const 2) (i64.const 3))) + ) + "type mismatch" +) + +(assert_invalid (module + (table $t32 30 30 funcref) + (table $t64 i64 30 30 funcref) + + (func (export "bad_src_idx") + (table.copy $t32 $t64 (i32.const 13) (i32.const 2) (i32.const 3))) + ) + "type mismatch" +) + +(assert_invalid (module + (table $t32 30 30 funcref) + (table $t64 i64 30 30 funcref) + + (func (export "bad_dst_idx") + (table.copy $t32 $t64 (i64.const 13) (i64.const 2) (i32.const 3))) + ) + "type mismatch" +) diff --git a/test/core/table_fill.wast b/test/core/table_fill.wast index a8e2225520..ea0c752523 100644 --- a/test/core/table_fill.wast +++ b/test/core/table_fill.wast @@ -12,6 +12,16 @@ (func (export "get") (param $i i32) (result externref) (table.get $t (local.get $i)) ) + + (table $t64 i64 10 externref) + + (func (export "fill-t64") (param $i i64) (param $r externref) (param $n i64) + (table.fill $t64 (local.get $i) (local.get $r) (local.get $n)) + ) + + (func (export "get-t64") (param $i i64) (result externref) + (table.get $t64 (local.get $i)) + ) ) (assert_return (invoke "get" (i32.const 1)) (ref.null extern)) @@ -68,6 +78,61 @@ "out of bounds table access" ) +;; Same as above but for t64 + +(assert_return (invoke "get-t64" (i64.const 1)) (ref.null extern)) +(assert_return (invoke "get-t64" (i64.const 2)) (ref.null extern)) +(assert_return (invoke "get-t64" (i64.const 3)) (ref.null extern)) +(assert_return (invoke "get-t64" (i64.const 4)) (ref.null extern)) +(assert_return (invoke "get-t64" (i64.const 5)) (ref.null extern)) + +(assert_return (invoke "fill-t64" (i64.const 2) (ref.extern 1) (i64.const 3))) +(assert_return (invoke "get-t64" (i64.const 1)) (ref.null extern)) +(assert_return (invoke "get-t64" (i64.const 2)) (ref.extern 1)) +(assert_return (invoke "get-t64" (i64.const 3)) (ref.extern 1)) +(assert_return (invoke "get-t64" (i64.const 4)) (ref.extern 1)) +(assert_return (invoke "get-t64" (i64.const 5)) (ref.null extern)) + +(assert_return (invoke "fill-t64" (i64.const 4) (ref.extern 2) (i64.const 2))) +(assert_return (invoke "get-t64" (i64.const 3)) (ref.extern 1)) +(assert_return (invoke "get-t64" (i64.const 4)) (ref.extern 2)) +(assert_return (invoke "get-t64" (i64.const 5)) (ref.extern 2)) +(assert_return (invoke "get-t64" (i64.const 6)) (ref.null extern)) + +(assert_return (invoke "fill-t64" (i64.const 4) (ref.extern 3) (i64.const 0))) +(assert_return (invoke "get-t64" (i64.const 3)) (ref.extern 1)) +(assert_return (invoke "get-t64" (i64.const 4)) (ref.extern 2)) +(assert_return (invoke "get-t64" (i64.const 5)) (ref.extern 2)) + +(assert_return (invoke "fill-t64" (i64.const 8) (ref.extern 4) (i64.const 2))) +(assert_return (invoke "get-t64" (i64.const 7)) (ref.null extern)) +(assert_return (invoke "get-t64" (i64.const 8)) (ref.extern 4)) +(assert_return (invoke "get-t64" (i64.const 9)) (ref.extern 4)) + +(assert_return (invoke "fill-t64" (i64.const 9) (ref.null extern) (i64.const 1))) +(assert_return (invoke "get-t64" (i64.const 8)) (ref.extern 4)) +(assert_return (invoke "get-t64" (i64.const 9)) (ref.null extern)) + +(assert_return (invoke "fill-t64" (i64.const 10) (ref.extern 5) (i64.const 0))) +(assert_return (invoke "get-t64" (i64.const 9)) (ref.null extern)) + +(assert_trap + (invoke "fill-t64" (i64.const 8) (ref.extern 6) (i64.const 3)) + "out of bounds table access" +) +(assert_return (invoke "get-t64" (i64.const 7)) (ref.null extern)) +(assert_return (invoke "get-t64" (i64.const 8)) (ref.extern 4)) +(assert_return (invoke "get-t64" (i64.const 9)) (ref.null extern)) + +(assert_trap + (invoke "fill-t64" (i64.const 11) (ref.null extern) (i64.const 0)) + "out of bounds table access" +) + +(assert_trap + (invoke "fill-t64" (i64.const 11) (ref.null extern) (i64.const 10)) + "out of bounds table access" +) ;; Type errors diff --git a/test/core/table_get.wast b/test/core/table_get.wast index 0dedb19f51..b472ad2552 100644 --- a/test/core/table_get.wast +++ b/test/core/table_get.wast @@ -1,6 +1,7 @@ (module (table $t2 2 externref) (table $t3 3 funcref) + (table $t64 i64 3 funcref) (elem (table $t3) (i32.const 1) func $dummy) (func $dummy) @@ -15,6 +16,9 @@ (func $f3 (export "get-funcref") (param $i i32) (result funcref) (table.get $t3 (local.get $i)) ) + (func $f4 (export "get-funcref-t64") (param $i i64) (result funcref) + (table.get $t64 (local.get $i)) + ) (func (export "is_null-funcref") (param $i i32) (result i32) (ref.is_null (call $f3 (local.get $i))) @@ -27,6 +31,7 @@ (assert_return (invoke "get-externref" (i32.const 1)) (ref.extern 1)) (assert_return (invoke "get-funcref" (i32.const 0)) (ref.null func)) +(assert_return (invoke "get-funcref-t64" (i64.const 0)) (ref.null func)) (assert_return (invoke "is_null-funcref" (i32.const 1)) (i32.const 0)) (assert_return (invoke "is_null-funcref" (i32.const 2)) (i32.const 0)) diff --git a/test/core/table_grow.wast b/test/core/table_grow.wast index 5345a800ff..e0872d78db 100644 --- a/test/core/table_grow.wast +++ b/test/core/table_grow.wast @@ -11,6 +11,15 @@ (table.grow (local.get $init) (local.get $sz)) ) (func (export "size") (result i32) (table.size $t)) + + (table $t64 i64 0 externref) + + (func (export "get-t64") (param $i i64) (result externref) (table.get $t64 (local.get $i))) + (func (export "set-t64") (param $i i64) (param $r externref) (table.set $t64 (local.get $i) (local.get $r))) + (func (export "grow-t64") (param $sz i64) (param $init externref) (result i64) + (table.grow $t64 (local.get $init) (local.get $sz)) + ) + (func (export "size-t64") (result i64) (table.size $t64)) ) (assert_return (invoke "size") (i32.const 0)) @@ -37,6 +46,30 @@ (assert_trap (invoke "set" (i32.const 5) (ref.extern 2)) "out of bounds table access") (assert_trap (invoke "get" (i32.const 5)) "out of bounds table access") +;; Similar to above but for t64 +(assert_return (invoke "size-t64") (i64.const 0)) +(assert_trap (invoke "set-t64" (i64.const 0) (ref.extern 2)) "out of bounds table access") +(assert_trap (invoke "get-t64" (i64.const 0)) "out of bounds table access") + +(assert_return (invoke "grow-t64" (i64.const 1) (ref.null extern)) (i64.const 0)) +(assert_return (invoke "size-t64") (i64.const 1)) +(assert_return (invoke "get-t64" (i64.const 0)) (ref.null extern)) +(assert_return (invoke "set-t64" (i64.const 0) (ref.extern 2))) +(assert_return (invoke "get-t64" (i64.const 0)) (ref.extern 2)) +(assert_trap (invoke "set-t64" (i64.const 1) (ref.extern 2)) "out of bounds table access") +(assert_trap (invoke "get-t64" (i64.const 1)) "out of bounds table access") + +(assert_return (invoke "grow-t64" (i64.const 4) (ref.extern 3)) (i64.const 1)) +(assert_return (invoke "size-t64") (i64.const 5)) +(assert_return (invoke "get-t64" (i64.const 0)) (ref.extern 2)) +(assert_return (invoke "set-t64" (i64.const 0) (ref.extern 2))) +(assert_return (invoke "get-t64" (i64.const 0)) (ref.extern 2)) +(assert_return (invoke "get-t64" (i64.const 1)) (ref.extern 3)) +(assert_return (invoke "get-t64" (i64.const 4)) (ref.extern 3)) +(assert_return (invoke "set-t64" (i64.const 4) (ref.extern 4))) +(assert_return (invoke "get-t64" (i64.const 4)) (ref.extern 4)) +(assert_trap (invoke "set-t64" (i64.const 5) (ref.extern 2)) "out of bounds table access") +(assert_trap (invoke "get-t64" (i64.const 5)) "out of bounds table access") ;; Reject growing to size outside i32 value range (module diff --git a/test/core/table_init.wast b/test/core/table_init.wast index 0b2d26f772..5c3679ab9a 100644 --- a/test/core/table_init.wast +++ b/test/core/table_init.wast @@ -21,6 +21,7 @@ (import "a" "ef4" (func (result i32))) ;; index 4 (table $t0 30 30 funcref) (table $t1 30 30 funcref) + (table $t2 i64 30 30 funcref) (elem (table $t0) (i32.const 2) func 3 1 4 1) (elem funcref (ref.func 2) (ref.func 7) (ref.func 1) (ref.func 8)) @@ -79,6 +80,7 @@ (import "a" "ef4" (func (result i32))) ;; index 4 (table $t0 30 30 funcref) (table $t1 30 30 funcref) + (table $t2 i64 30 30 funcref) (elem (table $t0) (i32.const 2) func 3 1 4 1) (elem funcref (ref.func 2) (ref.func 7) (ref.func 1) (ref.func 8)) @@ -137,6 +139,7 @@ (import "a" "ef4" (func (result i32))) ;; index 4 (table $t0 30 30 funcref) (table $t1 30 30 funcref) + (table $t2 i64 30 30 funcref) (elem (table $t0) (i32.const 2) func 3 1 4 1) (elem funcref (ref.func 2) (ref.func 7) (ref.func 1) (ref.func 8)) @@ -203,6 +206,7 @@ (import "a" "ef4" (func (result i32))) ;; index 4 (table $t0 30 30 funcref) (table $t1 30 30 funcref) + (table $t2 i64 30 30 funcref) (elem (table $t1) (i32.const 2) func 3 1 4 1) (elem funcref (ref.func 2) (ref.func 7) (ref.func 1) (ref.func 8)) @@ -261,6 +265,7 @@ (import "a" "ef4" (func (result i32))) ;; index 4 (table $t0 30 30 funcref) (table $t1 30 30 funcref) + (table $t2 i64 30 30 funcref) (elem (table $t1) (i32.const 2) func 3 1 4 1) (elem funcref (ref.func 2) (ref.func 7) (ref.func 1) (ref.func 8)) @@ -319,6 +324,7 @@ (import "a" "ef4" (func (result i32))) ;; index 4 (table $t0 30 30 funcref) (table $t1 30 30 funcref) + (table $t2 i64 30 30 funcref) (elem (table $t1) (i32.const 2) func 3 1 4 1) (elem funcref (ref.func 2) (ref.func 7) (ref.func 1) (ref.func 8)) @@ -375,6 +381,191 @@ (assert_trap (invoke "check" (i32.const 27)) "uninitialized element") (assert_trap (invoke "check" (i32.const 28)) "uninitialized element") (assert_trap (invoke "check" (i32.const 29)) "uninitialized element") + +(module + (type (func (result i32))) ;; type #0 + (import "a" "ef0" (func (result i32))) ;; index 0 + (import "a" "ef1" (func (result i32))) + (import "a" "ef2" (func (result i32))) + (import "a" "ef3" (func (result i32))) + (import "a" "ef4" (func (result i32))) ;; index 4 + (table $t0 30 30 funcref) + (table $t1 30 30 funcref) + (table $t2 i64 30 30 funcref) + (elem (table $t2) (i64.const 2) func 3 1 4 1) + (elem funcref + (ref.func 2) (ref.func 7) (ref.func 1) (ref.func 8)) + (elem (table $t2) (i64.const 12) func 7 5 2 3 6) + (elem funcref + (ref.func 5) (ref.func 9) (ref.func 2) (ref.func 7) (ref.func 6)) + (func (result i32) (i32.const 5)) ;; index 5 + (func (result i32) (i32.const 6)) + (func (result i32) (i32.const 7)) + (func (result i32) (i32.const 8)) + (func (result i32) (i32.const 9)) ;; index 9 + (func (export "test") + (table.init $t2 1 (i64.const 7) (i32.const 0) (i32.const 4))) + (func (export "check") (param i64) (result i32) + (call_indirect $t2 (type 0) (local.get 0))) +) + +(invoke "test") +(assert_trap (invoke "check" (i64.const 0)) "uninitialized element") +(assert_trap (invoke "check" (i64.const 1)) "uninitialized element") +(assert_return (invoke "check" (i64.const 2)) (i32.const 3)) +(assert_return (invoke "check" (i64.const 3)) (i32.const 1)) +(assert_return (invoke "check" (i64.const 4)) (i32.const 4)) +(assert_return (invoke "check" (i64.const 5)) (i32.const 1)) +(assert_trap (invoke "check" (i64.const 6)) "uninitialized element") +(assert_return (invoke "check" (i64.const 7)) (i32.const 2)) +(assert_return (invoke "check" (i64.const 8)) (i32.const 7)) +(assert_return (invoke "check" (i64.const 9)) (i32.const 1)) +(assert_return (invoke "check" (i64.const 10)) (i32.const 8)) +(assert_trap (invoke "check" (i64.const 11)) "uninitialized element") +(assert_return (invoke "check" (i64.const 12)) (i32.const 7)) +(assert_return (invoke "check" (i64.const 13)) (i32.const 5)) +(assert_return (invoke "check" (i64.const 14)) (i32.const 2)) +(assert_return (invoke "check" (i64.const 15)) (i32.const 3)) +(assert_return (invoke "check" (i64.const 16)) (i32.const 6)) +(assert_trap (invoke "check" (i64.const 17)) "uninitialized element") +(assert_trap (invoke "check" (i64.const 18)) "uninitialized element") +(assert_trap (invoke "check" (i64.const 19)) "uninitialized element") +(assert_trap (invoke "check" (i64.const 20)) "uninitialized element") +(assert_trap (invoke "check" (i64.const 21)) "uninitialized element") +(assert_trap (invoke "check" (i64.const 22)) "uninitialized element") +(assert_trap (invoke "check" (i64.const 23)) "uninitialized element") +(assert_trap (invoke "check" (i64.const 24)) "uninitialized element") +(assert_trap (invoke "check" (i64.const 25)) "uninitialized element") +(assert_trap (invoke "check" (i64.const 26)) "uninitialized element") +(assert_trap (invoke "check" (i64.const 27)) "uninitialized element") +(assert_trap (invoke "check" (i64.const 28)) "uninitialized element") +(assert_trap (invoke "check" (i64.const 29)) "uninitialized element") + +(module + (type (func (result i32))) ;; type #0 + (import "a" "ef0" (func (result i32))) ;; index 0 + (import "a" "ef1" (func (result i32))) + (import "a" "ef2" (func (result i32))) + (import "a" "ef3" (func (result i32))) + (import "a" "ef4" (func (result i32))) ;; index 4 + (table $t0 30 30 funcref) + (table $t1 30 30 funcref) + (table $t2 i64 30 30 funcref) + (elem (table $t2) (i64.const 2) func 3 1 4 1) + (elem funcref + (ref.func 2) (ref.func 7) (ref.func 1) (ref.func 8)) + (elem (table $t2) (i64.const 12) func 7 5 2 3 6) + (elem funcref + (ref.func 5) (ref.func 9) (ref.func 2) (ref.func 7) (ref.func 6)) + (func (result i32) (i32.const 5)) ;; index 5 + (func (result i32) (i32.const 6)) + (func (result i32) (i32.const 7)) + (func (result i32) (i32.const 8)) + (func (result i32) (i32.const 9)) ;; index 9 + (func (export "test") + (table.init $t2 3 (i64.const 15) (i32.const 1) (i32.const 3))) + (func (export "check") (param i64) (result i32) + (call_indirect $t2 (type 0) (local.get 0))) +) + +(invoke "test") +(assert_trap (invoke "check" (i64.const 0)) "uninitialized element") +(assert_trap (invoke "check" (i64.const 1)) "uninitialized element") +(assert_return (invoke "check" (i64.const 2)) (i32.const 3)) +(assert_return (invoke "check" (i64.const 3)) (i32.const 1)) +(assert_return (invoke "check" (i64.const 4)) (i32.const 4)) +(assert_return (invoke "check" (i64.const 5)) (i32.const 1)) +(assert_trap (invoke "check" (i64.const 6)) "uninitialized element") +(assert_trap (invoke "check" (i64.const 7)) "uninitialized element") +(assert_trap (invoke "check" (i64.const 8)) "uninitialized element") +(assert_trap (invoke "check" (i64.const 9)) "uninitialized element") +(assert_trap (invoke "check" (i64.const 10)) "uninitialized element") +(assert_trap (invoke "check" (i64.const 11)) "uninitialized element") +(assert_return (invoke "check" (i64.const 12)) (i32.const 7)) +(assert_return (invoke "check" (i64.const 13)) (i32.const 5)) +(assert_return (invoke "check" (i64.const 14)) (i32.const 2)) +(assert_return (invoke "check" (i64.const 15)) (i32.const 9)) +(assert_return (invoke "check" (i64.const 16)) (i32.const 2)) +(assert_return (invoke "check" (i64.const 17)) (i32.const 7)) +(assert_trap (invoke "check" (i64.const 18)) "uninitialized element") +(assert_trap (invoke "check" (i64.const 19)) "uninitialized element") +(assert_trap (invoke "check" (i64.const 20)) "uninitialized element") +(assert_trap (invoke "check" (i64.const 21)) "uninitialized element") +(assert_trap (invoke "check" (i64.const 22)) "uninitialized element") +(assert_trap (invoke "check" (i64.const 23)) "uninitialized element") +(assert_trap (invoke "check" (i64.const 24)) "uninitialized element") +(assert_trap (invoke "check" (i64.const 25)) "uninitialized element") +(assert_trap (invoke "check" (i64.const 26)) "uninitialized element") +(assert_trap (invoke "check" (i64.const 27)) "uninitialized element") +(assert_trap (invoke "check" (i64.const 28)) "uninitialized element") +(assert_trap (invoke "check" (i64.const 29)) "uninitialized element") + +(module + (type (func (result i32))) ;; type #0 + (import "a" "ef0" (func (result i32))) ;; index 0 + (import "a" "ef1" (func (result i32))) + (import "a" "ef2" (func (result i32))) + (import "a" "ef3" (func (result i32))) + (import "a" "ef4" (func (result i32))) ;; index 4 + (table $t0 30 30 funcref) + (table $t1 30 30 funcref) + (table $t2 i64 30 30 funcref) + (elem (table $t2) (i64.const 2) func 3 1 4 1) + (elem funcref + (ref.func 2) (ref.func 7) (ref.func 1) (ref.func 8)) + (elem (table $t2) (i64.const 12) func 7 5 2 3 6) + (elem funcref + (ref.func 5) (ref.func 9) (ref.func 2) (ref.func 7) (ref.func 6)) + (func (result i32) (i32.const 5)) ;; index 5 + (func (result i32) (i32.const 6)) + (func (result i32) (i32.const 7)) + (func (result i32) (i32.const 8)) + (func (result i32) (i32.const 9)) ;; index 9 + (func (export "test") + (table.init $t2 1 (i64.const 7) (i32.const 0) (i32.const 4)) + (elem.drop 1) + (table.init $t2 3 (i64.const 15) (i32.const 1) (i32.const 3)) + (elem.drop 3) + (table.copy $t2 2 (i64.const 20) (i64.const 15) (i64.const 5)) + (table.copy $t2 2 (i64.const 21) (i64.const 29) (i64.const 1)) + (table.copy $t2 2 (i64.const 24) (i64.const 10) (i64.const 1)) + (table.copy $t2 2 (i64.const 13) (i64.const 11) (i64.const 4)) + (table.copy $t2 2 (i64.const 19) (i64.const 20) (i64.const 5))) + (func (export "check") (param i64) (result i32) + (call_indirect $t2 (type 0) (local.get 0))) +) + +(invoke "test") +(assert_trap (invoke "check" (i64.const 0)) "uninitialized element") +(assert_trap (invoke "check" (i64.const 1)) "uninitialized element") +(assert_return (invoke "check" (i64.const 2)) (i32.const 3)) +(assert_return (invoke "check" (i64.const 3)) (i32.const 1)) +(assert_return (invoke "check" (i64.const 4)) (i32.const 4)) +(assert_return (invoke "check" (i64.const 5)) (i32.const 1)) +(assert_trap (invoke "check" (i64.const 6)) "uninitialized element") +(assert_return (invoke "check" (i64.const 7)) (i32.const 2)) +(assert_return (invoke "check" (i64.const 8)) (i32.const 7)) +(assert_return (invoke "check" (i64.const 9)) (i32.const 1)) +(assert_return (invoke "check" (i64.const 10)) (i32.const 8)) +(assert_trap (invoke "check" (i64.const 11)) "uninitialized element") +(assert_return (invoke "check" (i64.const 12)) (i32.const 7)) +(assert_trap (invoke "check" (i64.const 13)) "uninitialized element") +(assert_return (invoke "check" (i64.const 14)) (i32.const 7)) +(assert_return (invoke "check" (i64.const 15)) (i32.const 5)) +(assert_return (invoke "check" (i64.const 16)) (i32.const 2)) +(assert_return (invoke "check" (i64.const 17)) (i32.const 7)) +(assert_trap (invoke "check" (i64.const 18)) "uninitialized element") +(assert_return (invoke "check" (i64.const 19)) (i32.const 9)) +(assert_trap (invoke "check" (i64.const 20)) "uninitialized element") +(assert_return (invoke "check" (i64.const 21)) (i32.const 7)) +(assert_trap (invoke "check" (i64.const 22)) "uninitialized element") +(assert_return (invoke "check" (i64.const 23)) (i32.const 8)) +(assert_return (invoke "check" (i64.const 24)) (i32.const 8)) +(assert_trap (invoke "check" (i64.const 25)) "uninitialized element") +(assert_trap (invoke "check" (i64.const 26)) "uninitialized element") +(assert_trap (invoke "check" (i64.const 27)) "uninitialized element") +(assert_trap (invoke "check" (i64.const 28)) "uninitialized element") +(assert_trap (invoke "check" (i64.const 29)) "uninitialized element") (assert_invalid (module (func (export "test") diff --git a/test/core/table_set.wast b/test/core/table_set.wast index 3362f95673..246e01ad90 100644 --- a/test/core/table_set.wast +++ b/test/core/table_set.wast @@ -1,6 +1,7 @@ (module (table $t2 1 externref) (table $t3 2 funcref) + (table $t64 i64 2 funcref) (elem (table $t3) (i32.const 1) func $dummy) (func $dummy) @@ -10,6 +11,9 @@ (func $f3 (export "get-funcref") (param $i i32) (result funcref) (table.get $t3 (local.get $i)) ) + (func $f4 (export "get-funcref-t64") (param $i i64) (result funcref) + (table.get $t64 (local.get $i)) + ) (func (export "set-externref") (param $i i32) (param $r externref) (table.set (local.get $i) (local.get $r)) @@ -20,6 +24,9 @@ (func (export "set-funcref-from") (param $i i32) (param $j i32) (table.set $t3 (local.get $i) (table.get $t3 (local.get $j))) ) + (func (export "set-funcref-t64") (param $i i64) (param $r funcref) + (table.set $t64 (local.get $i) (local.get $r)) + ) (func (export "is_null-funcref") (param $i i32) (result i32) (ref.is_null (call $f3 (local.get $i))) @@ -32,6 +39,9 @@ (assert_return (invoke "set-externref" (i32.const 0) (ref.null extern))) (assert_return (invoke "get-externref" (i32.const 0)) (ref.null extern)) +(assert_return (invoke "set-funcref-t64" (i64.const 0) (ref.null func))) +(assert_return (invoke "get-funcref-t64" (i64.const 0)) (ref.null func)) + (assert_return (invoke "get-funcref" (i32.const 0)) (ref.null func)) (assert_return (invoke "set-funcref-from" (i32.const 0) (i32.const 1))) (assert_return (invoke "is_null-funcref" (i32.const 0)) (i32.const 0)) diff --git a/test/core/table_size.wast b/test/core/table_size.wast index 83fef02b33..71081d7e6b 100644 --- a/test/core/table_size.wast +++ b/test/core/table_size.wast @@ -3,11 +3,13 @@ (table $t1 1 externref) (table $t2 0 2 externref) (table $t3 3 8 externref) + (table $t64 i64 42 42 externref) (func (export "size-t0") (result i32) table.size) (func (export "size-t1") (result i32) (table.size $t1)) (func (export "size-t2") (result i32) (table.size $t2)) (func (export "size-t3") (result i32) (table.size $t3)) + (func (export "size-t64") (result i64) (table.size $t64)) (func (export "grow-t0") (param $sz i32) (drop (table.grow $t0 (ref.null extern) (local.get $sz))) @@ -63,6 +65,7 @@ (assert_return (invoke "grow-t3" (i32.const 1))) (assert_return (invoke "size-t3") (i32.const 8)) +(assert_return (invoke "size-t64") (i64.const 42)) ;; Type errors diff --git a/test/js-api/memory/assertions.js b/test/js-api/memory/assertions.js index b539513adc..4407a04035 100644 --- a/test/js-api/memory/assertions.js +++ b/test/js-api/memory/assertions.js @@ -27,7 +27,7 @@ function assert_ArrayBuffer(actual, { size=0, shared=false, detached=false }, me assert_equals(Object.isExtensible(actual), !shared, "buffer extensibility"); } -function assert_Memory(memory, { size=0, shared=false }) { +function assert_Memory(memory, { size=0, shared=false, address="i32" }) { assert_equals(Object.getPrototypeOf(memory), WebAssembly.Memory.prototype, "prototype"); assert_true(Object.isExtensible(memory), "extensible"); @@ -35,4 +35,9 @@ function assert_Memory(memory, { size=0, shared=false }) { // https://github.com/WebAssembly/spec/issues/840 assert_equals(memory.buffer, memory.buffer, "buffer should be idempotent"); assert_ArrayBuffer(memory.buffer, { size, shared }); + + // this depends on js-types proposal implementation + if (typeof memory.type == "function") { + assert_equals(memory.type().address, address, "memory address type"); + } } diff --git a/test/js-api/memory/constructor.any.js b/test/js-api/memory/constructor.any.js index 0a0be11e37..05953f2763 100644 --- a/test/js-api/memory/constructor.any.js +++ b/test/js-api/memory/constructor.any.js @@ -62,10 +62,29 @@ for (const value of outOfRangeValues) { }, `Out-of-range maximum value in descriptor: ${format_value(value)}`); } +const outOfRangeValuesI64 = [ + -1n, + 0x1_0000_0000_0000_0000n, +]; + +for (const value of outOfRangeValuesI64) { + test(() => { + assert_throws_js(TypeError, () => new WebAssembly.Memory({ "address": "i64", "initial": value })); + }, `Out-of-range initial i64 value in descriptor: ${format_value(value)}`); + + test(() => { + assert_throws_js(TypeError, () => new WebAssembly.Memory({ "address": "i64", "initial": 0n, "maximum": value })); + }, `Out-of-range maximum i64 value in descriptor: ${format_value(value)}`); +} + test(() => { assert_throws_js(RangeError, () => new WebAssembly.Memory({ "initial": 10, "maximum": 9 })); }, "Initial value exceeds maximum"); +test(() => { + assert_throws_js(RangeError, () => new WebAssembly.Memory({ "address": "i64", "initial": 10n, "maximum": 9n })); +}, "Initial value exceeds maximum (i64)"); + test(() => { const proxy = new Proxy({}, { has(o, x) { @@ -79,6 +98,8 @@ test(() => { case "initial": case "maximum": return 0; + case "address": + return "i32"; default: return undefined; } @@ -110,9 +131,21 @@ test(() => { }, }; }, + + get address() { + order.push("address"); + return { + toString() { + order.push("address toString"); + return "i32"; + }, + }; + }, }); assert_array_equals(order, [ + "address", + "address toString", "initial", "initial valueOf", "maximum", @@ -132,8 +165,66 @@ test(() => { assert_Memory(memory, { "size": 4 }); }, "Non-zero initial"); +test(() => { + const argument = { "address": "i64", "initial": 0n }; + const memory = new WebAssembly.Memory(argument); + assert_Memory(memory, { "size": 0, "address": "i64" }); +}, "Zero initial (i64)"); + +test(() => { + const argument = { "address": "i64", "initial": 4n }; + const memory = new WebAssembly.Memory(argument); + assert_Memory(memory, { "size": 4, "address": "i64" }); +}, "Non-zero initial (i64)"); + test(() => { const argument = { "initial": 0 }; const memory = new WebAssembly.Memory(argument, {}); assert_Memory(memory, { "size": 0 }); }, "Stray argument"); + +test(() => { + const argument = { "initial": 1 }; + const memory = new WebAssembly.Memory(argument); + assert_Memory(memory, { "size": 1, "address": "i32" }); +}, "Memory with address parameter omitted"); + +test(() => { + const argument = { "initial": 1, "address": "i32" }; + const memory = new WebAssembly.Memory(argument); + assert_Memory(memory, { "size": 1, "address": "i32" }); +}, "Memory with i32 address constructor"); + +test(() => { + const argument = { "initial": 1n, "address": "i64" }; + const memory = new WebAssembly.Memory(argument); + assert_Memory(memory, { "size": 1, "address": "i64" }); +}, "Memory with i64 address constructor"); + +test(() => { + const argument = { "initial": "3" }; + const memory = new WebAssembly.Memory(argument); + assert_Memory(memory, { "size": 3 }); +}, "Memory with string value for initial"); + +test(() => { + const argument = { "address": "i64", "initial": "3" }; + const memory = new WebAssembly.Memory(argument); + assert_Memory(memory, { "size": 3, "address": "i64" }); +}, "Memory with string value for initial (i64)"); + +test(() => { + const argument = { "initial": true }; + const memory = new WebAssembly.Memory(argument); + assert_Memory(memory, { "size": 1 }); +}, "Memory with boolean value for initial"); + +test(() => { + const argument = { "address": "i64", "initial": true }; + const memory = new WebAssembly.Memory(argument); + assert_Memory(memory, { "size": 1, "address": "i64" }); +}, "Memory with boolean value for initial (i64)"); + +test(() => { + assert_throws_js(TypeError, () => new WebAssembly.Memory({ "initial": 1, "address": "none" })); +}, "Unknown memory address"); diff --git a/test/js-api/memory/grow.any.js b/test/js-api/memory/grow.any.js index c511129491..cb1a9a6f32 100644 --- a/test/js-api/memory/grow.any.js +++ b/test/js-api/memory/grow.any.js @@ -47,6 +47,21 @@ test(() => { assert_ArrayBuffer(newMemory, { "size": 2 }, "New buffer after growing"); }, "Zero initial"); +test(() => { + const argument = { "address": "i64", "initial": 0n }; + const memory = new WebAssembly.Memory(argument); + const oldMemory = memory.buffer; + assert_ArrayBuffer(oldMemory, { "size": 0 }, "Buffer before growing"); + + const result = memory.grow(2n); + assert_equals(result, 0n); + + const newMemory = memory.buffer; + assert_not_equals(oldMemory, newMemory); + assert_ArrayBuffer(oldMemory, { "detached": true }, "Old buffer after growing"); + assert_ArrayBuffer(newMemory, { "size": 2 }, "New buffer after growing"); +}, "Zero initial (i64)"); + test(() => { const argument = { "initial": { valueOf() { return 0 } } }; const memory = new WebAssembly.Memory(argument); @@ -77,6 +92,21 @@ test(() => { assert_ArrayBuffer(newMemory, { "size": 5 }, "New buffer after growing"); }, "Non-zero initial"); +test(() => { + const argument = { "address": "i64", "initial": 3n }; + const memory = new WebAssembly.Memory(argument); + const oldMemory = memory.buffer; + assert_ArrayBuffer(oldMemory, { "size": 3 }, "Buffer before growing"); + + const result = memory.grow(2n); + assert_equals(result, 3n); + + const newMemory = memory.buffer; + assert_not_equals(oldMemory, newMemory); + assert_ArrayBuffer(oldMemory, { "detached": true }, "Old buffer after growing"); + assert_ArrayBuffer(newMemory, { "size": 5 }, "New buffer after growing"); +}, "Non-zero initial (i64)"); + test(() => { const argument = { "initial": 0, "maximum": 2 }; const memory = new WebAssembly.Memory(argument); @@ -92,6 +122,21 @@ test(() => { assert_ArrayBuffer(newMemory, { "size": 2 }, "New buffer after growing"); }, "Zero initial with respected maximum"); +test(() => { + const argument = { "address": "i64", "initial": 0n, "maximum": 2n }; + const memory = new WebAssembly.Memory(argument); + const oldMemory = memory.buffer; + assert_ArrayBuffer(oldMemory, { "size": 0 }, "Buffer before growing"); + + const result = memory.grow(2n); + assert_equals(result, 0n); + + const newMemory = memory.buffer; + assert_not_equals(oldMemory, newMemory); + assert_ArrayBuffer(oldMemory, { "detached": true }, "Old buffer after growing"); + assert_ArrayBuffer(newMemory, { "size": 2 }, "New buffer after growing"); +}, "Zero initial with respected maximum (i64)"); + test(() => { const argument = { "initial": 0, "maximum": 2 }; const memory = new WebAssembly.Memory(argument); @@ -116,6 +161,30 @@ test(() => { assert_ArrayBuffer(newestMemory, { "size": 2 }, "Newest buffer after growing twice"); }, "Zero initial with respected maximum grown twice"); +test(() => { + const argument = { "address": "i64", "initial": 0n, "maximum": 2n }; + const memory = new WebAssembly.Memory(argument); + const oldMemory = memory.buffer; + assert_ArrayBuffer(oldMemory, { "size": 0 }, "Buffer before growing"); + + const result = memory.grow(1n); + assert_equals(result, 0n); + + const newMemory = memory.buffer; + assert_not_equals(oldMemory, newMemory); + assert_ArrayBuffer(oldMemory, { "detached": true }, "Old buffer after growing once"); + assert_ArrayBuffer(newMemory, { "size": 1 }, "New buffer after growing once"); + + const result2 = memory.grow(1n); + assert_equals(result2, 1n); + + const newestMemory = memory.buffer; + assert_not_equals(newMemory, newestMemory); + assert_ArrayBuffer(oldMemory, { "detached": true }, "New buffer after growing twice"); + assert_ArrayBuffer(newMemory, { "detached": true }, "New buffer after growing twice"); + assert_ArrayBuffer(newestMemory, { "size": 2 }, "Newest buffer after growing twice"); +}, "Zero initial with respected maximum grown twice (i64)"); + test(() => { const argument = { "initial": 1, "maximum": 2 }; const memory = new WebAssembly.Memory(argument); @@ -127,6 +196,17 @@ test(() => { assert_ArrayBuffer(memory.buffer, { "size": 1 }, "Buffer before trying to grow"); }, "Zero initial growing too much"); +test(() => { + const argument = { "address": "i64", "initial": 1n, "maximum": 2n }; + const memory = new WebAssembly.Memory(argument); + const oldMemory = memory.buffer; + assert_ArrayBuffer(oldMemory, { "size": 1 }, "Buffer before growing"); + + assert_throws_js(RangeError, () => memory.grow(2n)); + assert_equals(memory.buffer, oldMemory); + assert_ArrayBuffer(memory.buffer, { "size": 1 }, "Buffer before trying to grow"); +}, "Zero initial growing too much (i64)"); + const outOfRangeValues = [ undefined, NaN, @@ -147,6 +227,20 @@ for (const value of outOfRangeValues) { }, `Out-of-range argument: ${format_value(value)}`); } +const outOfRangeValuesI64 = [ + -1n, + 0x10000000000000000n, + "0x10000000000000000", +]; + +for (const value of outOfRangeValuesI64) { + test(() => { + const argument = { "address": "i64", "initial": 0n }; + const memory = new WebAssembly.Memory(argument); + assert_throws_js(TypeError, () => memory.grow(value)); + }, `Out-of-range i64 argument: ${format_value(value)}`); +} + test(() => { const argument = { "initial": 0 }; const memory = new WebAssembly.Memory(argument); diff --git a/test/js-api/table/assertions.js b/test/js-api/table/assertions.js index 19cc5c3b92..cd403b4809 100644 --- a/test/js-api/table/assertions.js +++ b/test/js-api/table/assertions.js @@ -1,24 +1,28 @@ -function assert_equal_to_array(table, expected, message) { - assert_equals(table.length, expected.length, `${message}: length`); +function assert_equal_to_array(table, expected, message, address = "i32") { + function addr(i) { + return address === "i64" ? BigInt(i) : i; + } + + assert_equals(table.length, addr(expected.length), `${message}: length`); // The argument check in get() happens before the range check, and negative numbers // are illegal, hence will throw TypeError per spec. - assert_throws_js(TypeError, () => table.get(-1), `${message}: table.get(-1)`); + assert_throws_js(TypeError, () => table.get(addr(-1)), `${message}: table.get(-1)`); for (let i = 0; i < expected.length; ++i) { - assert_equals(table.get(i), expected[i], `${message}: table.get(${i} of ${expected.length})`); + assert_equals(table.get(addr(i)), expected[i], `${message}: table.get(${i} of ${expected.length})`); } - assert_throws_js(RangeError, () => table.get(expected.length), + assert_throws_js(RangeError, () => table.get(addr(expected.length)), `${message}: table.get(${expected.length} of ${expected.length})`); - assert_throws_js(RangeError, () => table.get(expected.length + 1), + assert_throws_js(RangeError, () => table.get(addr(expected.length + 1)), `${message}: table.get(${expected.length + 1} of ${expected.length})`); } -function assert_Table(actual, expected) { +function assert_Table(actual, expected, address = "i32") { assert_equals(Object.getPrototypeOf(actual), WebAssembly.Table.prototype, "prototype"); assert_true(Object.isExtensible(actual), "extensible"); assert_equals(actual.length, expected.length, "length"); - for (let i = 0; i < expected.length; ++i) { + for (let i = address === "i64" ? 0n : 0; i < expected.length; ++i) { assert_equals(actual.get(i), null, `actual.get(${i})`); } } diff --git a/test/js-api/table/constructor.any.js b/test/js-api/table/constructor.any.js index 6d38d04e4f..ebcd98b520 100644 --- a/test/js-api/table/constructor.any.js +++ b/test/js-api/table/constructor.any.js @@ -71,10 +71,29 @@ for (const value of outOfRangeValues) { }, `Out-of-range maximum value in descriptor: ${format_value(value)}`); } +const outOfRangeValuesI64 = [ + -1n, + 0x1_0000_0000_0000_0000n, +]; + +for (const value of outOfRangeValuesI64) { + test(() => { + assert_throws_js(TypeError, () => new WebAssembly.Table({ "element": "anyfunc", "address": "i64", "initial": value })); + }, `Out-of-range initial i64 value in descriptor: ${format_value(value)}`); + + test(() => { + assert_throws_js(TypeError, () => new WebAssembly.Table({ "element": "anyfunc", "address": "i64", "initial": 0n, "maximum": value })); + }, `Out-of-range maximum i64 value in descriptor: ${format_value(value)}`); +} + test(() => { assert_throws_js(RangeError, () => new WebAssembly.Table({ "element": "anyfunc", "initial": 10, "maximum": 9 })); }, "Initial value exceeds maximum"); +test(() => { + assert_throws_js(RangeError, () => new WebAssembly.Table({ "element": "anyfunc", "address": "i64", "initial": 10n, "maximum": 9n })); +}, "Initial value exceeds maximum (i64)"); + test(() => { const argument = { "element": "anyfunc", "initial": 0 }; const table = new WebAssembly.Table(argument); @@ -87,6 +106,18 @@ test(() => { assert_Table(table, { "length": 5 }); }, "Basic (non-zero)"); +test(() => { + const argument = { "element": "anyfunc", "address": "i64", "initial": 0n }; + const table = new WebAssembly.Table(argument); + assert_Table(table, { "length": 0n }, "i64"); +}, "Basic (zero, i64)"); + +test(() => { + const argument = { "element": "anyfunc", "address": "i64", "initial": 5n }; + const table = new WebAssembly.Table(argument); + assert_Table(table, { "length": 5n }, "i64"); +}, "Basic (non-zero, i64)"); + test(() => { const argument = { "element": "anyfunc", "initial": 0 }; const table = new WebAssembly.Table(argument, null, {}); @@ -157,11 +188,23 @@ test(() => { }, }; }, + + get address() { + order.push("address"); + return { + toString() { + order.push("address toString"); + return "i32"; + }, + }; + }, }); assert_array_equals(order, [ "element", "element toString", + "address", + "address toString", "initial", "initial valueOf", "maximum", @@ -206,3 +249,96 @@ test(() => { assert_throws_js(TypeError, () => new WebAssembly.Table(argument, "cannot be used as a wasm function")); assert_throws_js(TypeError, () => new WebAssembly.Table(argument, 37)); }, "initialize anyfunc table with a bad default value"); + +test(() => { + const argument = { "element": "anyfunc", "initial": 3, "address": "i32" }; + const table = new WebAssembly.Table(argument); + // Once this is merged with the type reflection proposal we should check the + // address type of `table`. + assert_equals(table.length, 3); +}, "Table with i32 address constructor"); + +test(() => { + const argument = { "element": "anyfunc", "initial": 3n, "address": "i64" }; + const table = new WebAssembly.Table(argument); + // Once this is merged with the type reflection proposal we should check the + // address type of `table`. + assert_equals(table.length, 3n); +}, "Table with i64 address constructor"); + +test(() => { + const argument = { "element": "anyfunc", "initial": "3", "address": "i32" }; + const table = new WebAssembly.Table(argument); + assert_equals(table.length, 3); +}, "Table with string value for initial"); + +test(() => { + const argument = { "element": "anyfunc", "initial": "3", "address": "i64" }; + const table = new WebAssembly.Table(argument); + assert_equals(table.length, 3n); +}, "Table with string value for initial (i64)"); + +test(() => { + const argument = { "element": "anyfunc", "initial": true, "address": "i32" }; + const table = new WebAssembly.Table(argument); + assert_equals(table.length, 1); +}, "Table with boolean value for initial"); + +test(() => { + const argument = { "element": "anyfunc", "initial": true, "address": "i64" }; + const table = new WebAssembly.Table(argument); + assert_equals(table.length, 1n); +}, "Table with boolean value for initial (i64)"); + +test(() => { + const argument = { "element": "anyfunc", "initial": 0, "maximum": "3", "address": "i32" }; + const table = new WebAssembly.Table(argument); + table.grow(3); + assert_equals(table.length, 3); +}, "Table with string value for maximum"); + +test(() => { + const argument = { "element": "anyfunc", "initial": 0n, "maximum": "3", "address": "i64" }; + const table = new WebAssembly.Table(argument); + table.grow(3n); + assert_equals(table.length, 3n); +}, "Table with string value for maximum (i64)"); + +test(() => { + const argument = { "element": "anyfunc", "initial": 0, "maximum": true, "address": "i32" }; + const table = new WebAssembly.Table(argument); + table.grow(1); + assert_equals(table.length, 1); +}, "Table with boolean value for maximum"); + +test(() => { + const argument = { "element": "anyfunc", "initial": 0n, "maximum": true, "address": "i64" }; + const table = new WebAssembly.Table(argument); + table.grow(1n); + assert_equals(table.length, 1n); +}, "Table with boolean value for maximum (i64)"); + +test(() => { + const argument = { "element": "anyfunc", "initial": 3, "address": "unknown" }; + assert_throws_js(TypeError, () => new WebAssembly.Table(argument)); +}, "Unknown table address"); + +test(() => { + const argument = { "element": "i32", "initial": 3n }; + assert_throws_js(TypeError, () => new WebAssembly.Table(argument)); +}, "initialize table with a wrong initial type"); + +test(() => { + const argument = { "element": "i32", "initial": 3, "maximum": 10n }; + assert_throws_js(TypeError, () => new WebAssembly.Table(argument)); +}, "initialize table with a wrong maximum type"); + +test(() => { + const argument = { "element": "i32", "initial": 3 }; + assert_throws_js(TypeError, () => new WebAssembly.Table(argument)); +}, "initialize table with a wrong initial type (i64)"); + +test(() => { + const argument = { "element": "i32", "initial": 3n, "maximum": 10 }; + assert_throws_js(TypeError, () => new WebAssembly.Table(argument)); +}, "initialize table with a wrong maximum type (i64)"); diff --git a/test/js-api/table/get-set.any.js b/test/js-api/table/get-set.any.js index 9301057a53..c656cd29c4 100644 --- a/test/js-api/table/get-set.any.js +++ b/test/js-api/table/get-set.any.js @@ -100,6 +100,23 @@ test(() => { assert_equal_to_array(table, [null, null, fn2, null, fn]); }, "Basic"); +test(() => { + const argument = { "element": "anyfunc", "address": "i64", "initial": 5n }; + const table = new WebAssembly.Table(argument); + assert_equal_to_array(table, [null, null, null, null, null], undefined, "i64"); + + const {fn, fn2} = functions; + + assert_equals(table.set(0n, fn), undefined, "set() returns undefined."); + table.set(2n, fn2); + table.set(4n, fn); + + assert_equal_to_array(table, [fn, null, fn2, null, fn], undefined, "i64"); + + table.set(0n, null); + assert_equal_to_array(table, [null, null, fn2, null, fn], undefined, "i64"); +}, "Basic (i64)"); + test(() => { const argument = { "element": "anyfunc", "initial": 5 }; const table = new WebAssembly.Table(argument); @@ -118,6 +135,24 @@ test(() => { assert_equal_to_array(table, [fn, null, fn2, null, fn, null, null, null, null]); }, "Growing"); +test(() => { + const argument = { "element": "anyfunc", "address": "i64", "initial": 5n }; + const table = new WebAssembly.Table(argument); + assert_equal_to_array(table, [null, null, null, null, null], undefined, "i64"); + + const {fn, fn2} = functions; + + table.set(0n, fn); + table.set(2n, fn2); + table.set(4n, fn); + + assert_equal_to_array(table, [fn, null, fn2, null, fn], undefined, "i64"); + + table.grow(4n); + + assert_equal_to_array(table, [fn, null, fn2, null, fn, null, null, null, null], undefined, "i64"); +}, "Growing (i64)"); + test(() => { const argument = { "element": "anyfunc", "initial": 5 }; const table = new WebAssembly.Table(argument); @@ -132,6 +167,20 @@ test(() => { assert_equal_to_array(table, [null, null, null, null, null]); }, "Setting out-of-bounds"); +test(() => { + const argument = { "element": "anyfunc", "address": "i64", "initial": 5n }; + const table = new WebAssembly.Table(argument); + assert_equal_to_array(table, [null, null, null, null, null], undefined, "i64"); + + const {fn} = functions; + + // -1 is the wrong type hence the type check on entry gets this + // before the range check does. + assert_throws_js(TypeError, () => table.set(-1n, fn)); + assert_throws_js(RangeError, () => table.set(5n, fn)); + assert_equal_to_array(table, [null, null, null, null, null], undefined, "i64"); +}, "Setting out-of-bounds (i64)"); + test(() => { const argument = { "element": "anyfunc", "initial": 1 }; const table = new WebAssembly.Table(argument); @@ -200,6 +249,26 @@ for (const value of outOfRangeValues) { }, `Setting out-of-range argument: ${format_value(value)}`); } +const outOfRangeValuesI64 = [ + -1n, + 0x10000000000000000n, + "0x10000000000000000", +]; + +for (const value of outOfRangeValuesI64) { + test(() => { + const argument = { "element": "anyfunc", "address": "i64", "initial": 1n }; + const table = new WebAssembly.Table(argument); + assert_throws_js(TypeError, () => table.get(value)); + }, `Getting out-of-range argument (i64): ${format_value(value)}`); + + test(() => { + const argument = { "element": "anyfunc", "address": "i64", "initial": 1n }; + const table = new WebAssembly.Table(argument); + assert_throws_js(TypeError, () => table.set(value, null)); + }, `Setting out-of-range argument (i64): ${format_value(value)}`); +} + test(() => { const argument = { "element": "anyfunc", "initial": 1 }; const table = new WebAssembly.Table(argument); diff --git a/test/js-api/table/grow.any.js b/test/js-api/table/grow.any.js index 520d24bf4b..55226cbdb9 100644 --- a/test/js-api/table/grow.any.js +++ b/test/js-api/table/grow.any.js @@ -45,7 +45,17 @@ test(() => { const result = table.grow(3); assert_equals(result, 5); assert_equal_to_array(table, nulls(8), "after"); -}, "Basic"); +}, "Basic i32"); + +test(() => { + const argument = { "element": "anyfunc", "address": "i64", "initial": 5n }; + const table = new WebAssembly.Table(argument); + assert_equal_to_array(table, nulls(5), "before", "i64"); + + const result = table.grow(3n); + assert_equals(result, 5n); + assert_equal_to_array(table, nulls(8), "after", "i64"); +}, "Basic i64"); test(() => { const argument = { "element": "anyfunc", "initial": 3, "maximum": 5 }; @@ -55,7 +65,17 @@ test(() => { const result = table.grow(2); assert_equals(result, 3); assert_equal_to_array(table, nulls(5), "after"); -}, "Reached maximum"); +}, "Reached maximum (i32)"); + +test(() => { + const argument = { "element": "anyfunc", "address": "i64", "initial": 3n, "maximum": 5n }; + const table = new WebAssembly.Table(argument); + assert_equal_to_array(table, nulls(3), "before", "i64"); + + const result = table.grow(2n); + assert_equals(result, 3n); + assert_equal_to_array(table, nulls(5), "after", "i64"); +}, "Reached maximum (i64)"); test(() => { const argument = { "element": "anyfunc", "initial": 2, "maximum": 5 }; @@ -64,7 +84,16 @@ test(() => { assert_throws_js(RangeError, () => table.grow(4)); assert_equal_to_array(table, nulls(2), "after"); -}, "Exceeded maximum"); +}, "Exceeded maximum (i32)"); + +test(() => { + const argument = { "element": "anyfunc", "address": "i64", "initial": 2n, "maximum": 5n }; + const table = new WebAssembly.Table(argument); + assert_equal_to_array(table, nulls(2), "before", "i64"); + + assert_throws_js(RangeError, () => table.grow(4n)); + assert_equal_to_array(table, nulls(2), "after", "i64"); +}, "Exceeded maximum (i64)"); const outOfRangeValues = [ undefined, @@ -86,6 +115,20 @@ for (const value of outOfRangeValues) { }, `Out-of-range argument: ${format_value(value)}`); } +const outOfRangeValuesI64 = [ + -1n, + 0x10000000000000000n, + "0x10000000000000000", +]; + +for (const value of outOfRangeValuesI64) { + test(() => { + const argument = { "element": "anyfunc", "address": "i64", "initial": 1n }; + const table = new WebAssembly.Table(argument); + assert_throws_js(TypeError, () => table.grow(value)); + }, `Out-of-range i64 argument: ${format_value(value)}`); +} + test(() => { const argument = { "element": "anyfunc", "initial": 5 }; const table = new WebAssembly.Table(argument); diff --git a/test/meta/common.js b/test/meta/common.js index 9a277e44f2..493da2d47e 100644 --- a/test/meta/common.js +++ b/test/meta/common.js @@ -7,23 +7,23 @@ function print_origin(origin) { print(";;"); } -function checkRangeCode() { +function checkRangeCode(memtype) { return ` - (func (export "checkRange") (param $from i32) (param $to i32) (param $expected i32) (result i32) + (func (export "checkRange") (param $from ${memtype}) (param $to ${memtype}) (param $expected i32) (result ${memtype}) (loop $cont - (if (i32.eq (local.get $from) (local.get $to)) + (if (${memtype}.eq (local.get $from) (local.get $to)) (then - (return (i32.const -1)))) + (return (${memtype}.const -1)))) (if (i32.eq (i32.load8_u (local.get $from)) (local.get $expected)) (then - (local.set $from (i32.add (local.get $from) (i32.const 1))) + (local.set $from (${memtype}.add (local.get $from) (${memtype}.const 1))) (br $cont)))) (return (local.get $from))) `; } -function checkRange(from, to, expected) { +function checkRange(memtype, from, to, expected) { print( -`(assert_return (invoke "checkRange" (i32.const ${from}) (i32.const ${to}) (i32.const ${expected})) - (i32.const -1))`); +`(assert_return (invoke "checkRange" (${memtype}.const ${from}) (${memtype}.const ${to}) (i32.const ${expected})) + (${memtype}.const -1))`); } diff --git a/test/meta/generate_memory_copy.js b/test/meta/generate_memory_copy.js index 36751b86af..ee47143542 100644 --- a/test/meta/generate_memory_copy.js +++ b/test/meta/generate_memory_copy.js @@ -3,96 +3,100 @@ print_origin("generate_memory_copy.js"); -// In-bounds tests. +for ( const memtype of ['i32', 'i64'] ) { -function mem_test(instruction, expected_result_vector) { - print( + const decltype = memtype == 'i64' ? ' i64' : ''; + + // In-bounds tests. + + function mem_test(instruction, expected_result_vector) { + print( ` (module - (memory (export "memory0") 1 1) - (data (i32.const 2) "\\03\\01\\04\\01") - (data (i32.const 12) "\\07\\05\\02\\03\\06") + (memory (export "memory0")${decltype} 1 1) + (data (${memtype}.const 2) "\\03\\01\\04\\01") + (data (${memtype}.const 12) "\\07\\05\\02\\03\\06") (func (export "test") ${instruction}) - (func (export "load8_u") (param i32) (result i32) + (func (export "load8_u") (param ${memtype}) (result i32) (i32.load8_u (local.get 0)))) (invoke "test") `); - for (let i = 0; i < expected_result_vector.length; i++) { - print(`(assert_return (invoke "load8_u" (i32.const ${i})) (i32.const ${expected_result_vector[i]}))`); - } -} - -const e = 0; - -// This just gives the initial state of the memory, with its active -// initialisers applied. -mem_test("(nop)", - [e,e,3,1,4, 1,e,e,e,e, e,e,7,5,2, 3,6,e,e,e, e,e,e,e,e, e,e,e,e,e]); - -// Copy non-zero over non-zero -mem_test("(memory.copy (i32.const 13) (i32.const 2) (i32.const 3))", - [e,e,3,1,4, 1,e,e,e,e, e,e,7,3,1, 4,6,e,e,e, e,e,e,e,e, e,e,e,e,e]); - -// Copy non-zero over zero -mem_test("(memory.copy (i32.const 25) (i32.const 15) (i32.const 2))", - [e,e,3,1,4, 1,e,e,e,e, e,e,7,5,2, 3,6,e,e,e, e,e,e,e,e, 3,6,e,e,e]); - -// Copy zero over non-zero -mem_test("(memory.copy (i32.const 13) (i32.const 25) (i32.const 3))", - [e,e,3,1,4, 1,e,e,e,e, e,e,7,e,e, e,6,e,e,e, e,e,e,e,e, e,e,e,e,e]); - -// Copy zero over zero -mem_test("(memory.copy (i32.const 20) (i32.const 22) (i32.const 4))", - [e,e,3,1,4, 1,e,e,e,e, e,e,7,5,2, 3,6,e,e,e, e,e,e,e,e, e,e,e,e,e]); - -// Copy zero and non-zero entries, non overlapping -mem_test("(memory.copy (i32.const 25) (i32.const 1) (i32.const 3))", - [e,e,3,1,4, 1,e,e,e,e, e,e,7,5,2, 3,6,e,e,e, e,e,e,e,e, e,3,1,e,e]); - -// Copy zero and non-zero entries, overlapping, backwards -mem_test("(memory.copy (i32.const 10) (i32.const 12) (i32.const 7))", - [e,e,3,1,4, 1,e,e,e,e, 7,5,2,3,6, e,e,e,e,e, e,e,e,e,e, e,e,e,e,e]); - -// Copy zero and non-zero entries, overlapping, forwards -mem_test("(memory.copy (i32.const 12) (i32.const 10) (i32.const 7))", - [e,e,3,1,4, 1,e,e,e,e, e,e,e,e,7, 5,2,3,6,e, e,e,e,e,e, e,e,e,e,e]); - -// Out-of-bounds tests. -// -// The operation is out of bounds of the memory for the source or target, but -// must perform the operation up to the appropriate bound. Major cases: -// -// - non-overlapping regions -// - overlapping regions with src >= dest -// - overlapping regions with src == dest -// - overlapping regions with src < dest -// - arithmetic overflow on src addresses -// - arithmetic overflow on target addresses -// -// for each of those, -// -// - src address oob -// - target address oob -// - both oob - -function initializers(count, startingAt) { - let s = ""; - for ( let i=0, j=startingAt; i < count; i++, j++ ) - s += "\\" + (i + 256).toString(16).substring(1); - return s; -} - -function mem_copy(min, max, shared, srcOffs, targetOffs, len) { - let copyDown = srcOffs < targetOffs; - let memLength = min * PAGESIZE; - let targetAvail = memLength - targetOffs; - let srcAvail = memLength - srcOffs; - let targetLim = targetOffs + Math.min(len, targetAvail, srcAvail); - let srcLim = srcOffs + Math.min(len, targetAvail, srcAvail); - - print( + for (let i = 0; i < expected_result_vector.length; i++) { + print(`(assert_return (invoke "load8_u" (${memtype}.const ${i})) (i32.const ${expected_result_vector[i]}))`); + } + } + + const e = 0; + + // This just gives the initial state of the memory, with its active + // initialisers applied. + mem_test("(nop)", + [e,e,3,1,4, 1,e,e,e,e, e,e,7,5,2, 3,6,e,e,e, e,e,e,e,e, e,e,e,e,e]); + + // Copy non-zero over non-zero + mem_test(`(memory.copy (${memtype}.const 13) (${memtype}.const 2) (${memtype}.const 3))`, + [e,e,3,1,4, 1,e,e,e,e, e,e,7,3,1, 4,6,e,e,e, e,e,e,e,e, e,e,e,e,e]); + + // Copy non-zero over zero + mem_test(`(memory.copy (${memtype}.const 25) (${memtype}.const 15) (${memtype}.const 2))`, + [e,e,3,1,4, 1,e,e,e,e, e,e,7,5,2, 3,6,e,e,e, e,e,e,e,e, 3,6,e,e,e]); + + // Copy zero over non-zero + mem_test(`(memory.copy (${memtype}.const 13) (${memtype}.const 25) (${memtype}.const 3))`, + [e,e,3,1,4, 1,e,e,e,e, e,e,7,e,e, e,6,e,e,e, e,e,e,e,e, e,e,e,e,e]); + + // Copy zero over zero + mem_test(`(memory.copy (${memtype}.const 20) (${memtype}.const 22) (${memtype}.const 4))`, + [e,e,3,1,4, 1,e,e,e,e, e,e,7,5,2, 3,6,e,e,e, e,e,e,e,e, e,e,e,e,e]); + + // Copy zero and non-zero entries, non overlapping + mem_test(`(memory.copy (${memtype}.const 25) (${memtype}.const 1) (${memtype}.const 3))`, + [e,e,3,1,4, 1,e,e,e,e, e,e,7,5,2, 3,6,e,e,e, e,e,e,e,e, e,3,1,e,e]); + + // Copy zero and non-zero entries, overlapping, backwards + mem_test(`(memory.copy (${memtype}.const 10) (${memtype}.const 12) (${memtype}.const 7))`, + [e,e,3,1,4, 1,e,e,e,e, 7,5,2,3,6, e,e,e,e,e, e,e,e,e,e, e,e,e,e,e]); + + // Copy zero and non-zero entries, overlapping, forwards + mem_test(`(memory.copy (${memtype}.const 12) (${memtype}.const 10) (${memtype}.const 7))`, + [e,e,3,1,4, 1,e,e,e,e, e,e,e,e,7, 5,2,3,6,e, e,e,e,e,e, e,e,e,e,e]); + + // Out-of-bounds tests. + // + // The operation is out of bounds of the memory for the source or target, but + // must perform the operation up to the appropriate bound. Major cases: + // + // - non-overlapping regions + // - overlapping regions with src >= dest + // - overlapping regions with src == dest + // - overlapping regions with src < dest + // - arithmetic overflow on src addresses + // - arithmetic overflow on target addresses + // + // for each of those, + // + // - src address oob + // - target address oob + // - both oob + + function initializers(count, startingAt) { + let s = ""; + for ( let i=0, j=startingAt; i < count; i++, j++ ) + s += "\\" + (i + 256).toString(16).substring(1); + return s; + } + + function mem_copy(min, max, shared, srcOffs, targetOffs, len) { + let copyDown = srcOffs < targetOffs; + let memLength = min * PAGESIZE; + let targetAvail = memLength - targetOffs; + let srcAvail = memLength - srcOffs; + let targetLim = targetOffs + Math.min(len, targetAvail, srcAvail); + let srcLim = srcOffs + Math.min(len, targetAvail, srcAvail); + + print( ` (module (memory (export "mem") ${min} ${max} ${shared}) @@ -106,663 +110,664 @@ function mem_copy(min, max, shared, srcOffs, targetOffs, len) { "out of bounds memory access") `); - let immediateOOB = copyDown && (srcOffs + len > memLength || targetOffs + len > memLength); - - var s = 0; - var i = 0; - let k = 0; - for (i=0; i < memLength; i++ ) { - if (i >= srcOffs && i < srcLim) { - print(`(assert_return (invoke "load8_u" (i32.const ${i})) (i32.const ${(s++) & 0xFF}))`); - continue; - } - // Only spot-check for zero, or we'll be here all night. - if (++k == 199) { - print(`(assert_return (invoke "load8_u" (i32.const ${i})) (i32.const 0))`); - k = 0; - } - } -} - -// OOB target address, nonoverlapping -mem_copy(1, 1, "", 0, PAGESIZE-20, 40); -mem_copy(1, 1, "", 0, PAGESIZE-21, 39); -if (WITH_SHARED_MEMORY) { - mem_copy(2, 4, "shared", 0, 2*PAGESIZE-20, 40); - mem_copy(2, 4, "shared", 0, 2*PAGESIZE-21, 39); -} - -// OOB source address, nonoverlapping -mem_copy(1, 1, "", PAGESIZE-20, 0, 40); -mem_copy(1, 1, "", PAGESIZE-21, 0, 39); -if (WITH_SHARED_MEMORY) { - mem_copy(2, 4, "shared", 2*PAGESIZE-20, 0, 40); - mem_copy(2, 4, "shared", 2*PAGESIZE-21, 0, 39); -} - -// OOB target address, overlapping, src < target -mem_copy(1, 1, "", PAGESIZE-50, PAGESIZE-20, 40); - -// OOB source address, overlapping, target < src -mem_copy(1, 1, "", PAGESIZE-20, PAGESIZE-50, 40); - -// OOB both, overlapping, including target == src -mem_copy(1, 1, "", PAGESIZE-30, PAGESIZE-20, 40); -mem_copy(1, 1, "", PAGESIZE-20, PAGESIZE-30, 40); -mem_copy(1, 1, "", PAGESIZE-20, PAGESIZE-20, 40); - -// Arithmetic overflow on source address. -mem_copy(1, "", "", PAGESIZE-20, 0, 0xFFFFF000); - -// Arithmetic overflow on target adddress is an overlapping case. -mem_copy(1, 1, "", PAGESIZE-0x1000, PAGESIZE-20, 0xFFFFFF00); - -// Sundry compilation failures. - -// Module doesn't have a memory. -print( + let immediateOOB = copyDown && (srcOffs + len > memLength || targetOffs + len > memLength); + + var s = 0; + var i = 0; + let k = 0; + for (i=0; i < memLength; i++ ) { + if (i >= srcOffs && i < srcLim) { + print(`(assert_return (invoke "load8_u" (i32.const ${i})) (i32.const ${(s++) & 0xFF}))`); + continue; + } + // Only spot-check for zero, or we'll be here all night. + if (++k == 199) { + print(`(assert_return (invoke "load8_u" (i32.const ${i})) (i32.const 0))`); + k = 0; + } + } + } + + // OOB target address, nonoverlapping + mem_copy(1, 1, "", 0, PAGESIZE-20, 40); + mem_copy(1, 1, "", 0, PAGESIZE-21, 39); + if (WITH_SHARED_MEMORY) { + mem_copy(2, 4, "shared", 0, 2*PAGESIZE-20, 40); + mem_copy(2, 4, "shared", 0, 2*PAGESIZE-21, 39); + } + + // OOB source address, nonoverlapping + mem_copy(1, 1, "", PAGESIZE-20, 0, 40); + mem_copy(1, 1, "", PAGESIZE-21, 0, 39); + if (WITH_SHARED_MEMORY) { + mem_copy(2, 4, "shared", 2*PAGESIZE-20, 0, 40); + mem_copy(2, 4, "shared", 2*PAGESIZE-21, 0, 39); + } + + // OOB target address, overlapping, src < target + mem_copy(1, 1, "", PAGESIZE-50, PAGESIZE-20, 40); + + // OOB source address, overlapping, target < src + mem_copy(1, 1, "", PAGESIZE-20, PAGESIZE-50, 40); + + // OOB both, overlapping, including target == src + mem_copy(1, 1, "", PAGESIZE-30, PAGESIZE-20, 40); + mem_copy(1, 1, "", PAGESIZE-20, PAGESIZE-30, 40); + mem_copy(1, 1, "", PAGESIZE-20, PAGESIZE-20, 40); + + // Arithmetic overflow on source address. + mem_copy(1, "", "", PAGESIZE-20, 0, 0xFFFFF000); + + // Arithmetic overflow on target adddress is an overlapping case. + mem_copy(1, 1, "", PAGESIZE-0x1000, PAGESIZE-20, 0xFFFFFF00); + + // Sundry compilation failures. + + // Module doesn't have a memory. + print( ` (assert_invalid (module (func (export "testfn") - (memory.copy (i32.const 10) (i32.const 20) (i32.const 30)))) + (memory.copy (${memtype}.const 10) (${memtype}.const 20) (${memtype}.const 30)))) "unknown memory 0") `); -// Invalid argument types. TODO: We can add anyref, funcref, etc here. -{ - const tys = ['i32', 'f32', 'i64', 'f64']; - for (let ty1 of tys) { - for (let ty2 of tys) { - for (let ty3 of tys) { - if (ty1 == 'i32' && ty2 == 'i32' && ty3 == 'i32') - continue; // this is the only valid case - print( + // Invalid argument types. TODO: We can add anyref, funcref, etc here. + { + const tys = ['i32', 'f32', 'i64', 'f64']; + for (let ty1 of tys) { + for (let ty2 of tys) { + for (let ty3 of tys) { + if (ty1 == memtype && ty2 == memtype && ty3 == memtype) + continue; // this is the only valid case + print( `(assert_invalid (module - (memory 1 1) + (memory${decltype} 1 1) (func (export "testfn") (memory.copy (${ty1}.const 10) (${ty2}.const 20) (${ty3}.const 30)))) "type mismatch") `); - }}} -} + }}} + } -// Both ranges valid. Copy 5 bytes backwards by 1 (overlapping). -// result = 0x00--(09) 0x55--(11) 0x00--(pagesize-20) -print( + // Both ranges valid. Copy 5 bytes backwards by 1 (overlapping). + // result = 0x00--(09) 0x55--(11) 0x00--(pagesize-20) + print( ` (module - (memory 1 1) + (memory${decltype} 1 1) (func (export "test") - (memory.fill (i32.const 10) (i32.const 0x55) (i32.const 10)) - (memory.copy (i32.const 9) (i32.const 10) (i32.const 5))) - ${checkRangeCode()}) + (memory.fill (${memtype}.const 10) (i32.const 0x55) (${memtype}.const 10)) + (memory.copy (${memtype}.const 9) (${memtype}.const 10) (${memtype}.const 5))) + ${checkRangeCode(memtype)}) (invoke "test") `); -checkRange(0, 0+9, 0x00); -checkRange(9, 9+11, 0x55); -checkRange(9+11, 0x10000, 0x00); + checkRange(memtype, 0, 0+9, 0x00); + checkRange(memtype, 9, 9+11, 0x55); + checkRange(memtype, 9+11, 0x10000, 0x00); -// Both ranges valid. Copy 5 bytes forwards by 1 (overlapping). -// result = 0x00--(10) 0x55--(11) 0x00--(pagesize-19) -print( + // Both ranges valid. Copy 5 bytes forwards by 1 (overlapping). + // result = 0x00--(10) 0x55--(11) 0x00--(pagesize-19) + print( ` (module - (memory 1 1) + (memory${decltype} 1 1) (func (export "test") - (memory.fill (i32.const 10) (i32.const 0x55) (i32.const 10)) - (memory.copy (i32.const 16) (i32.const 15) (i32.const 5))) - ${checkRangeCode()}) + (memory.fill (${memtype}.const 10) (i32.const 0x55) (${memtype}.const 10)) + (memory.copy (${memtype}.const 16) (${memtype}.const 15) (${memtype}.const 5))) + ${checkRangeCode(memtype)}) (invoke "test") `); -checkRange(0, 0+10, 0x00); -checkRange(10, 10+11, 0x55); -checkRange(10+11, 0x10000, 0x00); + checkRange(memtype, 0, 0+10, 0x00); + checkRange(memtype, 10, 10+11, 0x55); + checkRange(memtype, 10+11, 0x10000, 0x00); -// Destination range invalid -print( + // Destination range invalid + print( ` (module - (memory 1 1) + (memory${decltype} 1 1) (func (export "test") - (memory.copy (i32.const 0xFF00) (i32.const 0x8000) (i32.const 257)))) + (memory.copy (${memtype}.const 0xFF00) (${memtype}.const 0x8000) (${memtype}.const 257)))) (assert_trap (invoke "test") "out of bounds memory access") `); -// Destination wraparound the end of 32-bit offset space + // Destination wraparound the end of 32-bit offset space print( `(module - (memory 1 1) + (memory${decltype} 1 1) (func (export "test") - (memory.copy (i32.const 0xFFFFFF00) (i32.const 0x4000) (i32.const 257)))) + (memory.copy (${memtype}.const 0xFFFFFF00) (${memtype}.const 0x4000) (${memtype}.const 257)))) (assert_trap (invoke "test") "out of bounds memory access") `); -// Source range invalid + // Source range invalid print( `(module - (memory 1 1) + (memory${decltype} 1 1) (func (export "test") - (memory.copy (i32.const 0x8000) (i32.const 0xFF00) (i32.const 257)))) + (memory.copy (${memtype}.const 0x8000) (${memtype}.const 0xFF00) (${memtype}.const 257)))) (assert_trap (invoke "test") "out of bounds memory access") `); -// Source wraparound the end of 32-bit offset space + // Source wraparound the end of 32-bit offset space print( `(module - (memory 1 1) + (memory${decltype} 1 1) (func (export "test") - (memory.copy (i32.const 0x4000) (i32.const 0xFFFFFF00) (i32.const 257)))) + (memory.copy (${memtype}.const 0x4000) (${memtype}.const 0xFFFFFF00) (${memtype}.const 257)))) (assert_trap (invoke "test") "out of bounds memory access") `); -// Zero len with both offsets in-bounds is a no-op + // Zero len with both offsets in-bounds is a no-op print( `(module - (memory 1 1) + (memory${decltype} 1 1) (func (export "test") - (memory.fill (i32.const 0x0000) (i32.const 0x55) (i32.const 0x8000)) - (memory.fill (i32.const 0x8000) (i32.const 0xAA) (i32.const 0x8000)) - (memory.copy (i32.const 0x9000) (i32.const 0x7000) (i32.const 0))) - ${checkRangeCode()}) + (memory.fill (${memtype}.const 0x0000) (i32.const 0x55) (${memtype}.const 0x8000)) + (memory.fill (${memtype}.const 0x8000) (i32.const 0xAA) (${memtype}.const 0x8000)) + (memory.copy (${memtype}.const 0x9000) (${memtype}.const 0x7000) (${memtype}.const 0))) + ${checkRangeCode(memtype)}) (invoke "test") `); -checkRange(0x00000, 0x08000, 0x55); -checkRange(0x08000, 0x10000, 0xAA); + checkRange(memtype, 0x00000, 0x08000, 0x55); + checkRange(memtype, 0x08000, 0x10000, 0xAA); -// Zero len with dest offset out-of-bounds at the end of memory is allowed -print( + // Zero len with dest offset out-of-bounds at the end of memory is allowed + print( `(module - (memory 1 1) + (memory${decltype} 1 1) (func (export "test") - (memory.copy (i32.const 0x10000) (i32.const 0x7000) (i32.const 0)))) + (memory.copy (${memtype}.const 0x10000) (${memtype}.const 0x7000) (${memtype}.const 0)))) (invoke "test") `); -// Zero len with dest offset out-of-bounds past the end of memory is not allowed -print( + // Zero len with dest offset out-of-bounds past the end of memory is not allowed + print( `(module - (memory 1 1) + (memory${decltype} 1 1) (func (export "test") - (memory.copy (i32.const 0x20000) (i32.const 0x7000) (i32.const 0)))) + (memory.copy (${memtype}.const 0x20000) (${memtype}.const 0x7000) (${memtype}.const 0)))) (assert_trap (invoke "test") "out of bounds memory access") `); -// Zero len with src offset out-of-bounds at the end of memory is allowed -print( + // Zero len with src offset out-of-bounds at the end of memory is allowed + print( `(module - (memory 1 1) + (memory${decltype} 1 1) (func (export "test") - (memory.copy (i32.const 0x9000) (i32.const 0x10000) (i32.const 0)))) + (memory.copy (${memtype}.const 0x9000) (${memtype}.const 0x10000) (${memtype}.const 0)))) (invoke "test") `); -// Zero len with src offset out-of-bounds past the end of memory is not allowed -print( + // Zero len with src offset out-of-bounds past the end of memory is not allowed + print( `(module - (memory 1 1) + (memory${decltype} 1 1) (func (export "test") - (memory.copy (i32.const 0x9000) (i32.const 0x20000) (i32.const 0)))) + (memory.copy (${memtype}.const 0x9000) (${memtype}.const 0x20000) (${memtype}.const 0)))) (assert_trap (invoke "test") "out of bounds memory access") `); -// Zero len with both dest and src offsets out-of-bounds at the end of memory is allowed -print( + // Zero len with both dest and src offsets out-of-bounds at the end of memory is allowed + print( `(module - (memory 1 1) + (memory${decltype} 1 1) (func (export "test") - (memory.copy (i32.const 0x10000) (i32.const 0x10000) (i32.const 0)))) + (memory.copy (${memtype}.const 0x10000) (${memtype}.const 0x10000) (${memtype}.const 0)))) (invoke "test") `); -// Zero len with both dest and src offsets out-of-bounds past the end of memory is not allowed -print( + // Zero len with both dest and src offsets out-of-bounds past the end of memory is not allowed + print( `(module - (memory 1 1) + (memory${decltype} 1 1) (func (export "test") - (memory.copy (i32.const 0x20000) (i32.const 0x20000) (i32.const 0)))) + (memory.copy (${memtype}.const 0x20000) (${memtype}.const 0x20000) (${memtype}.const 0)))) (assert_trap (invoke "test") "out of bounds memory access") `); -// 100 random fills followed by 100 random copies, in a single-page buffer, -// followed by verification of the (now heavily mashed-around) buffer. -print( + // 100 random fills followed by 100 random copies, in a single-page buffer, + // followed by verification of the (now heavily mashed-around) buffer. + print( `(module - (memory 1 1) + (memory${decltype} 1 1) (func (export "test") - (memory.fill (i32.const 17767) (i32.const 1) (i32.const 1344)) - (memory.fill (i32.const 39017) (i32.const 2) (i32.const 1055)) - (memory.fill (i32.const 56401) (i32.const 3) (i32.const 988)) - (memory.fill (i32.const 37962) (i32.const 4) (i32.const 322)) - (memory.fill (i32.const 7977) (i32.const 5) (i32.const 1994)) - (memory.fill (i32.const 22714) (i32.const 6) (i32.const 3036)) - (memory.fill (i32.const 16882) (i32.const 7) (i32.const 2372)) - (memory.fill (i32.const 43491) (i32.const 8) (i32.const 835)) - (memory.fill (i32.const 124) (i32.const 9) (i32.const 1393)) - (memory.fill (i32.const 2132) (i32.const 10) (i32.const 2758)) - (memory.fill (i32.const 8987) (i32.const 11) (i32.const 3098)) - (memory.fill (i32.const 52711) (i32.const 12) (i32.const 741)) - (memory.fill (i32.const 3958) (i32.const 13) (i32.const 2823)) - (memory.fill (i32.const 49715) (i32.const 14) (i32.const 1280)) - (memory.fill (i32.const 50377) (i32.const 15) (i32.const 1466)) - (memory.fill (i32.const 20493) (i32.const 16) (i32.const 3158)) - (memory.fill (i32.const 47665) (i32.const 17) (i32.const 544)) - (memory.fill (i32.const 12451) (i32.const 18) (i32.const 2669)) - (memory.fill (i32.const 24869) (i32.const 19) (i32.const 2651)) - (memory.fill (i32.const 45317) (i32.const 20) (i32.const 1570)) - (memory.fill (i32.const 43096) (i32.const 21) (i32.const 1691)) - (memory.fill (i32.const 33886) (i32.const 22) (i32.const 646)) - (memory.fill (i32.const 48555) (i32.const 23) (i32.const 1858)) - (memory.fill (i32.const 53453) (i32.const 24) (i32.const 2657)) - (memory.fill (i32.const 30363) (i32.const 25) (i32.const 981)) - (memory.fill (i32.const 9300) (i32.const 26) (i32.const 1807)) - (memory.fill (i32.const 50190) (i32.const 27) (i32.const 487)) - (memory.fill (i32.const 62753) (i32.const 28) (i32.const 530)) - (memory.fill (i32.const 36316) (i32.const 29) (i32.const 943)) - (memory.fill (i32.const 6768) (i32.const 30) (i32.const 381)) - (memory.fill (i32.const 51262) (i32.const 31) (i32.const 3089)) - (memory.fill (i32.const 49729) (i32.const 32) (i32.const 658)) - (memory.fill (i32.const 44540) (i32.const 33) (i32.const 1702)) - (memory.fill (i32.const 33342) (i32.const 34) (i32.const 1092)) - (memory.fill (i32.const 50814) (i32.const 35) (i32.const 1410)) - (memory.fill (i32.const 47594) (i32.const 36) (i32.const 2204)) - (memory.fill (i32.const 54123) (i32.const 37) (i32.const 2394)) - (memory.fill (i32.const 55183) (i32.const 38) (i32.const 250)) - (memory.fill (i32.const 22620) (i32.const 39) (i32.const 2097)) - (memory.fill (i32.const 17132) (i32.const 40) (i32.const 3264)) - (memory.fill (i32.const 54331) (i32.const 41) (i32.const 3299)) - (memory.fill (i32.const 39474) (i32.const 42) (i32.const 2796)) - (memory.fill (i32.const 36156) (i32.const 43) (i32.const 2070)) - (memory.fill (i32.const 35308) (i32.const 44) (i32.const 2763)) - (memory.fill (i32.const 32731) (i32.const 45) (i32.const 312)) - (memory.fill (i32.const 63746) (i32.const 46) (i32.const 192)) - (memory.fill (i32.const 30974) (i32.const 47) (i32.const 596)) - (memory.fill (i32.const 16635) (i32.const 48) (i32.const 501)) - (memory.fill (i32.const 57002) (i32.const 49) (i32.const 686)) - (memory.fill (i32.const 34299) (i32.const 50) (i32.const 385)) - (memory.fill (i32.const 60881) (i32.const 51) (i32.const 903)) - (memory.fill (i32.const 61445) (i32.const 52) (i32.const 2390)) - (memory.fill (i32.const 46972) (i32.const 53) (i32.const 1441)) - (memory.fill (i32.const 25973) (i32.const 54) (i32.const 3162)) - (memory.fill (i32.const 5566) (i32.const 55) (i32.const 2135)) - (memory.fill (i32.const 35977) (i32.const 56) (i32.const 519)) - (memory.fill (i32.const 44892) (i32.const 57) (i32.const 3280)) - (memory.fill (i32.const 46760) (i32.const 58) (i32.const 1678)) - (memory.fill (i32.const 46607) (i32.const 59) (i32.const 3168)) - (memory.fill (i32.const 22449) (i32.const 60) (i32.const 1441)) - (memory.fill (i32.const 58609) (i32.const 61) (i32.const 663)) - (memory.fill (i32.const 32261) (i32.const 62) (i32.const 1671)) - (memory.fill (i32.const 3063) (i32.const 63) (i32.const 721)) - (memory.fill (i32.const 34025) (i32.const 64) (i32.const 84)) - (memory.fill (i32.const 33338) (i32.const 65) (i32.const 2029)) - (memory.fill (i32.const 36810) (i32.const 66) (i32.const 29)) - (memory.fill (i32.const 19147) (i32.const 67) (i32.const 3034)) - (memory.fill (i32.const 12616) (i32.const 68) (i32.const 1043)) - (memory.fill (i32.const 18276) (i32.const 69) (i32.const 3324)) - (memory.fill (i32.const 4639) (i32.const 70) (i32.const 1091)) - (memory.fill (i32.const 16158) (i32.const 71) (i32.const 1997)) - (memory.fill (i32.const 18204) (i32.const 72) (i32.const 2259)) - (memory.fill (i32.const 50532) (i32.const 73) (i32.const 3189)) - (memory.fill (i32.const 11028) (i32.const 74) (i32.const 1968)) - (memory.fill (i32.const 15962) (i32.const 75) (i32.const 1455)) - (memory.fill (i32.const 45406) (i32.const 76) (i32.const 1177)) - (memory.fill (i32.const 54137) (i32.const 77) (i32.const 1568)) - (memory.fill (i32.const 33083) (i32.const 78) (i32.const 1642)) - (memory.fill (i32.const 61028) (i32.const 79) (i32.const 3284)) - (memory.fill (i32.const 51729) (i32.const 80) (i32.const 223)) - (memory.fill (i32.const 4361) (i32.const 81) (i32.const 2171)) - (memory.fill (i32.const 57514) (i32.const 82) (i32.const 1322)) - (memory.fill (i32.const 55724) (i32.const 83) (i32.const 2648)) - (memory.fill (i32.const 24091) (i32.const 84) (i32.const 1045)) - (memory.fill (i32.const 43183) (i32.const 85) (i32.const 3097)) - (memory.fill (i32.const 32307) (i32.const 86) (i32.const 2796)) - (memory.fill (i32.const 3811) (i32.const 87) (i32.const 2010)) - (memory.fill (i32.const 54856) (i32.const 88) (i32.const 0)) - (memory.fill (i32.const 49941) (i32.const 89) (i32.const 2069)) - (memory.fill (i32.const 20411) (i32.const 90) (i32.const 2896)) - (memory.fill (i32.const 33826) (i32.const 91) (i32.const 192)) - (memory.fill (i32.const 9402) (i32.const 92) (i32.const 2195)) - (memory.fill (i32.const 12413) (i32.const 93) (i32.const 24)) - (memory.fill (i32.const 14091) (i32.const 94) (i32.const 577)) - (memory.fill (i32.const 44058) (i32.const 95) (i32.const 2089)) - (memory.fill (i32.const 36735) (i32.const 96) (i32.const 3436)) - (memory.fill (i32.const 23288) (i32.const 97) (i32.const 2765)) - (memory.fill (i32.const 6392) (i32.const 98) (i32.const 830)) - (memory.fill (i32.const 33307) (i32.const 99) (i32.const 1938)) - (memory.fill (i32.const 21941) (i32.const 100) (i32.const 2750)) - (memory.copy (i32.const 59214) (i32.const 54248) (i32.const 2098)) - (memory.copy (i32.const 63026) (i32.const 39224) (i32.const 230)) - (memory.copy (i32.const 51833) (i32.const 23629) (i32.const 2300)) - (memory.copy (i32.const 6708) (i32.const 23996) (i32.const 639)) - (memory.copy (i32.const 6990) (i32.const 33399) (i32.const 1097)) - (memory.copy (i32.const 19403) (i32.const 10348) (i32.const 3197)) - (memory.copy (i32.const 27308) (i32.const 54406) (i32.const 100)) - (memory.copy (i32.const 27221) (i32.const 43682) (i32.const 1717)) - (memory.copy (i32.const 60528) (i32.const 8629) (i32.const 119)) - (memory.copy (i32.const 5947) (i32.const 2308) (i32.const 658)) - (memory.copy (i32.const 4787) (i32.const 51631) (i32.const 2269)) - (memory.copy (i32.const 12617) (i32.const 19197) (i32.const 833)) - (memory.copy (i32.const 11854) (i32.const 46505) (i32.const 3300)) - (memory.copy (i32.const 11376) (i32.const 45012) (i32.const 2281)) - (memory.copy (i32.const 34186) (i32.const 6697) (i32.const 2572)) - (memory.copy (i32.const 4936) (i32.const 1690) (i32.const 1328)) - (memory.copy (i32.const 63164) (i32.const 7637) (i32.const 1670)) - (memory.copy (i32.const 44568) (i32.const 18344) (i32.const 33)) - (memory.copy (i32.const 43918) (i32.const 22348) (i32.const 1427)) - (memory.copy (i32.const 46637) (i32.const 49819) (i32.const 1434)) - (memory.copy (i32.const 63684) (i32.const 8755) (i32.const 834)) - (memory.copy (i32.const 33485) (i32.const 20131) (i32.const 3317)) - (memory.copy (i32.const 40575) (i32.const 54317) (i32.const 3201)) - (memory.copy (i32.const 25812) (i32.const 59254) (i32.const 2452)) - (memory.copy (i32.const 19678) (i32.const 56882) (i32.const 346)) - (memory.copy (i32.const 15852) (i32.const 35914) (i32.const 2430)) - (memory.copy (i32.const 11824) (i32.const 35574) (i32.const 300)) - (memory.copy (i32.const 59427) (i32.const 13957) (i32.const 3153)) - (memory.copy (i32.const 34299) (i32.const 60594) (i32.const 1281)) - (memory.copy (i32.const 8964) (i32.const 12276) (i32.const 943)) - (memory.copy (i32.const 2827) (i32.const 10425) (i32.const 1887)) - (memory.copy (i32.const 43194) (i32.const 43910) (i32.const 738)) - (memory.copy (i32.const 63038) (i32.const 18949) (i32.const 122)) - (memory.copy (i32.const 24044) (i32.const 44761) (i32.const 1755)) - (memory.copy (i32.const 22608) (i32.const 14755) (i32.const 702)) - (memory.copy (i32.const 11284) (i32.const 26579) (i32.const 1830)) - (memory.copy (i32.const 23092) (i32.const 20471) (i32.const 1064)) - (memory.copy (i32.const 57248) (i32.const 54770) (i32.const 2631)) - (memory.copy (i32.const 25492) (i32.const 1025) (i32.const 3113)) - (memory.copy (i32.const 49588) (i32.const 44220) (i32.const 975)) - (memory.copy (i32.const 28280) (i32.const 41722) (i32.const 2336)) - (memory.copy (i32.const 61289) (i32.const 230) (i32.const 2872)) - (memory.copy (i32.const 22480) (i32.const 52506) (i32.const 2197)) - (memory.copy (i32.const 40553) (i32.const 9578) (i32.const 1958)) - (memory.copy (i32.const 29004) (i32.const 20862) (i32.const 2186)) - (memory.copy (i32.const 53029) (i32.const 43955) (i32.const 1037)) - (memory.copy (i32.const 25476) (i32.const 35667) (i32.const 1650)) - (memory.copy (i32.const 58516) (i32.const 45819) (i32.const 1986)) - (memory.copy (i32.const 38297) (i32.const 5776) (i32.const 1955)) - (memory.copy (i32.const 28503) (i32.const 55364) (i32.const 2368)) - (memory.copy (i32.const 62619) (i32.const 18108) (i32.const 1356)) - (memory.copy (i32.const 50149) (i32.const 13861) (i32.const 382)) - (memory.copy (i32.const 16904) (i32.const 36341) (i32.const 1900)) - (memory.copy (i32.const 48098) (i32.const 11358) (i32.const 2807)) - (memory.copy (i32.const 28512) (i32.const 40362) (i32.const 323)) - (memory.copy (i32.const 35506) (i32.const 27856) (i32.const 1670)) - (memory.copy (i32.const 62970) (i32.const 53332) (i32.const 1341)) - (memory.copy (i32.const 14133) (i32.const 46312) (i32.const 644)) - (memory.copy (i32.const 29030) (i32.const 19074) (i32.const 496)) - (memory.copy (i32.const 44952) (i32.const 47577) (i32.const 2784)) - (memory.copy (i32.const 39559) (i32.const 44661) (i32.const 1350)) - (memory.copy (i32.const 10352) (i32.const 29274) (i32.const 1475)) - (memory.copy (i32.const 46911) (i32.const 46178) (i32.const 1467)) - (memory.copy (i32.const 4905) (i32.const 28740) (i32.const 1895)) - (memory.copy (i32.const 38012) (i32.const 57253) (i32.const 1751)) - (memory.copy (i32.const 26446) (i32.const 27223) (i32.const 1127)) - (memory.copy (i32.const 58835) (i32.const 24657) (i32.const 1063)) - (memory.copy (i32.const 61356) (i32.const 38790) (i32.const 766)) - (memory.copy (i32.const 44160) (i32.const 2284) (i32.const 1520)) - (memory.copy (i32.const 32740) (i32.const 47237) (i32.const 3014)) - (memory.copy (i32.const 11148) (i32.const 21260) (i32.const 1011)) - (memory.copy (i32.const 7665) (i32.const 31612) (i32.const 3034)) - (memory.copy (i32.const 18044) (i32.const 12987) (i32.const 3320)) - (memory.copy (i32.const 57306) (i32.const 55905) (i32.const 308)) - (memory.copy (i32.const 24675) (i32.const 16815) (i32.const 1155)) - (memory.copy (i32.const 19900) (i32.const 10115) (i32.const 722)) - (memory.copy (i32.const 2921) (i32.const 5935) (i32.const 2370)) - (memory.copy (i32.const 32255) (i32.const 50095) (i32.const 2926)) - (memory.copy (i32.const 15126) (i32.const 17299) (i32.const 2607)) - (memory.copy (i32.const 45575) (i32.const 28447) (i32.const 2045)) - (memory.copy (i32.const 55149) (i32.const 36113) (i32.const 2596)) - (memory.copy (i32.const 28461) (i32.const 54157) (i32.const 1168)) - (memory.copy (i32.const 47951) (i32.const 53385) (i32.const 3137)) - (memory.copy (i32.const 30646) (i32.const 45155) (i32.const 2649)) - (memory.copy (i32.const 5057) (i32.const 4295) (i32.const 52)) - (memory.copy (i32.const 6692) (i32.const 24195) (i32.const 441)) - (memory.copy (i32.const 32984) (i32.const 27117) (i32.const 3445)) - (memory.copy (i32.const 32530) (i32.const 59372) (i32.const 2785)) - (memory.copy (i32.const 34361) (i32.const 8962) (i32.const 2406)) - (memory.copy (i32.const 17893) (i32.const 54538) (i32.const 3381)) - (memory.copy (i32.const 22685) (i32.const 44151) (i32.const 136)) - (memory.copy (i32.const 59089) (i32.const 7077) (i32.const 1045)) - (memory.copy (i32.const 42945) (i32.const 55028) (i32.const 2389)) - (memory.copy (i32.const 44693) (i32.const 20138) (i32.const 877)) - (memory.copy (i32.const 36810) (i32.const 25196) (i32.const 3447)) - (memory.copy (i32.const 45742) (i32.const 31888) (i32.const 854)) - (memory.copy (i32.const 24236) (i32.const 31866) (i32.const 1377)) - (memory.copy (i32.const 33778) (i32.const 692) (i32.const 1594)) - (memory.copy (i32.const 60618) (i32.const 18585) (i32.const 2987)) - (memory.copy (i32.const 50370) (i32.const 41271) (i32.const 1406)) + (memory.fill (${memtype}.const 17767) (i32.const 1) (${memtype}.const 1344)) + (memory.fill (${memtype}.const 39017) (i32.const 2) (${memtype}.const 1055)) + (memory.fill (${memtype}.const 56401) (i32.const 3) (${memtype}.const 988)) + (memory.fill (${memtype}.const 37962) (i32.const 4) (${memtype}.const 322)) + (memory.fill (${memtype}.const 7977) (i32.const 5) (${memtype}.const 1994)) + (memory.fill (${memtype}.const 22714) (i32.const 6) (${memtype}.const 3036)) + (memory.fill (${memtype}.const 16882) (i32.const 7) (${memtype}.const 2372)) + (memory.fill (${memtype}.const 43491) (i32.const 8) (${memtype}.const 835)) + (memory.fill (${memtype}.const 124) (i32.const 9) (${memtype}.const 1393)) + (memory.fill (${memtype}.const 2132) (i32.const 10) (${memtype}.const 2758)) + (memory.fill (${memtype}.const 8987) (i32.const 11) (${memtype}.const 3098)) + (memory.fill (${memtype}.const 52711) (i32.const 12) (${memtype}.const 741)) + (memory.fill (${memtype}.const 3958) (i32.const 13) (${memtype}.const 2823)) + (memory.fill (${memtype}.const 49715) (i32.const 14) (${memtype}.const 1280)) + (memory.fill (${memtype}.const 50377) (i32.const 15) (${memtype}.const 1466)) + (memory.fill (${memtype}.const 20493) (i32.const 16) (${memtype}.const 3158)) + (memory.fill (${memtype}.const 47665) (i32.const 17) (${memtype}.const 544)) + (memory.fill (${memtype}.const 12451) (i32.const 18) (${memtype}.const 2669)) + (memory.fill (${memtype}.const 24869) (i32.const 19) (${memtype}.const 2651)) + (memory.fill (${memtype}.const 45317) (i32.const 20) (${memtype}.const 1570)) + (memory.fill (${memtype}.const 43096) (i32.const 21) (${memtype}.const 1691)) + (memory.fill (${memtype}.const 33886) (i32.const 22) (${memtype}.const 646)) + (memory.fill (${memtype}.const 48555) (i32.const 23) (${memtype}.const 1858)) + (memory.fill (${memtype}.const 53453) (i32.const 24) (${memtype}.const 2657)) + (memory.fill (${memtype}.const 30363) (i32.const 25) (${memtype}.const 981)) + (memory.fill (${memtype}.const 9300) (i32.const 26) (${memtype}.const 1807)) + (memory.fill (${memtype}.const 50190) (i32.const 27) (${memtype}.const 487)) + (memory.fill (${memtype}.const 62753) (i32.const 28) (${memtype}.const 530)) + (memory.fill (${memtype}.const 36316) (i32.const 29) (${memtype}.const 943)) + (memory.fill (${memtype}.const 6768) (i32.const 30) (${memtype}.const 381)) + (memory.fill (${memtype}.const 51262) (i32.const 31) (${memtype}.const 3089)) + (memory.fill (${memtype}.const 49729) (i32.const 32) (${memtype}.const 658)) + (memory.fill (${memtype}.const 44540) (i32.const 33) (${memtype}.const 1702)) + (memory.fill (${memtype}.const 33342) (i32.const 34) (${memtype}.const 1092)) + (memory.fill (${memtype}.const 50814) (i32.const 35) (${memtype}.const 1410)) + (memory.fill (${memtype}.const 47594) (i32.const 36) (${memtype}.const 2204)) + (memory.fill (${memtype}.const 54123) (i32.const 37) (${memtype}.const 2394)) + (memory.fill (${memtype}.const 55183) (i32.const 38) (${memtype}.const 250)) + (memory.fill (${memtype}.const 22620) (i32.const 39) (${memtype}.const 2097)) + (memory.fill (${memtype}.const 17132) (i32.const 40) (${memtype}.const 3264)) + (memory.fill (${memtype}.const 54331) (i32.const 41) (${memtype}.const 3299)) + (memory.fill (${memtype}.const 39474) (i32.const 42) (${memtype}.const 2796)) + (memory.fill (${memtype}.const 36156) (i32.const 43) (${memtype}.const 2070)) + (memory.fill (${memtype}.const 35308) (i32.const 44) (${memtype}.const 2763)) + (memory.fill (${memtype}.const 32731) (i32.const 45) (${memtype}.const 312)) + (memory.fill (${memtype}.const 63746) (i32.const 46) (${memtype}.const 192)) + (memory.fill (${memtype}.const 30974) (i32.const 47) (${memtype}.const 596)) + (memory.fill (${memtype}.const 16635) (i32.const 48) (${memtype}.const 501)) + (memory.fill (${memtype}.const 57002) (i32.const 49) (${memtype}.const 686)) + (memory.fill (${memtype}.const 34299) (i32.const 50) (${memtype}.const 385)) + (memory.fill (${memtype}.const 60881) (i32.const 51) (${memtype}.const 903)) + (memory.fill (${memtype}.const 61445) (i32.const 52) (${memtype}.const 2390)) + (memory.fill (${memtype}.const 46972) (i32.const 53) (${memtype}.const 1441)) + (memory.fill (${memtype}.const 25973) (i32.const 54) (${memtype}.const 3162)) + (memory.fill (${memtype}.const 5566) (i32.const 55) (${memtype}.const 2135)) + (memory.fill (${memtype}.const 35977) (i32.const 56) (${memtype}.const 519)) + (memory.fill (${memtype}.const 44892) (i32.const 57) (${memtype}.const 3280)) + (memory.fill (${memtype}.const 46760) (i32.const 58) (${memtype}.const 1678)) + (memory.fill (${memtype}.const 46607) (i32.const 59) (${memtype}.const 3168)) + (memory.fill (${memtype}.const 22449) (i32.const 60) (${memtype}.const 1441)) + (memory.fill (${memtype}.const 58609) (i32.const 61) (${memtype}.const 663)) + (memory.fill (${memtype}.const 32261) (i32.const 62) (${memtype}.const 1671)) + (memory.fill (${memtype}.const 3063) (i32.const 63) (${memtype}.const 721)) + (memory.fill (${memtype}.const 34025) (i32.const 64) (${memtype}.const 84)) + (memory.fill (${memtype}.const 33338) (i32.const 65) (${memtype}.const 2029)) + (memory.fill (${memtype}.const 36810) (i32.const 66) (${memtype}.const 29)) + (memory.fill (${memtype}.const 19147) (i32.const 67) (${memtype}.const 3034)) + (memory.fill (${memtype}.const 12616) (i32.const 68) (${memtype}.const 1043)) + (memory.fill (${memtype}.const 18276) (i32.const 69) (${memtype}.const 3324)) + (memory.fill (${memtype}.const 4639) (i32.const 70) (${memtype}.const 1091)) + (memory.fill (${memtype}.const 16158) (i32.const 71) (${memtype}.const 1997)) + (memory.fill (${memtype}.const 18204) (i32.const 72) (${memtype}.const 2259)) + (memory.fill (${memtype}.const 50532) (i32.const 73) (${memtype}.const 3189)) + (memory.fill (${memtype}.const 11028) (i32.const 74) (${memtype}.const 1968)) + (memory.fill (${memtype}.const 15962) (i32.const 75) (${memtype}.const 1455)) + (memory.fill (${memtype}.const 45406) (i32.const 76) (${memtype}.const 1177)) + (memory.fill (${memtype}.const 54137) (i32.const 77) (${memtype}.const 1568)) + (memory.fill (${memtype}.const 33083) (i32.const 78) (${memtype}.const 1642)) + (memory.fill (${memtype}.const 61028) (i32.const 79) (${memtype}.const 3284)) + (memory.fill (${memtype}.const 51729) (i32.const 80) (${memtype}.const 223)) + (memory.fill (${memtype}.const 4361) (i32.const 81) (${memtype}.const 2171)) + (memory.fill (${memtype}.const 57514) (i32.const 82) (${memtype}.const 1322)) + (memory.fill (${memtype}.const 55724) (i32.const 83) (${memtype}.const 2648)) + (memory.fill (${memtype}.const 24091) (i32.const 84) (${memtype}.const 1045)) + (memory.fill (${memtype}.const 43183) (i32.const 85) (${memtype}.const 3097)) + (memory.fill (${memtype}.const 32307) (i32.const 86) (${memtype}.const 2796)) + (memory.fill (${memtype}.const 3811) (i32.const 87) (${memtype}.const 2010)) + (memory.fill (${memtype}.const 54856) (i32.const 88) (${memtype}.const 0)) + (memory.fill (${memtype}.const 49941) (i32.const 89) (${memtype}.const 2069)) + (memory.fill (${memtype}.const 20411) (i32.const 90) (${memtype}.const 2896)) + (memory.fill (${memtype}.const 33826) (i32.const 91) (${memtype}.const 192)) + (memory.fill (${memtype}.const 9402) (i32.const 92) (${memtype}.const 2195)) + (memory.fill (${memtype}.const 12413) (i32.const 93) (${memtype}.const 24)) + (memory.fill (${memtype}.const 14091) (i32.const 94) (${memtype}.const 577)) + (memory.fill (${memtype}.const 44058) (i32.const 95) (${memtype}.const 2089)) + (memory.fill (${memtype}.const 36735) (i32.const 96) (${memtype}.const 3436)) + (memory.fill (${memtype}.const 23288) (i32.const 97) (${memtype}.const 2765)) + (memory.fill (${memtype}.const 6392) (i32.const 98) (${memtype}.const 830)) + (memory.fill (${memtype}.const 33307) (i32.const 99) (${memtype}.const 1938)) + (memory.fill (${memtype}.const 21941) (i32.const 100) (${memtype}.const 2750)) + (memory.copy (${memtype}.const 59214) (${memtype}.const 54248) (${memtype}.const 2098)) + (memory.copy (${memtype}.const 63026) (${memtype}.const 39224) (${memtype}.const 230)) + (memory.copy (${memtype}.const 51833) (${memtype}.const 23629) (${memtype}.const 2300)) + (memory.copy (${memtype}.const 6708) (${memtype}.const 23996) (${memtype}.const 639)) + (memory.copy (${memtype}.const 6990) (${memtype}.const 33399) (${memtype}.const 1097)) + (memory.copy (${memtype}.const 19403) (${memtype}.const 10348) (${memtype}.const 3197)) + (memory.copy (${memtype}.const 27308) (${memtype}.const 54406) (${memtype}.const 100)) + (memory.copy (${memtype}.const 27221) (${memtype}.const 43682) (${memtype}.const 1717)) + (memory.copy (${memtype}.const 60528) (${memtype}.const 8629) (${memtype}.const 119)) + (memory.copy (${memtype}.const 5947) (${memtype}.const 2308) (${memtype}.const 658)) + (memory.copy (${memtype}.const 4787) (${memtype}.const 51631) (${memtype}.const 2269)) + (memory.copy (${memtype}.const 12617) (${memtype}.const 19197) (${memtype}.const 833)) + (memory.copy (${memtype}.const 11854) (${memtype}.const 46505) (${memtype}.const 3300)) + (memory.copy (${memtype}.const 11376) (${memtype}.const 45012) (${memtype}.const 2281)) + (memory.copy (${memtype}.const 34186) (${memtype}.const 6697) (${memtype}.const 2572)) + (memory.copy (${memtype}.const 4936) (${memtype}.const 1690) (${memtype}.const 1328)) + (memory.copy (${memtype}.const 63164) (${memtype}.const 7637) (${memtype}.const 1670)) + (memory.copy (${memtype}.const 44568) (${memtype}.const 18344) (${memtype}.const 33)) + (memory.copy (${memtype}.const 43918) (${memtype}.const 22348) (${memtype}.const 1427)) + (memory.copy (${memtype}.const 46637) (${memtype}.const 49819) (${memtype}.const 1434)) + (memory.copy (${memtype}.const 63684) (${memtype}.const 8755) (${memtype}.const 834)) + (memory.copy (${memtype}.const 33485) (${memtype}.const 20131) (${memtype}.const 3317)) + (memory.copy (${memtype}.const 40575) (${memtype}.const 54317) (${memtype}.const 3201)) + (memory.copy (${memtype}.const 25812) (${memtype}.const 59254) (${memtype}.const 2452)) + (memory.copy (${memtype}.const 19678) (${memtype}.const 56882) (${memtype}.const 346)) + (memory.copy (${memtype}.const 15852) (${memtype}.const 35914) (${memtype}.const 2430)) + (memory.copy (${memtype}.const 11824) (${memtype}.const 35574) (${memtype}.const 300)) + (memory.copy (${memtype}.const 59427) (${memtype}.const 13957) (${memtype}.const 3153)) + (memory.copy (${memtype}.const 34299) (${memtype}.const 60594) (${memtype}.const 1281)) + (memory.copy (${memtype}.const 8964) (${memtype}.const 12276) (${memtype}.const 943)) + (memory.copy (${memtype}.const 2827) (${memtype}.const 10425) (${memtype}.const 1887)) + (memory.copy (${memtype}.const 43194) (${memtype}.const 43910) (${memtype}.const 738)) + (memory.copy (${memtype}.const 63038) (${memtype}.const 18949) (${memtype}.const 122)) + (memory.copy (${memtype}.const 24044) (${memtype}.const 44761) (${memtype}.const 1755)) + (memory.copy (${memtype}.const 22608) (${memtype}.const 14755) (${memtype}.const 702)) + (memory.copy (${memtype}.const 11284) (${memtype}.const 26579) (${memtype}.const 1830)) + (memory.copy (${memtype}.const 23092) (${memtype}.const 20471) (${memtype}.const 1064)) + (memory.copy (${memtype}.const 57248) (${memtype}.const 54770) (${memtype}.const 2631)) + (memory.copy (${memtype}.const 25492) (${memtype}.const 1025) (${memtype}.const 3113)) + (memory.copy (${memtype}.const 49588) (${memtype}.const 44220) (${memtype}.const 975)) + (memory.copy (${memtype}.const 28280) (${memtype}.const 41722) (${memtype}.const 2336)) + (memory.copy (${memtype}.const 61289) (${memtype}.const 230) (${memtype}.const 2872)) + (memory.copy (${memtype}.const 22480) (${memtype}.const 52506) (${memtype}.const 2197)) + (memory.copy (${memtype}.const 40553) (${memtype}.const 9578) (${memtype}.const 1958)) + (memory.copy (${memtype}.const 29004) (${memtype}.const 20862) (${memtype}.const 2186)) + (memory.copy (${memtype}.const 53029) (${memtype}.const 43955) (${memtype}.const 1037)) + (memory.copy (${memtype}.const 25476) (${memtype}.const 35667) (${memtype}.const 1650)) + (memory.copy (${memtype}.const 58516) (${memtype}.const 45819) (${memtype}.const 1986)) + (memory.copy (${memtype}.const 38297) (${memtype}.const 5776) (${memtype}.const 1955)) + (memory.copy (${memtype}.const 28503) (${memtype}.const 55364) (${memtype}.const 2368)) + (memory.copy (${memtype}.const 62619) (${memtype}.const 18108) (${memtype}.const 1356)) + (memory.copy (${memtype}.const 50149) (${memtype}.const 13861) (${memtype}.const 382)) + (memory.copy (${memtype}.const 16904) (${memtype}.const 36341) (${memtype}.const 1900)) + (memory.copy (${memtype}.const 48098) (${memtype}.const 11358) (${memtype}.const 2807)) + (memory.copy (${memtype}.const 28512) (${memtype}.const 40362) (${memtype}.const 323)) + (memory.copy (${memtype}.const 35506) (${memtype}.const 27856) (${memtype}.const 1670)) + (memory.copy (${memtype}.const 62970) (${memtype}.const 53332) (${memtype}.const 1341)) + (memory.copy (${memtype}.const 14133) (${memtype}.const 46312) (${memtype}.const 644)) + (memory.copy (${memtype}.const 29030) (${memtype}.const 19074) (${memtype}.const 496)) + (memory.copy (${memtype}.const 44952) (${memtype}.const 47577) (${memtype}.const 2784)) + (memory.copy (${memtype}.const 39559) (${memtype}.const 44661) (${memtype}.const 1350)) + (memory.copy (${memtype}.const 10352) (${memtype}.const 29274) (${memtype}.const 1475)) + (memory.copy (${memtype}.const 46911) (${memtype}.const 46178) (${memtype}.const 1467)) + (memory.copy (${memtype}.const 4905) (${memtype}.const 28740) (${memtype}.const 1895)) + (memory.copy (${memtype}.const 38012) (${memtype}.const 57253) (${memtype}.const 1751)) + (memory.copy (${memtype}.const 26446) (${memtype}.const 27223) (${memtype}.const 1127)) + (memory.copy (${memtype}.const 58835) (${memtype}.const 24657) (${memtype}.const 1063)) + (memory.copy (${memtype}.const 61356) (${memtype}.const 38790) (${memtype}.const 766)) + (memory.copy (${memtype}.const 44160) (${memtype}.const 2284) (${memtype}.const 1520)) + (memory.copy (${memtype}.const 32740) (${memtype}.const 47237) (${memtype}.const 3014)) + (memory.copy (${memtype}.const 11148) (${memtype}.const 21260) (${memtype}.const 1011)) + (memory.copy (${memtype}.const 7665) (${memtype}.const 31612) (${memtype}.const 3034)) + (memory.copy (${memtype}.const 18044) (${memtype}.const 12987) (${memtype}.const 3320)) + (memory.copy (${memtype}.const 57306) (${memtype}.const 55905) (${memtype}.const 308)) + (memory.copy (${memtype}.const 24675) (${memtype}.const 16815) (${memtype}.const 1155)) + (memory.copy (${memtype}.const 19900) (${memtype}.const 10115) (${memtype}.const 722)) + (memory.copy (${memtype}.const 2921) (${memtype}.const 5935) (${memtype}.const 2370)) + (memory.copy (${memtype}.const 32255) (${memtype}.const 50095) (${memtype}.const 2926)) + (memory.copy (${memtype}.const 15126) (${memtype}.const 17299) (${memtype}.const 2607)) + (memory.copy (${memtype}.const 45575) (${memtype}.const 28447) (${memtype}.const 2045)) + (memory.copy (${memtype}.const 55149) (${memtype}.const 36113) (${memtype}.const 2596)) + (memory.copy (${memtype}.const 28461) (${memtype}.const 54157) (${memtype}.const 1168)) + (memory.copy (${memtype}.const 47951) (${memtype}.const 53385) (${memtype}.const 3137)) + (memory.copy (${memtype}.const 30646) (${memtype}.const 45155) (${memtype}.const 2649)) + (memory.copy (${memtype}.const 5057) (${memtype}.const 4295) (${memtype}.const 52)) + (memory.copy (${memtype}.const 6692) (${memtype}.const 24195) (${memtype}.const 441)) + (memory.copy (${memtype}.const 32984) (${memtype}.const 27117) (${memtype}.const 3445)) + (memory.copy (${memtype}.const 32530) (${memtype}.const 59372) (${memtype}.const 2785)) + (memory.copy (${memtype}.const 34361) (${memtype}.const 8962) (${memtype}.const 2406)) + (memory.copy (${memtype}.const 17893) (${memtype}.const 54538) (${memtype}.const 3381)) + (memory.copy (${memtype}.const 22685) (${memtype}.const 44151) (${memtype}.const 136)) + (memory.copy (${memtype}.const 59089) (${memtype}.const 7077) (${memtype}.const 1045)) + (memory.copy (${memtype}.const 42945) (${memtype}.const 55028) (${memtype}.const 2389)) + (memory.copy (${memtype}.const 44693) (${memtype}.const 20138) (${memtype}.const 877)) + (memory.copy (${memtype}.const 36810) (${memtype}.const 25196) (${memtype}.const 3447)) + (memory.copy (${memtype}.const 45742) (${memtype}.const 31888) (${memtype}.const 854)) + (memory.copy (${memtype}.const 24236) (${memtype}.const 31866) (${memtype}.const 1377)) + (memory.copy (${memtype}.const 33778) (${memtype}.const 692) (${memtype}.const 1594)) + (memory.copy (${memtype}.const 60618) (${memtype}.const 18585) (${memtype}.const 2987)) + (memory.copy (${memtype}.const 50370) (${memtype}.const 41271) (${memtype}.const 1406)) ) - ${checkRangeCode()}) + ${checkRangeCode(memtype)}) (invoke "test") `); -checkRange(0, 124, 0); -checkRange(124, 1517, 9); -checkRange(1517, 2132, 0); -checkRange(2132, 2827, 10); -checkRange(2827, 2921, 92); -checkRange(2921, 3538, 83); -checkRange(3538, 3786, 77); -checkRange(3786, 4042, 97); -checkRange(4042, 4651, 99); -checkRange(4651, 5057, 0); -checkRange(5057, 5109, 99); -checkRange(5109, 5291, 0); -checkRange(5291, 5524, 72); -checkRange(5524, 5691, 92); -checkRange(5691, 6552, 83); -checkRange(6552, 7133, 77); -checkRange(7133, 7665, 99); -checkRange(7665, 8314, 0); -checkRange(8314, 8360, 62); -checkRange(8360, 8793, 86); -checkRange(8793, 8979, 83); -checkRange(8979, 9373, 79); -checkRange(9373, 9518, 95); -checkRange(9518, 9934, 59); -checkRange(9934, 10087, 77); -checkRange(10087, 10206, 5); -checkRange(10206, 10230, 77); -checkRange(10230, 10249, 41); -checkRange(10249, 11148, 83); -checkRange(11148, 11356, 74); -checkRange(11356, 11380, 93); -checkRange(11380, 11939, 74); -checkRange(11939, 12159, 68); -checkRange(12159, 12575, 83); -checkRange(12575, 12969, 79); -checkRange(12969, 13114, 95); -checkRange(13114, 14133, 59); -checkRange(14133, 14404, 76); -checkRange(14404, 14428, 57); -checkRange(14428, 14458, 59); -checkRange(14458, 14580, 32); -checkRange(14580, 14777, 89); -checkRange(14777, 15124, 59); -checkRange(15124, 15126, 36); -checkRange(15126, 15192, 100); -checkRange(15192, 15871, 96); -checkRange(15871, 15998, 95); -checkRange(15998, 17017, 59); -checkRange(17017, 17288, 76); -checkRange(17288, 17312, 57); -checkRange(17312, 17342, 59); -checkRange(17342, 17464, 32); -checkRange(17464, 17661, 89); -checkRange(17661, 17727, 59); -checkRange(17727, 17733, 5); -checkRange(17733, 17893, 96); -checkRange(17893, 18553, 77); -checkRange(18553, 18744, 42); -checkRange(18744, 18801, 76); -checkRange(18801, 18825, 57); -checkRange(18825, 18876, 59); -checkRange(18876, 18885, 77); -checkRange(18885, 18904, 41); -checkRange(18904, 19567, 83); -checkRange(19567, 20403, 96); -checkRange(20403, 21274, 77); -checkRange(21274, 21364, 100); -checkRange(21364, 21468, 74); -checkRange(21468, 21492, 93); -checkRange(21492, 22051, 74); -checkRange(22051, 22480, 68); -checkRange(22480, 22685, 100); -checkRange(22685, 22694, 68); -checkRange(22694, 22821, 10); -checkRange(22821, 22869, 100); -checkRange(22869, 24107, 97); -checkRange(24107, 24111, 37); -checkRange(24111, 24236, 77); -checkRange(24236, 24348, 72); -checkRange(24348, 24515, 92); -checkRange(24515, 24900, 83); -checkRange(24900, 25136, 95); -checkRange(25136, 25182, 85); -checkRange(25182, 25426, 68); -checkRange(25426, 25613, 89); -checkRange(25613, 25830, 96); -checkRange(25830, 26446, 100); -checkRange(26446, 26517, 10); -checkRange(26517, 27468, 92); -checkRange(27468, 27503, 95); -checkRange(27503, 27573, 77); -checkRange(27573, 28245, 92); -checkRange(28245, 28280, 95); -checkRange(28280, 29502, 77); -checkRange(29502, 29629, 42); -checkRange(29629, 30387, 83); -checkRange(30387, 30646, 77); -checkRange(30646, 31066, 92); -checkRange(31066, 31131, 77); -checkRange(31131, 31322, 42); -checkRange(31322, 31379, 76); -checkRange(31379, 31403, 57); -checkRange(31403, 31454, 59); -checkRange(31454, 31463, 77); -checkRange(31463, 31482, 41); -checkRange(31482, 31649, 83); -checkRange(31649, 31978, 72); -checkRange(31978, 32145, 92); -checkRange(32145, 32530, 83); -checkRange(32530, 32766, 95); -checkRange(32766, 32812, 85); -checkRange(32812, 33056, 68); -checkRange(33056, 33660, 89); -checkRange(33660, 33752, 59); -checkRange(33752, 33775, 36); -checkRange(33775, 33778, 32); -checkRange(33778, 34603, 9); -checkRange(34603, 35218, 0); -checkRange(35218, 35372, 10); -checkRange(35372, 35486, 77); -checkRange(35486, 35605, 5); -checkRange(35605, 35629, 77); -checkRange(35629, 35648, 41); -checkRange(35648, 36547, 83); -checkRange(36547, 36755, 74); -checkRange(36755, 36767, 93); -checkRange(36767, 36810, 83); -checkRange(36810, 36839, 100); -checkRange(36839, 37444, 96); -checkRange(37444, 38060, 100); -checkRange(38060, 38131, 10); -checkRange(38131, 39082, 92); -checkRange(39082, 39117, 95); -checkRange(39117, 39187, 77); -checkRange(39187, 39859, 92); -checkRange(39859, 39894, 95); -checkRange(39894, 40257, 77); -checkRange(40257, 40344, 89); -checkRange(40344, 40371, 59); -checkRange(40371, 40804, 77); -checkRange(40804, 40909, 5); -checkRange(40909, 42259, 92); -checkRange(42259, 42511, 77); -checkRange(42511, 42945, 83); -checkRange(42945, 43115, 77); -checkRange(43115, 43306, 42); -checkRange(43306, 43363, 76); -checkRange(43363, 43387, 57); -checkRange(43387, 43438, 59); -checkRange(43438, 43447, 77); -checkRange(43447, 43466, 41); -checkRange(43466, 44129, 83); -checkRange(44129, 44958, 96); -checkRange(44958, 45570, 77); -checkRange(45570, 45575, 92); -checkRange(45575, 45640, 77); -checkRange(45640, 45742, 42); -checkRange(45742, 45832, 72); -checkRange(45832, 45999, 92); -checkRange(45999, 46384, 83); -checkRange(46384, 46596, 95); -checkRange(46596, 46654, 92); -checkRange(46654, 47515, 83); -checkRange(47515, 47620, 77); -checkRange(47620, 47817, 79); -checkRange(47817, 47951, 95); -checkRange(47951, 48632, 100); -checkRange(48632, 48699, 97); -checkRange(48699, 48703, 37); -checkRange(48703, 49764, 77); -checkRange(49764, 49955, 42); -checkRange(49955, 50012, 76); -checkRange(50012, 50036, 57); -checkRange(50036, 50087, 59); -checkRange(50087, 50096, 77); -checkRange(50096, 50115, 41); -checkRange(50115, 50370, 83); -checkRange(50370, 51358, 92); -checkRange(51358, 51610, 77); -checkRange(51610, 51776, 83); -checkRange(51776, 51833, 89); -checkRange(51833, 52895, 100); -checkRange(52895, 53029, 97); -checkRange(53029, 53244, 68); -checkRange(53244, 54066, 100); -checkRange(54066, 54133, 97); -checkRange(54133, 54137, 37); -checkRange(54137, 55198, 77); -checkRange(55198, 55389, 42); -checkRange(55389, 55446, 76); -checkRange(55446, 55470, 57); -checkRange(55470, 55521, 59); -checkRange(55521, 55530, 77); -checkRange(55530, 55549, 41); -checkRange(55549, 56212, 83); -checkRange(56212, 57048, 96); -checkRange(57048, 58183, 77); -checkRange(58183, 58202, 41); -checkRange(58202, 58516, 83); -checkRange(58516, 58835, 95); -checkRange(58835, 58855, 77); -checkRange(58855, 59089, 95); -checkRange(59089, 59145, 77); -checkRange(59145, 59677, 99); -checkRange(59677, 60134, 0); -checkRange(60134, 60502, 89); -checkRange(60502, 60594, 59); -checkRange(60594, 60617, 36); -checkRange(60617, 60618, 32); -checkRange(60618, 60777, 42); -checkRange(60777, 60834, 76); -checkRange(60834, 60858, 57); -checkRange(60858, 60909, 59); -checkRange(60909, 60918, 77); -checkRange(60918, 60937, 41); -checkRange(60937, 61600, 83); -checkRange(61600, 62436, 96); -checkRange(62436, 63307, 77); -checkRange(63307, 63397, 100); -checkRange(63397, 63501, 74); -checkRange(63501, 63525, 93); -checkRange(63525, 63605, 74); -checkRange(63605, 63704, 100); -checkRange(63704, 63771, 97); -checkRange(63771, 63775, 37); -checkRange(63775, 64311, 77); -checkRange(64311, 64331, 26); -checkRange(64331, 64518, 92); -checkRange(64518, 64827, 11); -checkRange(64827, 64834, 26); -checkRange(64834, 65536, 0); + checkRange(memtype, 0, 124, 0); + checkRange(memtype, 124, 1517, 9); + checkRange(memtype, 1517, 2132, 0); + checkRange(memtype, 2132, 2827, 10); + checkRange(memtype, 2827, 2921, 92); + checkRange(memtype, 2921, 3538, 83); + checkRange(memtype, 3538, 3786, 77); + checkRange(memtype, 3786, 4042, 97); + checkRange(memtype, 4042, 4651, 99); + checkRange(memtype, 4651, 5057, 0); + checkRange(memtype, 5057, 5109, 99); + checkRange(memtype, 5109, 5291, 0); + checkRange(memtype, 5291, 5524, 72); + checkRange(memtype, 5524, 5691, 92); + checkRange(memtype, 5691, 6552, 83); + checkRange(memtype, 6552, 7133, 77); + checkRange(memtype, 7133, 7665, 99); + checkRange(memtype, 7665, 8314, 0); + checkRange(memtype, 8314, 8360, 62); + checkRange(memtype, 8360, 8793, 86); + checkRange(memtype, 8793, 8979, 83); + checkRange(memtype, 8979, 9373, 79); + checkRange(memtype, 9373, 9518, 95); + checkRange(memtype, 9518, 9934, 59); + checkRange(memtype, 9934, 10087, 77); + checkRange(memtype, 10087, 10206, 5); + checkRange(memtype, 10206, 10230, 77); + checkRange(memtype, 10230, 10249, 41); + checkRange(memtype, 10249, 11148, 83); + checkRange(memtype, 11148, 11356, 74); + checkRange(memtype, 11356, 11380, 93); + checkRange(memtype, 11380, 11939, 74); + checkRange(memtype, 11939, 12159, 68); + checkRange(memtype, 12159, 12575, 83); + checkRange(memtype, 12575, 12969, 79); + checkRange(memtype, 12969, 13114, 95); + checkRange(memtype, 13114, 14133, 59); + checkRange(memtype, 14133, 14404, 76); + checkRange(memtype, 14404, 14428, 57); + checkRange(memtype, 14428, 14458, 59); + checkRange(memtype, 14458, 14580, 32); + checkRange(memtype, 14580, 14777, 89); + checkRange(memtype, 14777, 15124, 59); + checkRange(memtype, 15124, 15126, 36); + checkRange(memtype, 15126, 15192, 100); + checkRange(memtype, 15192, 15871, 96); + checkRange(memtype, 15871, 15998, 95); + checkRange(memtype, 15998, 17017, 59); + checkRange(memtype, 17017, 17288, 76); + checkRange(memtype, 17288, 17312, 57); + checkRange(memtype, 17312, 17342, 59); + checkRange(memtype, 17342, 17464, 32); + checkRange(memtype, 17464, 17661, 89); + checkRange(memtype, 17661, 17727, 59); + checkRange(memtype, 17727, 17733, 5); + checkRange(memtype, 17733, 17893, 96); + checkRange(memtype, 17893, 18553, 77); + checkRange(memtype, 18553, 18744, 42); + checkRange(memtype, 18744, 18801, 76); + checkRange(memtype, 18801, 18825, 57); + checkRange(memtype, 18825, 18876, 59); + checkRange(memtype, 18876, 18885, 77); + checkRange(memtype, 18885, 18904, 41); + checkRange(memtype, 18904, 19567, 83); + checkRange(memtype, 19567, 20403, 96); + checkRange(memtype, 20403, 21274, 77); + checkRange(memtype, 21274, 21364, 100); + checkRange(memtype, 21364, 21468, 74); + checkRange(memtype, 21468, 21492, 93); + checkRange(memtype, 21492, 22051, 74); + checkRange(memtype, 22051, 22480, 68); + checkRange(memtype, 22480, 22685, 100); + checkRange(memtype, 22685, 22694, 68); + checkRange(memtype, 22694, 22821, 10); + checkRange(memtype, 22821, 22869, 100); + checkRange(memtype, 22869, 24107, 97); + checkRange(memtype, 24107, 24111, 37); + checkRange(memtype, 24111, 24236, 77); + checkRange(memtype, 24236, 24348, 72); + checkRange(memtype, 24348, 24515, 92); + checkRange(memtype, 24515, 24900, 83); + checkRange(memtype, 24900, 25136, 95); + checkRange(memtype, 25136, 25182, 85); + checkRange(memtype, 25182, 25426, 68); + checkRange(memtype, 25426, 25613, 89); + checkRange(memtype, 25613, 25830, 96); + checkRange(memtype, 25830, 26446, 100); + checkRange(memtype, 26446, 26517, 10); + checkRange(memtype, 26517, 27468, 92); + checkRange(memtype, 27468, 27503, 95); + checkRange(memtype, 27503, 27573, 77); + checkRange(memtype, 27573, 28245, 92); + checkRange(memtype, 28245, 28280, 95); + checkRange(memtype, 28280, 29502, 77); + checkRange(memtype, 29502, 29629, 42); + checkRange(memtype, 29629, 30387, 83); + checkRange(memtype, 30387, 30646, 77); + checkRange(memtype, 30646, 31066, 92); + checkRange(memtype, 31066, 31131, 77); + checkRange(memtype, 31131, 31322, 42); + checkRange(memtype, 31322, 31379, 76); + checkRange(memtype, 31379, 31403, 57); + checkRange(memtype, 31403, 31454, 59); + checkRange(memtype, 31454, 31463, 77); + checkRange(memtype, 31463, 31482, 41); + checkRange(memtype, 31482, 31649, 83); + checkRange(memtype, 31649, 31978, 72); + checkRange(memtype, 31978, 32145, 92); + checkRange(memtype, 32145, 32530, 83); + checkRange(memtype, 32530, 32766, 95); + checkRange(memtype, 32766, 32812, 85); + checkRange(memtype, 32812, 33056, 68); + checkRange(memtype, 33056, 33660, 89); + checkRange(memtype, 33660, 33752, 59); + checkRange(memtype, 33752, 33775, 36); + checkRange(memtype, 33775, 33778, 32); + checkRange(memtype, 33778, 34603, 9); + checkRange(memtype, 34603, 35218, 0); + checkRange(memtype, 35218, 35372, 10); + checkRange(memtype, 35372, 35486, 77); + checkRange(memtype, 35486, 35605, 5); + checkRange(memtype, 35605, 35629, 77); + checkRange(memtype, 35629, 35648, 41); + checkRange(memtype, 35648, 36547, 83); + checkRange(memtype, 36547, 36755, 74); + checkRange(memtype, 36755, 36767, 93); + checkRange(memtype, 36767, 36810, 83); + checkRange(memtype, 36810, 36839, 100); + checkRange(memtype, 36839, 37444, 96); + checkRange(memtype, 37444, 38060, 100); + checkRange(memtype, 38060, 38131, 10); + checkRange(memtype, 38131, 39082, 92); + checkRange(memtype, 39082, 39117, 95); + checkRange(memtype, 39117, 39187, 77); + checkRange(memtype, 39187, 39859, 92); + checkRange(memtype, 39859, 39894, 95); + checkRange(memtype, 39894, 40257, 77); + checkRange(memtype, 40257, 40344, 89); + checkRange(memtype, 40344, 40371, 59); + checkRange(memtype, 40371, 40804, 77); + checkRange(memtype, 40804, 40909, 5); + checkRange(memtype, 40909, 42259, 92); + checkRange(memtype, 42259, 42511, 77); + checkRange(memtype, 42511, 42945, 83); + checkRange(memtype, 42945, 43115, 77); + checkRange(memtype, 43115, 43306, 42); + checkRange(memtype, 43306, 43363, 76); + checkRange(memtype, 43363, 43387, 57); + checkRange(memtype, 43387, 43438, 59); + checkRange(memtype, 43438, 43447, 77); + checkRange(memtype, 43447, 43466, 41); + checkRange(memtype, 43466, 44129, 83); + checkRange(memtype, 44129, 44958, 96); + checkRange(memtype, 44958, 45570, 77); + checkRange(memtype, 45570, 45575, 92); + checkRange(memtype, 45575, 45640, 77); + checkRange(memtype, 45640, 45742, 42); + checkRange(memtype, 45742, 45832, 72); + checkRange(memtype, 45832, 45999, 92); + checkRange(memtype, 45999, 46384, 83); + checkRange(memtype, 46384, 46596, 95); + checkRange(memtype, 46596, 46654, 92); + checkRange(memtype, 46654, 47515, 83); + checkRange(memtype, 47515, 47620, 77); + checkRange(memtype, 47620, 47817, 79); + checkRange(memtype, 47817, 47951, 95); + checkRange(memtype, 47951, 48632, 100); + checkRange(memtype, 48632, 48699, 97); + checkRange(memtype, 48699, 48703, 37); + checkRange(memtype, 48703, 49764, 77); + checkRange(memtype, 49764, 49955, 42); + checkRange(memtype, 49955, 50012, 76); + checkRange(memtype, 50012, 50036, 57); + checkRange(memtype, 50036, 50087, 59); + checkRange(memtype, 50087, 50096, 77); + checkRange(memtype, 50096, 50115, 41); + checkRange(memtype, 50115, 50370, 83); + checkRange(memtype, 50370, 51358, 92); + checkRange(memtype, 51358, 51610, 77); + checkRange(memtype, 51610, 51776, 83); + checkRange(memtype, 51776, 51833, 89); + checkRange(memtype, 51833, 52895, 100); + checkRange(memtype, 52895, 53029, 97); + checkRange(memtype, 53029, 53244, 68); + checkRange(memtype, 53244, 54066, 100); + checkRange(memtype, 54066, 54133, 97); + checkRange(memtype, 54133, 54137, 37); + checkRange(memtype, 54137, 55198, 77); + checkRange(memtype, 55198, 55389, 42); + checkRange(memtype, 55389, 55446, 76); + checkRange(memtype, 55446, 55470, 57); + checkRange(memtype, 55470, 55521, 59); + checkRange(memtype, 55521, 55530, 77); + checkRange(memtype, 55530, 55549, 41); + checkRange(memtype, 55549, 56212, 83); + checkRange(memtype, 56212, 57048, 96); + checkRange(memtype, 57048, 58183, 77); + checkRange(memtype, 58183, 58202, 41); + checkRange(memtype, 58202, 58516, 83); + checkRange(memtype, 58516, 58835, 95); + checkRange(memtype, 58835, 58855, 77); + checkRange(memtype, 58855, 59089, 95); + checkRange(memtype, 59089, 59145, 77); + checkRange(memtype, 59145, 59677, 99); + checkRange(memtype, 59677, 60134, 0); + checkRange(memtype, 60134, 60502, 89); + checkRange(memtype, 60502, 60594, 59); + checkRange(memtype, 60594, 60617, 36); + checkRange(memtype, 60617, 60618, 32); + checkRange(memtype, 60618, 60777, 42); + checkRange(memtype, 60777, 60834, 76); + checkRange(memtype, 60834, 60858, 57); + checkRange(memtype, 60858, 60909, 59); + checkRange(memtype, 60909, 60918, 77); + checkRange(memtype, 60918, 60937, 41); + checkRange(memtype, 60937, 61600, 83); + checkRange(memtype, 61600, 62436, 96); + checkRange(memtype, 62436, 63307, 77); + checkRange(memtype, 63307, 63397, 100); + checkRange(memtype, 63397, 63501, 74); + checkRange(memtype, 63501, 63525, 93); + checkRange(memtype, 63525, 63605, 74); + checkRange(memtype, 63605, 63704, 100); + checkRange(memtype, 63704, 63771, 97); + checkRange(memtype, 63771, 63775, 37); + checkRange(memtype, 63775, 64311, 77); + checkRange(memtype, 64311, 64331, 26); + checkRange(memtype, 64331, 64518, 92); + checkRange(memtype, 64518, 64827, 11); + checkRange(memtype, 64827, 64834, 26); + checkRange(memtype, 64834, 65536, 0); +} diff --git a/test/meta/generate_memory_fill.js b/test/meta/generate_memory_fill.js index 3a8f485f15..b04c3738a0 100644 --- a/test/meta/generate_memory_fill.js +++ b/test/meta/generate_memory_fill.js @@ -3,155 +3,160 @@ print_origin("generate_memory_fill.js"); -let PREAMBLE = - `(memory 1 1) - ${checkRangeCode()}`; +for ( const memtype of ['i32', 'i64'] ) { -// Range valid -print( + const decltype = memtype == 'i64' ? ' i64' : ''; + + let PREAMBLE = + `(memory${decltype} 1 1) + ${checkRangeCode(memtype)}`; + + // Range valid + print( ` (module ${PREAMBLE} (func (export "test") - (memory.fill (i32.const 0xFF00) (i32.const 0x55) (i32.const 256)))) + (memory.fill (${memtype}.const 0xFF00) (i32.const 0x55) (${memtype}.const 256)))) (invoke "test") `); -checkRange(0x00000, 0x0FF00, 0x00) -checkRange(0x0FF00, 0x10000, 0x55) + checkRange(memtype, 0x00000, 0x0FF00, 0x00) + checkRange(memtype, 0x0FF00, 0x10000, 0x55) -// Range invalid -print( + // Range invalid + print( `(module ${PREAMBLE} (func (export "test") - (memory.fill (i32.const 0xFF00) (i32.const 0x55) (i32.const 257)))) + (memory.fill (${memtype}.const 0xFF00) (i32.const 0x55) (${memtype}.const 257)))) (assert_trap (invoke "test") "out of bounds memory access") `); -// Wraparound the end of 32-bit offset space -print( + // Wraparound the end of 32-bit offset space + print( `(module ${PREAMBLE} (func (export "test") - (memory.fill (i32.const 0xFFFFFF00) (i32.const 0x55) (i32.const 257)))) + (memory.fill (${memtype}.const 0xFFFFFF00) (i32.const 0x55) (${memtype}.const 257)))) (assert_trap (invoke "test") "out of bounds memory access") `); -// Zero len with offset in-bounds is a no-op -print( + // Zero len with offset in-bounds is a no-op + print( `(module ${PREAMBLE} (func (export "test") - (memory.fill (i32.const 0x12) (i32.const 0x55) (i32.const 0)))) + (memory.fill (${memtype}.const 0x12) (i32.const 0x55) (${memtype}.const 0)))) (invoke "test") `); -checkRange(0x00000, 0x10000, 0x00); + checkRange(memtype, 0x00000, 0x10000, 0x00); -// Zero len with offset out-of-bounds at the end of memory is allowed -print( + // Zero len with offset out-of-bounds at the end of memory is allowed + print( `(module ${PREAMBLE} (func (export "test") - (memory.fill (i32.const 0x10000) (i32.const 0x55) (i32.const 0)))) + (memory.fill (${memtype}.const 0x10000) (i32.const 0x55) (${memtype}.const 0)))) (invoke "test") `); -// Zero len with offset out-of-bounds past the end of memory is not allowed -print( + // Zero len with offset out-of-bounds past the end of memory is not allowed + print( `(module ${PREAMBLE} (func (export "test") - (memory.fill (i32.const 0x20000) (i32.const 0x55) (i32.const 0)))) + (memory.fill (${memtype}.const 0x20000) (i32.const 0x55) (${memtype}.const 0)))) (assert_trap (invoke "test") "out of bounds memory access") `); -// Very large range -print( + // Very large range + print( `(module ${PREAMBLE} (func (export "test") - (memory.fill (i32.const 0x1) (i32.const 0xAA) (i32.const 0xFFFE)))) + (memory.fill (${memtype}.const 0x1) (i32.const 0xAA) (${memtype}.const 0xFFFE)))) (invoke "test") `); -checkRange(0x00000, 0x00001, 0x00); -checkRange(0x00001, 0x0FFFF, 0xAA); -checkRange(0x0FFFF, 0x10000, 0x00); + checkRange(memtype, 0x00000, 0x00001, 0x00); + checkRange(memtype, 0x00001, 0x0FFFF, 0xAA); + checkRange(memtype, 0x0FFFF, 0x10000, 0x00); -// Sequencing -print( + // Sequencing + print( ` (module ${PREAMBLE} (func (export "test") - (memory.fill (i32.const 0x12) (i32.const 0x55) (i32.const 10)) - (memory.fill (i32.const 0x15) (i32.const 0xAA) (i32.const 4)))) + (memory.fill (${memtype}.const 0x12) (i32.const 0x55) (${memtype}.const 10)) + (memory.fill (${memtype}.const 0x15) (i32.const 0xAA) (${memtype}.const 4)))) (invoke "test") `); -checkRange(0x0, 0x12+0, 0x00); -checkRange(0x12+0, 0x12+3, 0x55); -checkRange(0x12+3, 0x12+7, 0xAA); -checkRange(0x12+7, 0x12+10, 0x55); -checkRange(0x12+10, 0x10000, 0x00); + checkRange(memtype, 0x0, 0x12+0, 0x00); + checkRange(memtype, 0x12+0, 0x12+3, 0x55); + checkRange(memtype, 0x12+3, 0x12+7, 0xAA); + checkRange(memtype, 0x12+7, 0x12+10, 0x55); + checkRange(memtype, 0x12+10, 0x10000, 0x00); -// Sundry compilation failures. + // Sundry compilation failures. -// Module doesn't have a memory. -print( + // Module doesn't have a memory. + print( `(assert_invalid (module (func (export "testfn") - (memory.fill (i32.const 10) (i32.const 20) (i32.const 30)))) + (memory.fill (${memtype}.const 10) (i32.const 20) (${memtype}.const 30)))) "unknown memory 0") `); -// Invalid argument types. TODO: We can add anyref, funcref, etc here. -{ - const tys = ['i32', 'f32', 'i64', 'f64']; - for (let ty1 of tys) { - for (let ty2 of tys) { - for (let ty3 of tys) { - if (ty1 == 'i32' && ty2 == 'i32' && ty3 == 'i32') - continue; // this is the only valid case - print( + // Invalid argument types. TODO: We can add anyref, funcref, etc here. + { + const tys = ['i32', 'f32', 'i64', 'f64']; + for (let ty1 of tys) { + for (let ty2 of tys) { + for (let ty3 of tys) { + if (ty1 == memtype && ty2 == 'i32' && ty3 == memtype) + continue; // this is the only valid case + print( `(assert_invalid (module - (memory 1 1) + (memory${decltype} 1 1) (func (export "testfn") (memory.fill (${ty1}.const 10) (${ty2}.const 20) (${ty3}.const 30)))) "type mismatch") `); - }}} -} + }}} + } -// memory.fill: out of bounds, and should not perform a partial fill. -// -// Arithmetic overflow of memory offset + len should not affect the behavior, we -// should still fill up to the limit. + // memory.fill: out of bounds, and should not perform a partial fill. + // + // Arithmetic overflow of memory offset + len should not affect the behavior, we + // should still fill up to the limit. -function mem_fill(min, max, shared, backup, write=backup*2) { - print( + function mem_fill(min, max, shared, backup, write=backup*2) { + print( `(module - (memory ${min} ${max} ${shared}) - ${checkRangeCode()} - (func (export "run") (param $offs i32) (param $val i32) (param $len i32) + (memory${decltype} ${min} ${max} ${shared}) + ${checkRangeCode(memtype)} + (func (export "run") (param $offs ${memtype}) (param $val i32) (param $len ${memtype}) (memory.fill (local.get $offs) (local.get $val) (local.get $len)))) `); - // A fill past the end should throw *and* not have performed a partial fill - let offs = min*PAGESIZE - backup; - let val = 37; - print( -`(assert_trap (invoke "run" (i32.const ${offs}) (i32.const ${val}) (i32.const ${write})) + // A fill past the end should throw *and* not have performed a partial fill + let offs = min*PAGESIZE - backup; + let val = 37; + print( +`(assert_trap (invoke "run" (${memtype}.const ${offs}) (i32.const ${val}) (${memtype}.const ${write})) "out of bounds memory access") `); - checkRange(0, min, 0); -} - -mem_fill(1, 1, "", 256); -mem_fill(1, 1, "", 257); -mem_fill(1, 1, "", 257, 0xFFFFFFFF); // offs + len overflows 32-bit - -if (WITH_SHARED_MEMORY) { - mem_fill(2, 4, "shared", 256); - mem_fill(2, 4, "shared", 257); - mem_fill(2, 4, "shared", 257, 0xFFFFFFFF); // offs + len overflows 32-bit + checkRange(memtype, 0, min, 0); + } + + mem_fill(1, 1, "", 256); + mem_fill(1, 1, "", 257); + mem_fill(1, 1, "", 257, 0xFFFFFFFF); // offs + len overflows 32-bit + + if (WITH_SHARED_MEMORY) { + mem_fill(2, 4, "shared", 256); + mem_fill(2, 4, "shared", 257); + mem_fill(2, 4, "shared", 257, 0xFFFFFFFF); // offs + len overflows 32-bit + } } diff --git a/test/meta/generate_memory_init.js b/test/meta/generate_memory_init.js index f8075cc339..fa8ed22b31 100644 --- a/test/meta/generate_memory_init.js +++ b/test/meta/generate_memory_init.js @@ -3,64 +3,67 @@ print_origin("generate_memory_init.js"); -// In-bounds tests. +for ( const memtype of ['i32', 'i64'] ) { -function mem_test(instruction, expected_result_vector) { - print( + const decltype = memtype == 'i64' ? ' i64' : ''; + + // In-bounds tests. + function mem_test(instruction, expected_result_vector) { + print( ` (module - (memory (export "memory0") 1 1) - (data (i32.const 2) "\\03\\01\\04\\01") + (memory (export "memory0")${decltype} 1 1) + (data (${memtype}.const 2) "\\03\\01\\04\\01") (data "\\02\\07\\01\\08") - (data (i32.const 12) "\\07\\05\\02\\03\\06") + (data (${memtype}.const 12) "\\07\\05\\02\\03\\06") (data "\\05\\09\\02\\07\\06") (func (export "test") ${instruction}) - (func (export "load8_u") (param i32) (result i32) + (func (export "load8_u") (param ${memtype}) (result i32) (i32.load8_u (local.get 0)))) (invoke "test") `); - for (let i = 0; i < expected_result_vector.length; i++) { - print(`(assert_return (invoke "load8_u" (i32.const ${i})) (i32.const ${expected_result_vector[i]}))`); - } -} + for (let i = 0; i < expected_result_vector.length; i++) { + print(`(assert_return (invoke "load8_u" (${memtype}.const ${i})) (i32.const ${expected_result_vector[i]}))`); + } + } -const e = 0; + const e = 0; -// This just gives the initial state of the memory, with its active -// initialisers applied. -mem_test("(nop)", - [e,e,3,1,4, 1,e,e,e,e, e,e,7,5,2, 3,6,e,e,e, e,e,e,e,e, e,e,e,e,e]); + // This just gives the initial state of the memory, with its active + // initialisers applied. + mem_test("(nop)", + [e,e,3,1,4, 1,e,e,e,e, e,e,7,5,2, 3,6,e,e,e, e,e,e,e,e, e,e,e,e,e]); -// Passive init that overwrites all-zero entries -mem_test("(memory.init 1 (i32.const 7) (i32.const 0) (i32.const 4))", - [e,e,3,1,4, 1,e,2,7,1, 8,e,7,5,2, 3,6,e,e,e, e,e,e,e,e, e,e,e,e,e]); + // Passive init that overwrites all-zero entries + mem_test(`(memory.init 1 (${memtype}.const 7) (i32.const 0) (i32.const 4))`, + [e,e,3,1,4, 1,e,2,7,1, 8,e,7,5,2, 3,6,e,e,e, e,e,e,e,e, e,e,e,e,e]); -// Passive init that overwrites existing active-init-created entries -mem_test("(memory.init 3 (i32.const 15) (i32.const 1) (i32.const 3))", - [e,e,3,1,4, 1,e,e,e,e, e,e,7,5,2, 9,2,7,e,e, e,e,e,e,e, e,e,e,e,e]); + // Passive init that overwrites existing active-init-created entries + mem_test(`(memory.init 3 (${memtype}.const 15) (i32.const 1) (i32.const 3))`, + [e,e,3,1,4, 1,e,e,e,e, e,e,7,5,2, 9,2,7,e,e, e,e,e,e,e, e,e,e,e,e]); -// Perform active and passive initialisation and then multiple copies -mem_test(`(memory.init 1 (i32.const 7) (i32.const 0) (i32.const 4)) + // Perform active and passive initialisation and then multiple copies + mem_test(`(memory.init 1 (${memtype}.const 7) (i32.const 0) (i32.const 4)) (data.drop 1) - (memory.init 3 (i32.const 15) (i32.const 1) (i32.const 3)) + (memory.init 3 (${memtype}.const 15) (i32.const 1) (i32.const 3)) (data.drop 3) - (memory.copy (i32.const 20) (i32.const 15) (i32.const 5)) - (memory.copy (i32.const 21) (i32.const 29) (i32.const 1)) - (memory.copy (i32.const 24) (i32.const 10) (i32.const 1)) - (memory.copy (i32.const 13) (i32.const 11) (i32.const 4)) - (memory.copy (i32.const 19) (i32.const 20) (i32.const 5))`, - [e,e,3,1,4, 1,e,2,7,1, 8,e,7,e,7, 5,2,7,e,9, e,7,e,8,8, e,e,e,e,e]); + (memory.copy (${memtype}.const 20) (${memtype}.const 15) (${memtype}.const 5)) + (memory.copy (${memtype}.const 21) (${memtype}.const 29) (${memtype}.const 1)) + (memory.copy (${memtype}.const 24) (${memtype}.const 10) (${memtype}.const 1)) + (memory.copy (${memtype}.const 13) (${memtype}.const 11) (${memtype}.const 4)) + (memory.copy (${memtype}.const 19) (${memtype}.const 20) (${memtype}.const 5))`, + [e,e,3,1,4, 1,e,2,7,1, 8,e,7,e,7, 5,2,7,e,9, e,7,e,8,8, e,e,e,e,e]); -// Miscellaneous + // Miscellaneous -let PREAMBLE = - `(memory 1) + let PREAMBLE = + `(memory${decltype} 1) (data "\\37")`; -// drop with no memory -print( + // drop with no memory + print( `(assert_invalid (module (func (export "test") @@ -68,8 +71,8 @@ print( "unknown data segment") `); -// drop with data seg ix out of range -print( + // drop with data seg ix out of range + print( `(assert_invalid (module ${PREAMBLE} @@ -78,8 +81,8 @@ print( "unknown data segment") `); -// drop, then drop -print( + // drop, then drop + print( `(module ${PREAMBLE} (func (export "test") @@ -88,147 +91,147 @@ print( (invoke "test") `); -// drop, then init -print( + // drop, then init + print( `(module ${PREAMBLE} (func (export "test") (data.drop 0) - (memory.init 0 (i32.const 1234) (i32.const 1) (i32.const 1)))) + (memory.init 0 (${memtype}.const 1234) (i32.const 1) (i32.const 1)))) (assert_trap (invoke "test") "out of bounds memory access") `); -// init with data seg ix indicating an active segment -print( + // init with data seg ix indicating an active segment + print( `(module - (memory 1) - (data (i32.const 0) "\\37") + (memory${decltype} 1) + (data (${memtype}.const 0) "\\37") (func (export "test") - (memory.init 0 (i32.const 1234) (i32.const 1) (i32.const 1)))) + (memory.init 0 (${memtype}.const 1234) (i32.const 1) (i32.const 1)))) (assert_trap (invoke "test") "out of bounds memory access") `); -// init with no memory -print( + // init with no memory + print( `(assert_invalid (module (func (export "test") - (memory.init 1 (i32.const 1234) (i32.const 1) (i32.const 1)))) + (memory.init 1 (${memtype}.const 1234) (i32.const 1) (i32.const 1)))) "unknown memory 0") `); -// init with data seg ix out of range -print( + // init with data seg ix out of range + print( `(assert_invalid (module ${PREAMBLE} (func (export "test") - (memory.init 1 (i32.const 1234) (i32.const 1) (i32.const 1)))) + (memory.init 1 (${memtype}.const 1234) (i32.const 1) (i32.const 1)))) "unknown data segment 1") `); -// init, using a data seg ix more than once is OK -print( + // init, using a data seg ix more than once is OK + print( `(module ${PREAMBLE} (func (export "test") - (memory.init 0 (i32.const 1) (i32.const 0) (i32.const 1)) - (memory.init 0 (i32.const 1) (i32.const 0) (i32.const 1)))) + (memory.init 0 (${memtype}.const 1) (i32.const 0) (i32.const 1)) + (memory.init 0 (${memtype}.const 1) (i32.const 0) (i32.const 1)))) (invoke "test") `); -// init: seg ix is valid passive, but length to copy > len of seg -print( + // init: seg ix is valid passive, but length to copy > len of seg + print( `(module ${PREAMBLE} (func (export "test") - (memory.init 0 (i32.const 1234) (i32.const 0) (i32.const 5)))) + (memory.init 0 (${memtype}.const 1234) (i32.const 0) (i32.const 5)))) (assert_trap (invoke "test") "out of bounds memory access") `); -// init: seg ix is valid passive, but implies copying beyond end of seg -print( + // init: seg ix is valid passive, but implies copying beyond end of seg + print( `(module ${PREAMBLE} (func (export "test") - (memory.init 0 (i32.const 1234) (i32.const 2) (i32.const 3)))) + (memory.init 0 (${memtype}.const 1234) (i32.const 2) (i32.const 3)))) (assert_trap (invoke "test") "out of bounds memory access") `); -// init: seg ix is valid passive, but implies copying beyond end of dst -print( + // init: seg ix is valid passive, but implies copying beyond end of dst + print( `(module ${PREAMBLE} (func (export "test") - (memory.init 0 (i32.const 0xFFFE) (i32.const 1) (i32.const 3)))) + (memory.init 0 (${memtype}.const 0xFFFE) (i32.const 1) (i32.const 3)))) (assert_trap (invoke "test") "out of bounds memory access") `); -// init: seg ix is valid passive, src offset past the end, zero len is invalid -print( + // init: seg ix is valid passive, src offset past the end, zero len is invalid + print( `(module ${PREAMBLE} (func (export "test") - (memory.init 0 (i32.const 1234) (i32.const 4) (i32.const 0)))) + (memory.init 0 (${memtype}.const 1234) (i32.const 4) (i32.const 0)))) (assert_trap (invoke "test") "out of bounds memory access") `); -// init: seg ix is valid passive, zero len, src offset at the end -print( + // init: seg ix is valid passive, zero len, src offset at the end + print( `(module ${PREAMBLE} (func (export "test") - (memory.init 0 (i32.const 1234) (i32.const 1) (i32.const 0)))) + (memory.init 0 (${memtype}.const 1234) (i32.const 1) (i32.const 0)))) (invoke "test") `); -// init: seg ix is valid passive, dst offset past the end, zero len is invalid -print( + // init: seg ix is valid passive, dst offset past the end, zero len is invalid + print( `(module ${PREAMBLE} (func (export "test") - (memory.init 0 (i32.const 0x10001) (i32.const 0) (i32.const 0)))) + (memory.init 0 (${memtype}.const 0x10001) (i32.const 0) (i32.const 0)))) (assert_trap (invoke "test") "out of bounds memory access") `); -// init: seg ix is valid passive, zero len, but dst offset at the end -print( + // init: seg ix is valid passive, zero len, but dst offset at the end + print( `(module ${PREAMBLE} (func (export "test") - (memory.init 0 (i32.const 0x10000) (i32.const 0) (i32.const 0)))) + (memory.init 0 (${memtype}.const 0x10000) (i32.const 0) (i32.const 0)))) (invoke "test") `); -// init: seg ix is valid passive, zero len, dst and src offsets at the end -print( + // init: seg ix is valid passive, zero len, dst and src offsets at the end + print( `(module ${PREAMBLE} (func (export "test") - (memory.init 0 (i32.const 0x10000) (i32.const 1) (i32.const 0)))) + (memory.init 0 (${memtype}.const 0x10000) (i32.const 1) (i32.const 0)))) (invoke "test") `); -// init: seg ix is valid passive, src and dst offset past the end, zero len is -// invalid -print( + // init: seg ix is valid passive, src and dst offset past the end, zero len is + // invalid + print( `(module ${PREAMBLE} (func (export "test") - (memory.init 0 (i32.const 0x10001) (i32.const 4) (i32.const 0)))) + (memory.init 0 (${memtype}.const 0x10001) (i32.const 4) (i32.const 0)))) (assert_trap (invoke "test") "out of bounds memory access") `); -// invalid argument types. TODO: can add anyfunc etc here. -{ - const tys = ['i32', 'f32', 'i64', 'f64']; + // invalid argument types. TODO: can add anyfunc etc here. + { + const tys = ['i32', 'f32', 'i64', 'f64']; - for (let ty1 of tys) { - for (let ty2 of tys) { - for (let ty3 of tys) { - if (ty1 == 'i32' && ty2 == 'i32' && ty3 == 'i32') - continue; // this is the only valid case - print( + for (let ty1 of tys) { + for (let ty2 of tys) { + for (let ty3 of tys) { + if (ty1 == memtype && ty2 == 'i32' && ty3 == 'i32') + continue; // this is the only valid case + print( `(assert_invalid (module ${PREAMBLE} @@ -236,68 +239,68 @@ print( (memory.init 0 (${ty1}.const 1) (${ty2}.const 1) (${ty3}.const 1)))) "type mismatch") `); - }}} -} + }}} + } -// memory.init: out of bounds of the memory or the segment, but should perform -// the operation up to the appropriate bound. -// -// Arithmetic overflow of memoffset + len or of bufferoffset + len should not -// affect the behavior. + // memory.init: out of bounds of the memory or the segment, but should perform + // the operation up to the appropriate bound. + // + // Arithmetic overflow of memoffset + len or of bufferoffset + len should not + // affect the behavior. -// Note, the length of the data segment is 16. -const mem_init_len = 16; + // Note, the length of the data segment is 16. + const mem_init_len = 16; -function mem_init(min, max, shared, backup, write) { - print( + function mem_init(min, max, shared, backup, write) { + print( `(module - (memory ${min} ${max} ${shared}) + (memory${decltype} ${min} ${max} ${shared}) (data "\\42\\42\\42\\42\\42\\42\\42\\42\\42\\42\\42\\42\\42\\42\\42\\42") - ${checkRangeCode()} - (func (export "run") (param $offs i32) (param $len i32) + ${checkRangeCode(memtype)} + (func (export "run") (param $offs ${memtype}) (param $len i32) (memory.init 0 (local.get $offs) (i32.const 0) (local.get $len)))) `); - // A fill writing past the end of the memory should throw *and* have filled - // all the way up to the end. - // - // A fill reading past the end of the segment should throw *and* have filled - // memory with as much data as was available. - let offs = min*PAGESIZE - backup; - print( -`(assert_trap (invoke "run" (i32.const ${offs}) (i32.const ${write})) + // A fill writing past the end of the memory should throw *and* have filled + // all the way up to the end. + // + // A fill reading past the end of the segment should throw *and* have filled + // memory with as much data as was available. + let offs = min*PAGESIZE - backup; + print( +`(assert_trap (invoke "run" (${memtype}.const ${offs}) (i32.const ${write})) "out of bounds memory access") `); - checkRange(0, min, 0); -} - -// We exceed the bounds of the memory but not of the data segment -mem_init(1, 1, "", Math.floor(mem_init_len/2), mem_init_len); -mem_init(1, 1, "", Math.floor(mem_init_len/2)+1, mem_init_len); -if (WITH_SHARED_MEMORY) { - mem_init(2, 4, "shared", Math.floor(mem_init_len/2), mem_init_len); - mem_init(2, 4, "shared", Math.floor(mem_init_len/2)+1, mem_init_len); -} - -// We exceed the bounds of the data segment but not the memory -mem_init(1, 1, "", mem_init_len*4, mem_init_len*2-2); -mem_init(1, 1, "", mem_init_len*4-1, mem_init_len*2-1); -if (WITH_SHARED_MEMORY) { - mem_init(2, 4, "shared", mem_init_len*4, mem_init_len*2-2); - mem_init(2, 4, "shared", mem_init_len*4-1, mem_init_len*2-1); -} - -// We arithmetically overflow the memory limit but not the segment limit -mem_init(1, "", "", Math.floor(mem_init_len/2), 0xFFFFFF00); - -// We arithmetically overflow the segment limit but not the memory limit -mem_init(1, "", "", PAGESIZE, 0xFFFFFFFC); - -// Test that the data segment index is properly encoded as an unsigned (not -// signed) LEB. -print( + checkRange(memtype, 0, min, 0); + } + + // We exceed the bounds of the memory but not of the data segment + mem_init(1, 1, "", Math.floor(mem_init_len/2), mem_init_len); + mem_init(1, 1, "", Math.floor(mem_init_len/2)+1, mem_init_len); + if (WITH_SHARED_MEMORY) { + mem_init(2, 4, "shared", Math.floor(mem_init_len/2), mem_init_len); + mem_init(2, 4, "shared", Math.floor(mem_init_len/2)+1, mem_init_len); + } + + // We exceed the bounds of the data segment but not the memory + mem_init(1, 1, "", mem_init_len*4, mem_init_len*2-2); + mem_init(1, 1, "", mem_init_len*4-1, mem_init_len*2-1); + if (WITH_SHARED_MEMORY) { + mem_init(2, 4, "shared", mem_init_len*4, mem_init_len*2-2); + mem_init(2, 4, "shared", mem_init_len*4-1, mem_init_len*2-1); + } + + // We arithmetically overflow the memory limit but not the segment limit + mem_init(1, "", "", Math.floor(mem_init_len/2), 0xFFFFFF00); + + // We arithmetically overflow the segment limit but not the memory limit + mem_init(1, "", "", PAGESIZE, 0xFFFFFFFC); + + // Test that the data segment index is properly encoded as an unsigned (not + // signed) LEB. + print( ` (module - (memory 1) + (memory${decltype} 1) ;; 65 data segments. 64 is the smallest positive number that is encoded ;; differently as a signed LEB. (data "") (data "") (data "") (data "") (data "") (data "") (data "") (data "") @@ -309,4 +312,5 @@ print( (data "") (data "") (data "") (data "") (data "") (data "") (data "") (data "") (data "") (data "") (data "") (data "") (data "") (data "") (data "") (data "") (data "") - (func (memory.init 64 (i32.const 0) (i32.const 0) (i32.const 0))))`) + (func (memory.init 64 (${memtype}.const 0) (i32.const 0) (i32.const 0))))`) +} diff --git a/test/meta/generate_table_copy.js b/test/meta/generate_table_copy.js index f7fd47dcba..8fb0a92245 100644 --- a/test/meta/generate_table_copy.js +++ b/test/meta/generate_table_copy.js @@ -154,16 +154,17 @@ for ( let table of [0,1] ) { // Out-of-bounds checks. -function do_test(insn1, insn2, errText) +function do_test(tt, insn1, insn2, errText) { + const type = tt == 'i64' ? ' i64' : ''; print(` (module - (table $t0 30 30 funcref) - (table $t1 30 30 funcref) - (elem (table $t0) (i32.const 2) func 3 1 4 1) + (table $t0${type} 30 30 funcref) + (table $t1${type} 30 30 funcref) + (elem (table $t0) (${tt}.const 2) func 3 1 4 1) (elem funcref (ref.func 2) (ref.func 7) (ref.func 1) (ref.func 8)) - (elem (table $t0) (i32.const 12) func 7 5 2 3 6) + (elem (table $t0) (${tt}.const 12) func 7 5 2 3 6) (elem funcref (ref.func 5) (ref.func 9) (ref.func 2) (ref.func 7) (ref.func 6)) (func (result i32) (i32.const 0)) @@ -188,72 +189,74 @@ function do_test(insn1, insn2, errText) } } -function tab_test2(insn1, insn2, errKind, errText) { - do_test(insn1, insn2, errKind, errText); +function tab_test2(tt, insn1, insn2, errKind, errText) { + do_test(tt, insn1, insn2, errKind, errText); } -function tab_test_nofail(insn1, insn2) { - do_test(insn1, insn2, undefined, undefined); +function tab_test_nofail(tt, insn1, insn2) { + do_test(tt, insn1, insn2, undefined, undefined); } -for ( let dest of ["$t0","$t1"] ) { - // Here we test the boundary-failure cases. The table's valid indices are 0..29 - // inclusive. - - // copy: dst range invalid - tab_test2(`(table.copy ${dest} $t0 (i32.const 28) (i32.const 1) (i32.const 3))`, - "", - "out of bounds table access"); - - // copy: dst wraparound end of 32 bit offset space - tab_test2(`(table.copy ${dest} $t0 (i32.const 0xFFFFFFFE) (i32.const 1) (i32.const 2))`, - "", - "out of bounds table access"); - - // copy: src range invalid - tab_test2(`(table.copy ${dest} $t0 (i32.const 15) (i32.const 25) (i32.const 6))`, - "", - "out of bounds table access"); - - // copy: src wraparound end of 32 bit offset space - tab_test2(`(table.copy ${dest} $t0 (i32.const 15) (i32.const 0xFFFFFFFE) (i32.const 2))`, - "", - "out of bounds table access"); - - // copy: zero length with both offsets in-bounds is OK - tab_test_nofail( - `(table.copy ${dest} $t0 (i32.const 15) (i32.const 25) (i32.const 0))`, - ""); - - // copy: zero length with dst offset out of bounds at the end of the table is allowed - tab_test2(`(table.copy ${dest} $t0 (i32.const 30) (i32.const 15) (i32.const 0))`, - "", - undefined); - - // copy: zero length with dst offset out of bounds past the end of the table is not allowed - tab_test2(`(table.copy ${dest} $t0 (i32.const 31) (i32.const 15) (i32.const 0))`, - "", - "out of bounds table access"); - - // copy: zero length with src offset out of bounds at the end of the table is allowed - tab_test2(`(table.copy ${dest} $t0 (i32.const 15) (i32.const 30) (i32.const 0))`, - "", - undefined); - - // copy: zero length with src offset out of bounds past the end of the table is not allowed - tab_test2(`(table.copy ${dest} $t0 (i32.const 15) (i32.const 31) (i32.const 0))`, - "", - "out of bounds table access"); - - // copy: zero length with both dst and src offset out of bounds at the end of the table is allowed - tab_test2(`(table.copy ${dest} $t0 (i32.const 30) (i32.const 30) (i32.const 0))`, - "", - undefined); - - // copy: zero length with both dst and src offset out of bounds past the end of the table is not allowed - tab_test2(`(table.copy ${dest} $t0 (i32.const 31) (i32.const 31) (i32.const 0))`, - "", - "out of bounds table access"); +for ( let tt of ["i32", "i64"] ) { + for ( let dest of ["$t0","$t1"] ) { + // Here we test the boundary-failure cases. The table's valid indices are 0..29 + // inclusive. + + // copy: dst range invalid + tab_test2(tt, `(table.copy ${dest} $t0 (${tt}.const 28) (${tt}.const 1) (${tt}.const 3))`, + "", + "out of bounds table access"); + + // copy: dst wraparound end of 32 bit offset space + tab_test2(tt, `(table.copy ${dest} $t0 (${tt}.const 0xFFFFFFFE) (${tt}.const 1) (${tt}.const 2))`, + "", + "out of bounds table access"); + + // copy: src range invalid + tab_test2(tt, `(table.copy ${dest} $t0 (${tt}.const 15) (${tt}.const 25) (${tt}.const 6))`, + "", + "out of bounds table access"); + + // copy: src wraparound end of 32 bit offset space + tab_test2(tt, `(table.copy ${dest} $t0 (${tt}.const 15) (${tt}.const 0xFFFFFFFE) (${tt}.const 2))`, + "", + "out of bounds table access"); + + // copy: zero length with both offsets in-bounds is OK + tab_test_nofail(tt, + `(table.copy ${dest} $t0 (${tt}.const 15) (${tt}.const 25) (${tt}.const 0))`, + ""); + + // copy: zero length with dst offset out of bounds at the end of the table is allowed + tab_test2(tt, `(table.copy ${dest} $t0 (${tt}.const 30) (${tt}.const 15) (${tt}.const 0))`, + "", + undefined); + + // copy: zero length with dst offset out of bounds past the end of the table is not allowed + tab_test2(tt, `(table.copy ${dest} $t0 (${tt}.const 31) (${tt}.const 15) (${tt}.const 0))`, + "", + "out of bounds table access"); + + // copy: zero length with src offset out of bounds at the end of the table is allowed + tab_test2(tt, `(table.copy ${dest} $t0 (${tt}.const 15) (${tt}.const 30) (${tt}.const 0))`, + "", + undefined); + + // copy: zero length with src offset out of bounds past the end of the table is not allowed + tab_test2(tt, `(table.copy ${dest} $t0 (${tt}.const 15) (${tt}.const 31) (${tt}.const 0))`, + "", + "out of bounds table access"); + + // copy: zero length with both dst and src offset out of bounds at the end of the table is allowed + tab_test2(tt, `(table.copy ${dest} $t0 (${tt}.const 30) (${tt}.const 30) (${tt}.const 0))`, + "", + undefined); + + // copy: zero length with both dst and src offset out of bounds past the end of the table is not allowed + tab_test2(tt, `(table.copy ${dest} $t0 (${tt}.const 31) (${tt}.const 31) (${tt}.const 0))`, + "", + "out of bounds table access"); + } } // table.copy: out of bounds of the table for the source or target, but should diff --git a/test/meta/generate_table_init.js b/test/meta/generate_table_init.js index 16b9a84067..5debac4e4a 100644 --- a/test/meta/generate_table_init.js +++ b/test/meta/generate_table_init.js @@ -27,6 +27,7 @@ function emit_a() { // the table entry is empty. function emit_b(insn, table) { + let tt = table == 2 ? 'i64' : 'i32'; print( ` (module @@ -38,10 +39,11 @@ function emit_b(insn, table) { (import "a" "ef4" (func (result i32))) ;; index 4 (table $t0 30 30 funcref) (table $t1 30 30 funcref) - (elem (table $t${table}) (i32.const 2) func 3 1 4 1) + (table $t2 i64 30 30 funcref) + (elem (table $t${table}) (${tt}.const 2) func 3 1 4 1) (elem funcref (ref.func 2) (ref.func 7) (ref.func 1) (ref.func 8)) - (elem (table $t${table}) (i32.const 12) func 7 5 2 3 6) + (elem (table $t${table}) (${tt}.const 12) func 7 5 2 3 6) (elem funcref (ref.func 5) (ref.func 9) (ref.func 2) (ref.func 7) (ref.func 6)) (func (result i32) (i32.const 5)) ;; index 5 @@ -51,7 +53,7 @@ function emit_b(insn, table) { (func (result i32) (i32.const 9)) ;; index 9 (func (export "test") ${insn}) - (func (export "check") (param i32) (result i32) + (func (export "check") (param ${tt}) (result i32) (call_indirect $t${table} (type 0) (local.get 0))) ) `); @@ -65,12 +67,13 @@ function emit_b(insn, table) { function tab_test(instruction, table, expected_result_vector) { emit_b(instruction, table); print(`(invoke "test")`); + let tt = table == 2 ? 'i64' : 'i32'; for (let i = 0; i < expected_result_vector.length; i++) { let expected = expected_result_vector[i]; if (expected === undefined) { - print(`(assert_trap (invoke "check" (i32.const ${i})) "uninitialized element")`); + print(`(assert_trap (invoke "check" (${tt}.const ${i})) "uninitialized element")`); } else { - print(`(assert_return (invoke "check" (i32.const ${i})) (i32.const ${expected}))`); + print(`(assert_return (invoke "check" (${tt}.const ${i})) (i32.const ${expected}))`); } } } @@ -81,28 +84,29 @@ emit_a(); // to count through the vector entries when debugging. let e = undefined; -for ( let table of [0, 1] ) { +for ( let table of [0, 1, 2] ) { + let tt = table == 2 ? 'i64' : 'i32'; // Passive init that overwrites all-null entries - tab_test(`(table.init $t${table} 1 (i32.const 7) (i32.const 0) (i32.const 4))`, + tab_test(`(table.init $t${table} 1 (${tt}.const 7) (i32.const 0) (i32.const 4))`, table, [e,e,3,1,4, 1,e,2,7,1, 8,e,7,5,2, 3,6,e,e,e, e,e,e,e,e, e,e,e,e,e]); // Passive init that overwrites existing active-init-created entries - tab_test(`(table.init $t${table} 3 (i32.const 15) (i32.const 1) (i32.const 3))`, + tab_test(`(table.init $t${table} 3 (${tt}.const 15) (i32.const 1) (i32.const 3))`, table, [e,e,3,1,4, 1,e,e,e,e, e,e,7,5,2, 9,2,7,e,e, e,e,e,e,e, e,e,e,e,e]); // Perform active and passive initialisation and then multiple copies tab_test( - `(table.init $t${table} 1 (i32.const 7) (i32.const 0) (i32.const 4)) + `(table.init $t${table} 1 (${tt}.const 7) (i32.const 0) (i32.const 4)) (elem.drop 1) - (table.init $t${table} 3 (i32.const 15) (i32.const 1) (i32.const 3)) + (table.init $t${table} 3 (${tt}.const 15) (i32.const 1) (i32.const 3)) (elem.drop 3) - (table.copy $t${table} ${table} (i32.const 20) (i32.const 15) (i32.const 5)) - (table.copy $t${table} ${table} (i32.const 21) (i32.const 29) (i32.const 1)) - (table.copy $t${table} ${table} (i32.const 24) (i32.const 10) (i32.const 1)) - (table.copy $t${table} ${table} (i32.const 13) (i32.const 11) (i32.const 4)) - (table.copy $t${table} ${table} (i32.const 19) (i32.const 20) (i32.const 5))`, + (table.copy $t${table} ${table} (${tt}.const 20) (${tt}.const 15) (${tt}.const 5)) + (table.copy $t${table} ${table} (${tt}.const 21) (${tt}.const 29) (${tt}.const 1)) + (table.copy $t${table} ${table} (${tt}.const 24) (${tt}.const 10) (${tt}.const 1)) + (table.copy $t${table} ${table} (${tt}.const 13) (${tt}.const 11) (${tt}.const 4)) + (table.copy $t${table} ${table} (${tt}.const 19) (${tt}.const 20) (${tt}.const 5))`, table, [e,e,3,1,4, 1,e,2,7,1, 8,e,7,e,7, 5,2,7,e,9, e,7,e,8,8, e,e,e,e,e]); }