From 6330e5b5e49f5caf6c7b944ca36bf10c72f74c6b Mon Sep 17 00:00:00 2001 From: Andreas Rossberg Date: Tue, 27 Oct 2020 11:57:18 +0100 Subject: [PATCH 01/17] [spec] automate instruction index rebuild (#1259) --- document/core/Makefile | 8 ++- .../core/appendix/gen-index-instructions.py | 55 +++++++++++++++++++ document/core/appendix/index-instructions.rst | 55 +++++++++++++++++++ 3 files changed, 116 insertions(+), 2 deletions(-) diff --git a/document/core/Makefile b/document/core/Makefile index aaa01b4f9..3ff1a87cb 100644 --- a/document/core/Makefile +++ b/document/core/Makefile @@ -89,8 +89,12 @@ bikeshed-keep: echo Downloaded Bikeshed. +.PHONY: index +index: + (cd appendix; ./gen-index-instructions.py) + .PHONY: pdf -pdf: latexpdf +pdf: index latexpdf mkdir -p $(BUILDDIR)/html/$(DOWNLOADDIR) ln -f $(BUILDDIR)/latex/$(NAME).pdf $(BUILDDIR)/html/$(DOWNLOADDIR)/$(NAME).pdf @@ -101,7 +105,7 @@ clean: rm -rf $(STATICDIR) .PHONY: html -html: +html: index $(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html for file in `ls $(BUILDDIR)/html/*.html`; \ do \ diff --git a/document/core/appendix/gen-index-instructions.py b/document/core/appendix/gen-index-instructions.py index 300f6cbec..bc1b9e23e 100755 --- a/document/core/appendix/gen-index-instructions.py +++ b/document/core/appendix/gen-index-instructions.py @@ -258,6 +258,61 @@ def Instruction(name, opcode, type=None, validation=None, execution=None, operat Instruction(r'\I64.\EXTEND\K{8\_s}', r'\hex{C2}', r'[\I64] \to [\I64]', r'valid-unop', r'exec-unop', r'op-iextendn_s'), Instruction(r'\I64.\EXTEND\K{16\_s}', r'\hex{C3}', r'[\I64] \to [\I64]', r'valid-unop', r'exec-unop', r'op-iextendn_s'), Instruction(r'\I64.\EXTEND\K{32\_s}', r'\hex{C4}', r'[\I64] \to [\I64]', r'valid-unop', r'exec-unop', r'op-iextendn_s'), + Instruction(None, r'\hex{C5}'), + Instruction(None, r'\hex{C6}'), + Instruction(None, r'\hex{C7}'), + Instruction(None, r'\hex{C8}'), + Instruction(None, r'\hex{C9}'), + Instruction(None, r'\hex{CA}'), + Instruction(None, r'\hex{CB}'), + Instruction(None, r'\hex{CC}'), + Instruction(None, r'\hex{CD}'), + Instruction(None, r'\hex{CE}'), + Instruction(None, r'\hex{CF}'), + Instruction(None, r'\hex{D0}'), + Instruction(None, r'\hex{D1}'), + Instruction(None, r'\hex{D2}'), + Instruction(None, r'\hex{D3}'), + Instruction(None, r'\hex{D4}'), + Instruction(None, r'\hex{D5}'), + Instruction(None, r'\hex{D6}'), + Instruction(None, r'\hex{D7}'), + Instruction(None, r'\hex{D8}'), + Instruction(None, r'\hex{D9}'), + Instruction(None, r'\hex{DA}'), + Instruction(None, r'\hex{DB}'), + Instruction(None, r'\hex{DC}'), + Instruction(None, r'\hex{DD}'), + Instruction(None, r'\hex{DE}'), + Instruction(None, r'\hex{DF}'), + Instruction(None, r'\hex{E0}'), + Instruction(None, r'\hex{E1}'), + Instruction(None, r'\hex{E2}'), + Instruction(None, r'\hex{E3}'), + Instruction(None, r'\hex{E4}'), + Instruction(None, r'\hex{E5}'), + Instruction(None, r'\hex{E6}'), + Instruction(None, r'\hex{E7}'), + Instruction(None, r'\hex{E8}'), + Instruction(None, r'\hex{E9}'), + Instruction(None, r'\hex{EA}'), + Instruction(None, r'\hex{EB}'), + Instruction(None, r'\hex{EC}'), + Instruction(None, r'\hex{ED}'), + Instruction(None, r'\hex{EE}'), + Instruction(None, r'\hex{EF}'), + Instruction(None, r'\hex{F0}'), + Instruction(None, r'\hex{F1}'), + Instruction(None, r'\hex{F2}'), + Instruction(None, r'\hex{F3}'), + Instruction(None, r'\hex{F4}'), + Instruction(None, r'\hex{F5}'), + Instruction(None, r'\hex{F6}'), + Instruction(None, r'\hex{F7}'), + Instruction(None, r'\hex{F8}'), + Instruction(None, r'\hex{F9}'), + Instruction(None, r'\hex{FA}'), + Instruction(None, r'\hex{FB}'), Instruction(r'\I32.\TRUNC\K{\_sat\_}\F32\K{\_s}', r'\hex{FC}~~0', r'[\F32] \to [\I32]', r'valid-cvtop', r'exec-cvtop', r'op-trunc_sat_s'), Instruction(r'\I32.\TRUNC\K{\_sat\_}\F32\K{\_u}', r'\hex{FC}~~1', r'[\F32] \to [\I32]', r'valid-cvtop', r'exec-cvtop', r'op-trunc_sat_u'), Instruction(r'\I32.\TRUNC\K{\_sat\_}\F64\K{\_s}', r'\hex{FC}~~2', r'[\F64] \to [\I32]', r'valid-cvtop', r'exec-cvtop', r'op-trunc_sat_s'), diff --git a/document/core/appendix/index-instructions.rst b/document/core/appendix/index-instructions.rst index 686f67674..cb988b288 100644 --- a/document/core/appendix/index-instructions.rst +++ b/document/core/appendix/index-instructions.rst @@ -206,6 +206,61 @@ Instruction Binary Opcode Type :math:`\I64.\EXTEND\K{8\_s}` :math:`\hex{C2}` :math:`[\I64] \to [\I64]` :ref:`validation ` :ref:`execution `, :ref:`operator ` :math:`\I64.\EXTEND\K{16\_s}` :math:`\hex{C3}` :math:`[\I64] \to [\I64]` :ref:`validation ` :ref:`execution `, :ref:`operator ` :math:`\I64.\EXTEND\K{32\_s}` :math:`\hex{C4}` :math:`[\I64] \to [\I64]` :ref:`validation ` :ref:`execution `, :ref:`operator ` +(reserved) :math:`\hex{C5}` +(reserved) :math:`\hex{C6}` +(reserved) :math:`\hex{C7}` +(reserved) :math:`\hex{C8}` +(reserved) :math:`\hex{C9}` +(reserved) :math:`\hex{CA}` +(reserved) :math:`\hex{CB}` +(reserved) :math:`\hex{CC}` +(reserved) :math:`\hex{CD}` +(reserved) :math:`\hex{CE}` +(reserved) :math:`\hex{CF}` +(reserved) :math:`\hex{D0}` +(reserved) :math:`\hex{D1}` +(reserved) :math:`\hex{D2}` +(reserved) :math:`\hex{D3}` +(reserved) :math:`\hex{D4}` +(reserved) :math:`\hex{D5}` +(reserved) :math:`\hex{D6}` +(reserved) :math:`\hex{D7}` +(reserved) :math:`\hex{D8}` +(reserved) :math:`\hex{D9}` +(reserved) :math:`\hex{DA}` +(reserved) :math:`\hex{DB}` +(reserved) :math:`\hex{DC}` +(reserved) :math:`\hex{DD}` +(reserved) :math:`\hex{DE}` +(reserved) :math:`\hex{DF}` +(reserved) :math:`\hex{E0}` +(reserved) :math:`\hex{E1}` +(reserved) :math:`\hex{E2}` +(reserved) :math:`\hex{E3}` +(reserved) :math:`\hex{E4}` +(reserved) :math:`\hex{E5}` +(reserved) :math:`\hex{E6}` +(reserved) :math:`\hex{E7}` +(reserved) :math:`\hex{E8}` +(reserved) :math:`\hex{E9}` +(reserved) :math:`\hex{EA}` +(reserved) :math:`\hex{EB}` +(reserved) :math:`\hex{EC}` +(reserved) :math:`\hex{ED}` +(reserved) :math:`\hex{EE}` +(reserved) :math:`\hex{EF}` +(reserved) :math:`\hex{F0}` +(reserved) :math:`\hex{F1}` +(reserved) :math:`\hex{F2}` +(reserved) :math:`\hex{F3}` +(reserved) :math:`\hex{F4}` +(reserved) :math:`\hex{F5}` +(reserved) :math:`\hex{F6}` +(reserved) :math:`\hex{F7}` +(reserved) :math:`\hex{F8}` +(reserved) :math:`\hex{F9}` +(reserved) :math:`\hex{FA}` +(reserved) :math:`\hex{FB}` :math:`\I32.\TRUNC\K{\_sat\_}\F32\K{\_s}` :math:`\hex{FC}~~0` :math:`[\F32] \to [\I32]` :ref:`validation ` :ref:`execution `, :ref:`operator ` :math:`\I32.\TRUNC\K{\_sat\_}\F32\K{\_u}` :math:`\hex{FC}~~1` :math:`[\F32] \to [\I32]` :ref:`validation ` :ref:`execution `, :ref:`operator ` :math:`\I32.\TRUNC\K{\_sat\_}\F64\K{\_s}` :math:`\hex{FC}~~2` :math:`[\F64] \to [\I32]` :ref:`validation ` :ref:`execution `, :ref:`operator ` From eae22f678a26cc9a44e8f2eadf67858d181def55 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Bylica?= Date: Mon, 2 Nov 2020 12:55:36 +0100 Subject: [PATCH 02/17] [test] Add test for malformed functype (#1254) --- test/core/binary.wast | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/test/core/binary.wast b/test/core/binary.wast index 8b5bcfc4c..badb34bd7 100644 --- a/test/core/binary.wast +++ b/test/core/binary.wast @@ -52,6 +52,20 @@ (assert_malformed (module binary "\00asm" "\01\00\00\00" "\ff\00\01\00") "malformed section id") +;; Type section with signed LEB128 encoded type +(assert_malformed + (module binary + "\00asm" "\01\00\00\00" + "\01" ;; Type section id + "\05" ;; Type section length + "\01" ;; Types vector length + "\e0\7f" ;; Malformed functype, -0x20 in signed LEB128 encoding + "\00\00" + ) + "integer representation too long" +) + + ;; call_indirect reserved byte equal to zero. (assert_malformed (module binary From 780479ff242701186dc488552224eab8e2569c93 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Bylica?= Date: Tue, 10 Nov 2020 09:40:28 +0100 Subject: [PATCH 03/17] [test] Correct tests for missing elements (#1251) Remove the code section in tests for malformed element section. Otherwise the code section id (0x0a) is taken as an element's table index what is a validation error. This is similar to the previously reported issue: https://github.com/WebAssembly/spec/issues/1170. --- test/core/binary.wast | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/test/core/binary.wast b/test/core/binary.wast index badb34bd7..fd188d760 100644 --- a/test/core/binary.wast +++ b/test/core/binary.wast @@ -787,8 +787,23 @@ "\09\07\02" ;; elem with inconsistent segment count (2 declared, 1 given) "\00\41\00\0b\01\00" ;; elem 0 ;; "\00\41\00\0b\01\00" ;; elem 1 (missed) - "\0a\04\01" ;; code section - "\02\00\0b" ;; function body + ) + "unexpected end" +) + +;; 2 elem segment declared, 1.5 given +(assert_malformed + (module binary + "\00asm" "\01\00\00\00" + "\01\04\01" ;; type section + "\60\00\00" ;; type 0 + "\03\02\01\00" ;; func section + "\04\04\01" ;; table section + "\70\00\01" ;; table 0 + "\09\07\02" ;; elem with inconsistent segment count (2 declared, 1 given) + "\00\41\00\0b\01\00" ;; elem 0 + "\00\41\00" ;; elem 1 (partial) + ;; "\0b\01\00" ;; elem 1 (missing part) ) "unexpected end" ) From 02a6f4fffe7bbbeaa8c74b6927374abe435ecef4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Bylica?= Date: Tue, 10 Nov 2020 17:25:07 +0100 Subject: [PATCH 04/17] [test] Add tests for data segment with memidx 1 (#1249) --- test/core/data.wast | 63 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 63 insertions(+) diff --git a/test/core/data.wast b/test/core/data.wast index 7d6945417..d65abf36f 100644 --- a/test/core/data.wast +++ b/test/core/data.wast @@ -286,6 +286,69 @@ "unknown memory" ) +;; Data segment with memory index 1 (only memory 0 available) +(assert_invalid + (module binary + "\00asm" "\01\00\00\00" + "\05\03\01" ;; memory section + "\00\00" ;; memory 0 + "\0b\06\01" ;; data section + "\01\41\00\0b" ;; data segment 0 for memory 1 + "\00" ;; empty vec(byte) + ) + "unknown memory 1" +) + +;; Data segment with memory index 1 (no memory section) +(assert_invalid + (module binary + "\00asm" "\01\00\00\00" + "\0b\06\01" ;; data section + "\01\41\00\0b" ;; data segment 0 for memory 1 + "\00" ;; empty vec(byte) + ) + "unknown memory 1" +) + +;; Data segment with memory index 1 and vec(byte) as above, +;; only memory 0 available. +(assert_invalid + (module binary + "\00asm" "\01\00\00\00" + "\05\03\01" ;; memory section + "\00\00" ;; memory 0 + "\0b\44\01" ;; data section + "\01" ;; memory index + "\41\00\0b" ;; offset constant expression + "\3e" ;; vec(byte) length + "\00\01\02\03\04\05\06\07\08\09\0a\0b\0c\0d\0e\0f" + "\10\11\12\13\14\15\16\17\18\19\1a\1b\1c\1d\1e\1f" + "\20\21\22\23\24\25\26\27\28\29\2a\2b\2c\2d\2e\2f" + "\30\31\32\33\34\35\36\37\38\39\3a\3b\3c\3d" + ) + "unknown memory 1" +) + +;; Data segment with memory index 1 and specially crafted vec(byte) after. +;; This is to detect incorrect validation where memory index is interpreted +;; as a flag followed by "\41" interpreted as the size of vec(byte) +;; with the expected number of bytes following. +(assert_invalid + (module binary + "\00asm" "\01\00\00\00" + "\0b\44\01" ;; data section + "\01" ;; memory index + "\41\00\0b" ;; offset constant expression + "\3e" ;; vec(byte) length + "\00\01\02\03\04\05\06\07\08\09\0a\0b\0c\0d\0e\0f" + "\10\11\12\13\14\15\16\17\18\19\1a\1b\1c\1d\1e\1f" + "\20\21\22\23\24\25\26\27\28\29\2a\2b\2c\2d\2e\2f" + "\30\31\32\33\34\35\36\37\38\39\3a\3b\3c\3d" + ) + "unknown memory 1" +) + + ;; Invalid offsets (assert_invalid From 5475b7015684a07ba69762f8438e3bcff2647686 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Bylica?= Date: Thu, 12 Nov 2020 08:36:08 +0100 Subject: [PATCH 05/17] [test] Correct i32.store alignment in a LEB128 test (#1261) In the binary-leb128.wast, change the alignment of an i32.store instruction from 3 (invalid) to 2 (the intention suggested by the comment). --- test/core/binary-leb128.wast | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/core/binary-leb128.wast b/test/core/binary-leb128.wast index cd39a5d2c..8503c9ae9 100644 --- a/test/core/binary-leb128.wast +++ b/test/core/binary-leb128.wast @@ -852,7 +852,7 @@ "\41\00" ;; i32.const 0 "\41\03" ;; i32.const 3 "\36" ;; i32.store - "\03" ;; alignment 2 + "\02" ;; alignment 2 "\82\80\80\80\10" ;; offset 2 with unused bits set "\0b" ;; end ) From 4d112b9321537d97a46886bf583d5993f38de34d Mon Sep 17 00:00:00 2001 From: Ms2ger Date: Fri, 8 Jan 2021 15:37:44 +0100 Subject: [PATCH 06/17] [js-api] Better null handling in table.get/set. --- document/js-api/index.bs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/document/js-api/index.bs b/document/js-api/index.bs index 9af7e6962..91fc50985 100644 --- a/document/js-api/index.bs +++ b/document/js-api/index.bs @@ -792,6 +792,7 @@ Each {{Table}} object has a \[[Table]] internal slot, which is a [=table address 1. Let |store| be the [=surrounding agent=]'s [=associated store=]. 1. Let |result| be [=table_read=](|store|, |tableaddr|, |index|). 1. If |result| is [=error=], throw a {{RangeError}} exception. + 1. If |result| is ε, return null. 1. Let |function| be the result of creating [=a new Exported Function=] from |result|. 1. Return |function|. @@ -799,7 +800,7 @@ 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. If |value| is null, let |funcaddr| be an empty [=function element=]. + 1. If |value| is null, let |funcaddr| be ε. 1. Otherwise, 1. If |value| does not have a \[[FunctionAddress]] internal slot, throw a {{TypeError}} exception. 1. Let |funcaddr| be |value|.\[[FunctionAddress]]. From 6b67f2b6410f1994a2f1bd1f631af1ec2ae1360a Mon Sep 17 00:00:00 2001 From: Andrei Maiboroda Date: Thu, 30 Jul 2020 13:15:05 +0200 Subject: [PATCH 07/17] [test] Add tests for exporting nonexistent function, global, table, memory --- test/core/exports.wast | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/test/core/exports.wast b/test/core/exports.wast index ef1c4c17e..0c44694db 100644 --- a/test/core/exports.wast +++ b/test/core/exports.wast @@ -25,10 +25,18 @@ (module $Other1) (assert_return (invoke $Func "e" (i32.const 42)) (i32.const 43)) +(assert_invalid + (module (export "a" (func 0))) + "unknown function" +) (assert_invalid (module (func) (export "a" (func 1))) "unknown function" ) +(assert_invalid + (module (import "spectest" "print_i32" (func (param i32))) (export "a" (func 1))) + "unknown function" +) (assert_invalid (module (func) (export "a" (func 0)) (export "a" (func 0))) "duplicate export name" @@ -74,10 +82,18 @@ (module $Other2) (assert_return (get $Global "e") (i32.const 42)) +(assert_invalid + (module (export "a" (global 0))) + "unknown global" +) (assert_invalid (module (global i32 (i32.const 0)) (export "a" (global 1))) "unknown global" ) +(assert_invalid + (module (import "spectest" "global_i32" (global i32)) (export "a" (global 1))) + "unknown global" +) (assert_invalid (module (global i32 (i32.const 0)) (export "a" (global 0)) (export "a" (global 0))) "duplicate export name" @@ -122,10 +138,18 @@ (; TODO: access table ;) +(assert_invalid + (module (export "a" (table 0))) + "unknown table" +) (assert_invalid (module (table 0 funcref) (export "a" (table 1))) "unknown table" ) +(assert_invalid + (module (import "spectest" "table" (table 10 20 funcref)) (export "a" (table 1))) + "unknown table" +) (assert_invalid (module (table 0 funcref) (export "a" (table 0)) (export "a" (table 0))) "duplicate export name" @@ -171,10 +195,18 @@ (; TODO: access memory ;) +(assert_invalid + (module (export "a" (memory 0))) + "unknown memory" +) (assert_invalid (module (memory 0) (export "a" (memory 1))) "unknown memory" ) +(assert_invalid + (module (import "spectest" "memory" (memory 1 2)) (export "a" (memory 1))) + "unknown memory" +) (assert_invalid (module (memory 0) (export "a" (memory 0)) (export "a" (memory 0))) "duplicate export name" From 04c324bd6ddd5b44e39e7ef8bdc07979e53a2c62 Mon Sep 17 00:00:00 2001 From: Andrei Maiboroda Date: Mon, 11 Jan 2021 16:46:05 +0100 Subject: [PATCH 08/17] [test] Add invalid cases with globals access (#1267) --- test/core/global.wast | 67 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 67 insertions(+) diff --git a/test/core/global.wast b/test/core/global.wast index ef1fccbbd..5241eb6e6 100644 --- a/test/core/global.wast +++ b/test/core/global.wast @@ -244,6 +244,11 @@ "global is immutable" ) +(assert_invalid + (module (import "spectest" "global_i32" (global i32)) (func (global.set 0 (i32.const 1)))) + "global is immutable" +) + ;; mutable globals can be exported (module (global (mut f32) (f32.const 0)) (export "a" (global 0))) (module (global (export "a") (mut f32) (f32.const 0))) @@ -356,6 +361,68 @@ "malformed mutability" ) +;; global.get with invalid index +(assert_invalid + (module (func (result i32) (global.get 0))) + "unknown global" +) + +(assert_invalid + (module + (global i32 (i32.const 0)) + (func (result i32) (global.get 1)) + ) + "unknown global" +) + +(assert_invalid + (module + (import "spectest" "global_i32" (global i32)) + (func (result i32) (global.get 1)) + ) + "unknown global" +) + +(assert_invalid + (module + (import "spectest" "global_i32" (global i32)) + (global i32 (i32.const 0)) + (func (result i32) (global.get 2)) + ) + "unknown global" +) + +;; global.set with invalid index +(assert_invalid + (module (func (i32.const 0) (global.set 0))) + "unknown global" +) + +(assert_invalid + (module + (global i32 (i32.const 0)) + (func (i32.const 0) (global.set 1)) + ) + "unknown global" +) + +(assert_invalid + (module + (import "spectest" "global_i32" (global i32)) + (func (i32.const 0) (global.set 1)) + ) + "unknown global" +) + +(assert_invalid + (module + (import "spectest" "global_i32" (global i32)) + (global i32 (i32.const 0)) + (func (i32.const 0) (global.set 2)) + ) + "unknown global" +) + (assert_invalid (module From 80095c78b2dc65ed64e1f5f4514749e04ac9a4dc Mon Sep 17 00:00:00 2001 From: Andrei Maiboroda Date: Wed, 13 Jan 2021 19:35:04 +0100 Subject: [PATCH 09/17] [test] Fix invalid index cases for local.tee and local.get (#1271) --- test/core/local_get.wast | 12 ++++++------ test/core/local_tee.wast | 38 +++++++++++++++++++------------------- 2 files changed, 25 insertions(+), 25 deletions(-) diff --git a/test/core/local_get.wast b/test/core/local_get.wast index ab564cbed..6acab3988 100644 --- a/test/core/local_get.wast +++ b/test/core/local_get.wast @@ -198,29 +198,29 @@ ;; Invalid local index (assert_invalid - (module (func $unbound-local (local i32 i64) (local.get 3))) + (module (func $unbound-local (local i32 i64) (local.get 3) drop)) "unknown local" ) (assert_invalid - (module (func $large-local (local i32 i64) (local.get 14324343))) + (module (func $large-local (local i32 i64) (local.get 14324343) drop)) "unknown local" ) (assert_invalid - (module (func $unbound-param (param i32 i64) (local.get 2))) + (module (func $unbound-param (param i32 i64) (local.get 2) drop)) "unknown local" ) (assert_invalid - (module (func $large-param (param i32 i64) (local.get 714324343))) + (module (func $large-param (param i32 i64) (local.get 714324343) drop)) "unknown local" ) (assert_invalid - (module (func $unbound-mixed (param i32) (local i32 i64) (local.get 3))) + (module (func $unbound-mixed (param i32) (local i32 i64) (local.get 3) drop)) "unknown local" ) (assert_invalid - (module (func $large-mixed (param i64) (local i32 i64) (local.get 214324343))) + (module (func $large-mixed (param i64) (local i32 i64) (local.get 214324343) drop)) "unknown local" ) diff --git a/test/core/local_tee.wast b/test/core/local_tee.wast index dde7321ec..a158f0c7c 100644 --- a/test/core/local_tee.wast +++ b/test/core/local_tee.wast @@ -595,45 +595,45 @@ "type mismatch" ) - -;; Invalid local index - (assert_invalid - (module (func $unbound-local (local i32 i64) (local.get 3))) - "unknown local" + (module (func $type-mixed-arg-num-vs-num (param f32) (local i32) (local.tee 1 (f32.const 0)))) + "type mismatch" ) (assert_invalid - (module (func $large-local (local i32 i64) (local.get 14324343))) - "unknown local" + (module (func $type-mixed-arg-num-vs-num (param i64 i32) (local f32) (local.tee 1 (f32.const 0)))) + "type mismatch" +) +(assert_invalid + (module (func $type-mixed-arg-num-vs-num (param i64) (local f64 i64) (local.tee 1 (i64.const 0)))) + "type mismatch" ) + +;; Invalid local index + (assert_invalid - (module (func $unbound-param (param i32 i64) (local.get 2))) + (module (func $unbound-local (local i32 i64) (local.tee 3 (i32.const 0)) drop)) "unknown local" ) (assert_invalid - (module (func $large-param (local i32 i64) (local.get 714324343))) + (module (func $large-local (local i32 i64) (local.tee 14324343 (i32.const 0)) drop)) "unknown local" ) (assert_invalid - (module (func $unbound-mixed (param i32) (local i32 i64) (local.get 3))) + (module (func $unbound-param (param i32 i64) (local.tee 2 (i32.const 0)) drop)) "unknown local" ) (assert_invalid - (module (func $large-mixed (param i64) (local i32 i64) (local.get 214324343))) + (module (func $large-param (param i32 i64) (local.tee 714324343 (i32.const 0)) drop)) "unknown local" ) (assert_invalid - (module (func $type-mixed-arg-num-vs-num (param f32) (local i32) (local.tee 1 (f32.const 0)))) - "type mismatch" -) -(assert_invalid - (module (func $type-mixed-arg-num-vs-num (param i64 i32) (local f32) (local.tee 1 (f32.const 0)))) - "type mismatch" + (module (func $unbound-mixed (param i32) (local i32 i64) (local.tee 3 (i32.const 0)) drop)) + "unknown local" ) (assert_invalid - (module (func $type-mixed-arg-num-vs-num (param i64) (local f64 i64) (local.tee 1 (i64.const 0)))) - "type mismatch" + (module (func $large-mixed (param i64) (local i32 i64) (local.tee 214324343 (i32.const 0)) drop)) + "unknown local" ) From 7d21686da3bd5d1114c4db4e86c29826fbfe1e02 Mon Sep 17 00:00:00 2001 From: Andrei Maiboroda Date: Wed, 13 Jan 2021 19:42:10 +0100 Subject: [PATCH 10/17] [test] Add tests for validating imported globals (#1273) --- test/core/imports.wast | 51 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 51 insertions(+) diff --git a/test/core/imports.wast b/test/core/imports.wast index 2f0200dc3..187e0afb9 100644 --- a/test/core/imports.wast +++ b/test/core/imports.wast @@ -10,6 +10,7 @@ (func (export "func-i64->i64") (param i64) (result i64) (local.get 0)) (global (export "global-i32") i32 (i32.const 55)) (global (export "global-f32") f32 (f32.const 44)) + (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) (memory (export "memory-2-inf") 2) @@ -230,6 +231,7 @@ (module (import "test" "global-i32" (global i32))) (module (import "test" "global-f32" (global f32))) +(module (import "test" "global-mut-i64" (global (mut i64)))) (assert_unlinkable (module (import "test" "unknown" (global i32))) @@ -240,6 +242,55 @@ "unknown import" ) +(assert_unlinkable + (module (import "test" "global-i32" (global i64))) + "incompatible import type" +) +(assert_unlinkable + (module (import "test" "global-i32" (global f32))) + "incompatible import type" +) +(assert_unlinkable + (module (import "test" "global-i32" (global f64))) + "incompatible import type" +) +(assert_unlinkable + (module (import "test" "global-i32" (global (mut i32)))) + "incompatible import type" +) +(assert_unlinkable + (module (import "test" "global-f32" (global i32))) + "incompatible import type" +) +(assert_unlinkable + (module (import "test" "global-f32" (global i64))) + "incompatible import type" +) +(assert_unlinkable + (module (import "test" "global-f32" (global f64))) + "incompatible import type" +) +(assert_unlinkable + (module (import "test" "global-f32" (global (mut f32)))) + "incompatible import type" +) +(assert_unlinkable + (module (import "test" "global-mut-i64" (global (mut i32)))) + "incompatible import type" +) +(assert_unlinkable + (module (import "test" "global-mut-i64" (global (mut f32)))) + "incompatible import type" +) +(assert_unlinkable + (module (import "test" "global-mut-i64" (global (mut f64)))) + "incompatible import type" +) +(assert_unlinkable + (module (import "test" "global-mut-i64" (global i64))) + "incompatible import type" +) + (assert_unlinkable (module (import "test" "func" (global i32))) "incompatible import type" From 4339e90f995019464b02513c2b11a33e0e7b3874 Mon Sep 17 00:00:00 2001 From: Andrei Maiboroda Date: Wed, 13 Jan 2021 19:58:20 +0100 Subject: [PATCH 11/17] [test] Add invalid cases with br_table type mismatch (#1268) --- test/core/br_table.wast | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/test/core/br_table.wast b/test/core/br_table.wast index 58abe38a4..d03068744 100644 --- a/test/core/br_table.wast +++ b/test/core/br_table.wast @@ -1464,6 +1464,16 @@ )) "type mismatch" ) +(assert_invalid + (module (func + (block (result i32) + (block (result i64) + (br_table 0 1 (i32.const 0) (i32.const 0)) + ) + ) + )) + "type mismatch" +) (assert_invalid (module (func $type-index-void-vs-i32 @@ -1552,6 +1562,31 @@ "type mismatch" ) +(assert_invalid + (module + (func (param i32) (result i32) + (loop (result i32) + (block (result i32) + (br_table 0 1 (i32.const 1) (local.get 0)) + ) + ) + ) + ) + "type mismatch" +) +(assert_invalid + (module + (func (param i32) (result i32) + (block (result i32) + (loop (result i32) + (br_table 0 1 (i32.const 1) (local.get 0)) + ) + ) + ) + ) + "type mismatch" +) + (assert_invalid (module (func $unbound-label From 9ff8601dc397d676a8d104c70eb3b64c2142189d Mon Sep 17 00:00:00 2001 From: Andreas Rossberg Date: Wed, 20 Jan 2021 10:34:09 +0100 Subject: [PATCH 12/17] [interpreter] Document spectest (#1280) --- interpreter/README.md | 30 ++++++++++++++++++++++++++++++ interpreter/host/spectest.ml | 6 ++++-- 2 files changed, 34 insertions(+), 2 deletions(-) diff --git a/interpreter/README.md b/interpreter/README.md index 54b9fd004..feb99bd0d 100644 --- a/interpreter/README.md +++ b/interpreter/README.md @@ -363,6 +363,36 @@ The `input` and `output` meta commands determine the requested file format from The interpreter supports a "dry" mode (flag `-d`), in which modules are only validated. In this mode, all actions and assertions are ignored. It also supports an "unchecked" mode (flag `-u`), in which module definitions are not validated before use. + +### Spectest host module + +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) + + (table (export "table") 10 20 funcref) + + (memory (export "memory") 1 2) + + (func (export "print")) + (func (export "print_i32") (param i32)) + (func (export "print_i64") (param i64)) + (func (export "print_f32") (param f32)) + (func (export "print_f64") (param f64)) + (func (export "print_i32_f32") (param i32 f32)) + (func (export "print_f64_f64") (param f64 f64)) +) +``` +The `print` functions are assumes to print their respective argument values to stdout (followed by a newline) and can be used to produce observable output. + +Note: This module predates the `register` command and should no longer be needed for new tests. +We might remove it in the future, so consider it deprecated. + + ### Binary Scripts The grammar of binary scripts is a subset of the grammar for general scripts: diff --git a/interpreter/host/spectest.ml b/interpreter/host/spectest.ml index 78f3e994a..9d6ff9a43 100644 --- a/interpreter/host/spectest.ml +++ b/interpreter/host/spectest.ml @@ -34,13 +34,15 @@ let lookup name t = match Utf8.encode name, t with | "print", _ -> ExternFunc (func print (FuncType ([], []))) | "print_i32", _ -> ExternFunc (func print (FuncType ([I32Type], []))) + | "print_i64", _ -> ExternFunc (func print (FuncType ([I64Type], []))) + | "print_f32", _ -> ExternFunc (func print (FuncType ([F32Type], []))) + | "print_f64", _ -> ExternFunc (func print (FuncType ([F64Type], []))) | "print_i32_f32", _ -> ExternFunc (func print (FuncType ([I32Type; F32Type], []))) | "print_f64_f64", _ -> ExternFunc (func print (FuncType ([F64Type; F64Type], []))) - | "print_f32", _ -> ExternFunc (func print (FuncType ([F32Type], []))) - | "print_f64", _ -> ExternFunc (func print (FuncType ([F64Type], []))) | "global_i32", _ -> ExternGlobal (global (GlobalType (I32Type, Immutable))) + | "global_i64", _ -> ExternGlobal (global (GlobalType (I64Type, Immutable))) | "global_f32", _ -> ExternGlobal (global (GlobalType (F32Type, Immutable))) | "global_f64", _ -> ExternGlobal (global (GlobalType (F64Type, Immutable))) | "table", _ -> ExternTable table From 3957c7dd3930b299e819f4c9c1d1dd4e7ae23b26 Mon Sep 17 00:00:00 2001 From: Andrei Maiboroda Date: Wed, 20 Jan 2021 10:42:33 +0100 Subject: [PATCH 13/17] [test] Add cases checking maximum allowed number of locals (#1272) --- test/core/binary.wast | 37 ++++++++++++++++++++++++++++++++++++- 1 file changed, 36 insertions(+), 1 deletion(-) diff --git a/test/core/binary.wast b/test/core/binary.wast index fd188d760..8f2e2ba80 100644 --- a/test/core/binary.wast +++ b/test/core/binary.wast @@ -350,7 +350,24 @@ "zero flag expected" ) -;; No more than 2^32 locals. +;; Local number is unsigned 32 bit +(assert_malformed + (module binary + "\00asm" "\01\00\00\00" + "\01\04\01\60\00\00" ;; Type section + "\03\02\01\00" ;; Function section + "\0a\0c\01" ;; Code section + + ;; function 0 + "\0a\02" + "\80\80\80\80\10\7f" ;; 0x100000000 i32 + "\02\7e" ;; 0x00000002 i64 + "\0b" ;; end + ) + "integer too large" +) + +;; No more than 2^32-1 locals. (assert_malformed (module binary "\00asm" "\01\00\00\00" @@ -367,6 +384,24 @@ "too many locals" ) +(assert_malformed + (module binary + "\00asm" "\01\00\00\00" + "\01\06\01\60\02\7f\7f\00" ;; Type section: (param i32 i32) + "\03\02\01\00" ;; Function section + "\0a\1c\01" ;; Code section + + ;; function 0 + "\1a\04" + "\80\80\80\80\04\7f" ;; 0x40000000 i32 + "\80\80\80\80\04\7e" ;; 0x40000000 i64 + "\80\80\80\80\04\7d" ;; 0x40000000 f32 + "\80\80\80\80\04\7c" ;; 0x40000000 f64 + "\0b" ;; end + ) + "too many locals" +) + ;; Local count can be 0. (module binary "\00asm" "\01\00\00\00" From 9db08d78b7da2c627de533316dbeb483700730c3 Mon Sep 17 00:00:00 2001 From: Ms2ger Date: Wed, 20 Jan 2021 09:20:45 +0100 Subject: [PATCH 14/17] [web-api] Update media-type registration for review. See #573. --- document/web-api/index.bs | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/document/web-api/index.bs b/document/web-api/index.bs index 564dd6ee0..3cc610820 100644 --- a/document/web-api/index.bs +++ b/document/web-api/index.bs @@ -253,17 +253,27 @@ application/wasm
Encoding Considerations:
binary
Security Considerations:
-
See see WebAssembly Core Security Considerations
- https://www.w3.org/TR/wasm-core/#security-considerations%E2%91%A0
+
+

WebAssembly is a standard, a safe, portable, low-level code format. The + security considerations associated with executing WebAssembly code are + described in https://www.w3.org/TR/wasm-core/#security-considerations.

+

The WebAssembly format includes no integrity or privacy protection. If + such protection is needed it must be provided externally, e.g., through + the use of HTTPS.

+
Interoperability Considerations:
-
See see WebAssembly Core Conformance
+
See WebAssembly Core Conformance
https://www.w3.org/TR/wasm-core/#conformance
Published specification:
- https://www.w3.org/TR/wasm-core-1/ +
https://www.w3.org/TR/wasm-core-1/ https://www.w3.org/TR/wasm-js-api-1/ - https://www.w3.org/TR/wasm-web-api-1/ + https://www.w3.org/TR/wasm-web-api-1/
Application Usage:
-
The application/wasm media type is already in use as the type used to describe WebAssembly files when sent over HTTP to be executed by browsers, which is a common scenario. Additionally, several WebAssembly runtimes that take advantage of the safety and portability while targeting efficient execution and compact representation.
+
The application/wasm media type is intended for use as the type used to + describe WebAssembly files when sent over HTTP to be executed by browsers, + which is a common scenario. Additionally, the type is used by several + WebAssembly runtimes that take advantage of the safety and portability + while targeting efficient execution and compact representation.
Fragment Identifier Considerations:
None
Restrictions on usage:
From c0b7eb03fff96b429f35b62fac192a7ba5af638e Mon Sep 17 00:00:00 2001 From: Zhi An Ng Date: Thu, 17 Dec 2020 06:55:53 +0000 Subject: [PATCH 15/17] Fix usage of extend in t.load and t.loadN_sx extend\F{\_}\sx isn't an operator, but extend_\sx is. --- document/core/exec/instructions.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/document/core/exec/instructions.rst b/document/core/exec/instructions.rst index 9dc6727f4..b783f5d94 100644 --- a/document/core/exec/instructions.rst +++ b/document/core/exec/instructions.rst @@ -424,7 +424,7 @@ Memory Instructions a. Let :math:`n` be the integer for which :math:`\bytes_{\iN}(n) = b^\ast`. - b. Let :math:`c` be the result of computing :math:`\extend\F{\_}\sx_{N,|t|}(n)`. + b. Let :math:`c` be the result of computing :math:`\extend^\sx_{N,|t|}(n)`. 13. Else: @@ -447,7 +447,7 @@ Memory Instructions \\[1ex] \begin{array}{lcl@{\qquad}l} S; F; (\I32.\CONST~i)~(t.\LOAD{N}\K{\_}\sx~\memarg) &\stepto& - S; F; (t.\CONST~\extend\F{\_}\sx_{N,|t|}(n)) + S; F; (t.\CONST~\extend^\sx_{N,|t|}(n)) \end{array} \\ \qquad \begin{array}[t]{@{}r@{~}l@{}} From 397bb5358c8c5ed776d103718a7603922b81374c Mon Sep 17 00:00:00 2001 From: Ng Zhi An Date: Thu, 21 Jan 2021 09:39:14 -0800 Subject: [PATCH 16/17] Missed the braces --- document/core/exec/instructions.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/document/core/exec/instructions.rst b/document/core/exec/instructions.rst index b783f5d94..c54a8fc94 100644 --- a/document/core/exec/instructions.rst +++ b/document/core/exec/instructions.rst @@ -424,7 +424,7 @@ Memory Instructions a. Let :math:`n` be the integer for which :math:`\bytes_{\iN}(n) = b^\ast`. - b. Let :math:`c` be the result of computing :math:`\extend^\sx_{N,|t|}(n)`. + b. Let :math:`c` be the result of computing :math:`\extend^{\sx}_{N,|t|}(n)`. 13. Else: @@ -447,7 +447,7 @@ Memory Instructions \\[1ex] \begin{array}{lcl@{\qquad}l} S; F; (\I32.\CONST~i)~(t.\LOAD{N}\K{\_}\sx~\memarg) &\stepto& - S; F; (t.\CONST~\extend^\sx_{N,|t|}(n)) + S; F; (t.\CONST~\extend^{\sx}_{N,|t|}(n)) \end{array} \\ \qquad \begin{array}[t]{@{}r@{~}l@{}} From a21888d9569810ee04cbd7ae6f271f4a98579322 Mon Sep 17 00:00:00 2001 From: Andrei Maiboroda Date: Tue, 26 Jan 2021 09:53:51 +0100 Subject: [PATCH 17/17] [test] Add tests for validating constant expressions (#1281) --- test/core/data.wast | 60 ++++++++++++++++++++++++++++++++++++++++++ test/core/elem.wast | 61 +++++++++++++++++++++++++++++++++++++++++++ test/core/global.wast | 25 ++++++++++++++++++ 3 files changed, 146 insertions(+) diff --git a/test/core/data.wast b/test/core/data.wast index d65abf36f..e840a9467 100644 --- a/test/core/data.wast +++ b/test/core/data.wast @@ -359,6 +359,40 @@ "type mismatch" ) +(assert_invalid + (module + (memory 1) + (data (offset (;empty instruction sequence;))) + ) + "type mismatch" +) + +(assert_invalid + (module + (memory 1) + (data (offset (i32.const 0) (i32.const 0))) + ) + "type mismatch" +) + +(assert_invalid + (module + (global (import "test" "global-i32") i32) + (memory 1) + (data (offset (global.get 0) (global.get 0))) + ) + "type mismatch" +) + +(assert_invalid + (module + (global (import "test" "global-i32") i32) + (memory 1) + (data (offset (global.get 0) (i32.const 0))) + ) + "type mismatch" +) + (assert_invalid (module (memory 1) @@ -396,3 +430,29 @@ ;; (module (memory 1) (data (global.get $g)) (global $g (mut i32) (i32.const 0))) ;; "constant expression required" ;; ) + +(assert_invalid + (module + (memory 1) + (data (global.get 0)) + ) + "unknown global 0" +) + +(assert_invalid + (module + (global (import "test" "global-i32") i32) + (memory 1) + (data (global.get 1)) + ) + "unknown global 1" +) + +(assert_invalid + (module + (global (import "test" "global-mut-i32") (mut i32)) + (memory 1) + (data (global.get 0)) + ) + "constant expression required" +) \ No newline at end of file diff --git a/test/core/elem.wast b/test/core/elem.wast index 1ea2b0618..ce8ec1f60 100644 --- a/test/core/elem.wast +++ b/test/core/elem.wast @@ -262,6 +262,41 @@ "type mismatch" ) +(assert_invalid + (module + (table 1 funcref) + (elem (offset (;empty instruction sequence;))) + ) + "type mismatch" +) + +(assert_invalid + (module + (table 1 funcref) + (elem (offset (i32.const 0) (i32.const 0))) + ) + "type mismatch" +) + +(assert_invalid + (module + (global (import "test" "global-i32") i32) + (table 1 funcref) + (elem (offset (global.get 0) (global.get 0))) + ) + "type mismatch" +) + +(assert_invalid + (module + (global (import "test" "global-i32") i32) + (table 1 funcref) + (elem (offset (global.get 0) (i32.const 0))) + ) + "type mismatch" +) + + (assert_invalid (module (table 1 funcref) @@ -300,6 +335,32 @@ ;; "constant expression required" ;; ) +(assert_invalid + (module + (table 1 funcref) + (elem (global.get 0)) + ) + "unknown global 0" +) + +(assert_invalid + (module + (global (import "test" "global-i32") i32) + (table 1 funcref) + (elem (global.get 1)) + ) + "unknown global 1" +) + +(assert_invalid + (module + (global (import "test" "global-mut-i32") (mut i32)) + (table 1 funcref) + (elem (global.get 0)) + ) + "constant expression required" +) + ;; Two elements target the same slot (module diff --git a/test/core/global.wast b/test/core/global.wast index 5241eb6e6..55d7447b1 100644 --- a/test/core/global.wast +++ b/test/core/global.wast @@ -273,6 +273,11 @@ "constant expression required" ) +(assert_invalid + (module (global i32 (i32.ctz (i32.const 0)))) + "constant expression required" +) + (assert_invalid (module (global i32 (nop))) "constant expression required" @@ -293,6 +298,16 @@ "type mismatch" ) +(assert_invalid + (module (global (import "test" "global-i32") i32) (global i32 (global.get 0) (global.get 0))) + "type mismatch" +) + +(assert_invalid + (module (global (import "test" "global-i32") i32) (global i32 (i32.const 0) (global.get 0))) + "type mismatch" +) + (assert_invalid (module (global i32 (global.get 0))) "unknown global" @@ -303,6 +318,16 @@ "unknown global" ) +(assert_invalid + (module (global (import "test" "global-i32") i32) (global i32 (global.get 2))) + "unknown global" +) + +(assert_invalid + (module (global (import "test" "global-mut-i32") (mut i32)) (global i32 (global.get 0))) + "constant expression required" +) + (module (import "spectest" "global_i32" (global i32)) )