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 01/24] [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 8b5bcfc4ce..badb34bd76 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 02/24] [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 badb34bd76..fd188d760c 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 03/24] [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 7d69454173..d65abf36f8 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 04/24] [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 cd39a5d2c9..8503c9ae9e 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 05/24] [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 9af7e69620..91fc509859 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 06/24] [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 ef1c4c17eb..0c44694dbf 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 07/24] [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 ef1fccbbde..5241eb6e66 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 08/24] [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 ab564cbed0..6acab3988f 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 dde7321ec1..a158f0c7c2 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 09/24] [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 2f0200dc3f..187e0afb9d 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 10/24] [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 58abe38a4f..d03068744e 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 c19b709d368310b5e4f34862de30b066b2fa7b9d Mon Sep 17 00:00:00 2001 From: Sergey Rubanov Date: Thu, 14 Jan 2021 11:02:26 +0300 Subject: [PATCH 11/24] Fix indentation (#126) --- document/core/binary/instructions.rst | 2 +- document/core/text/instructions.rst | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/document/core/binary/instructions.rst b/document/core/binary/instructions.rst index 29ed86851a..17aa5f439f 100644 --- a/document/core/binary/instructions.rst +++ b/document/core/binary/instructions.rst @@ -170,7 +170,7 @@ Table Instructions \hex{26}~~x{:}\Btableidx &\Rightarrow& \TABLESET~x \\ &&|& \hex{FC}~~12{:}\Bu32~~y{:}\Belemidx~~x{:}\Btableidx &\Rightarrow& \TABLEINIT~x~y \\ &&|& \hex{FC}~~13{:}\Bu32~~x{:}\Belemidx &\Rightarrow& \ELEMDROP~x \\ &&|& - \hex{FC}~~14{:}\Bu32~~x{:}\Btableidx~~y{:}\Btableidx &\Rightarrow& \TABLECOPY~x~y \\ + \hex{FC}~~14{:}\Bu32~~x{:}\Btableidx~~y{:}\Btableidx &\Rightarrow& \TABLECOPY~x~y \\ &&|& \hex{FC}~~15{:}\Bu32~~x{:}\Btableidx &\Rightarrow& \TABLEGROW~x \\ &&|& \hex{FC}~~16{:}\Bu32~~x{:}\Btableidx &\Rightarrow& \TABLESIZE~x \\ &&|& \hex{FC}~~17{:}\Bu32~~x{:}\Btableidx &\Rightarrow& \TABLEFILL~x \\ diff --git a/document/core/text/instructions.rst b/document/core/text/instructions.rst index c248bc0fa9..89a2758243 100644 --- a/document/core/text/instructions.rst +++ b/document/core/text/instructions.rst @@ -229,7 +229,7 @@ Table Instructions \text{table.set}~~x{:}\Ttableidx_I &\Rightarrow& \TABLESET~x \\ &&|& \text{table.size}~~x{:}\Ttableidx_I &\Rightarrow& \TABLESIZE~x \\ &&|& \text{table.grow}~~x{:}\Ttableidx_I &\Rightarrow& \TABLEGROW~x \\ &&|& - \text{table.fill}~~x{:}\Ttableidx_I &\Rightarrow& \TABLEFILL~x \\ + \text{table.fill}~~x{:}\Ttableidx_I &\Rightarrow& \TABLEFILL~x \\ &&|& \text{table.copy}~~x{:}\Ttableidx_I~~y{:}\Ttableidx_I &\Rightarrow& \TABLECOPY~x~y \\ &&|& \text{table.init}~~x{:}\Ttableidx_I~~y{:}\Telemidx_I &\Rightarrow& \TABLEINIT~x~y \\ &&|& \text{elem.drop}~~x{:}\Telemidx_I &\Rightarrow& \ELEMDROP~x \\ From 7c7bd2a9ed7554aba30563c8012ff7efda05cece Mon Sep 17 00:00:00 2001 From: Ms2ger Date: Thu, 14 Jan 2021 10:54:28 +0100 Subject: [PATCH 12/24] Fix some js-api bugs. (#128) --- document/js-api/index.bs | 37 +++++++++++++++---------------------- 1 file changed, 15 insertions(+), 22 deletions(-) diff --git a/document/js-api/index.bs b/document/js-api/index.bs index 35a591fc2e..79ccedfb17 100644 --- a/document/js-api/index.bs +++ b/document/js-api/index.bs @@ -740,14 +740,9 @@ interface Table { }; -
-A {{Table}} object represents a single [=table instance=] -which can be simultaneously referenced by multiple {{Instance}} objects. -Each {{Table}} object has the following internal slots: - - * \[[Table]] : a [=table address=] - * \[[Values]] : a [=list=] whose elements depend on the element type of \[[Table]]'s [=table type=]. -
+A {{Table}} object represents a single [=table instance=] which can be simultaneously referenced by +multiple {{Instance}} objects. +Each {{Table}} object has a \[[Table]] internal slot, which is a [=table address=].
To initialize a table object |table| from a [=table address=] |tableaddr|, perform the following steps: @@ -770,7 +765,7 @@ Each {{Table}} object has the following internal slots:
The Table(|descriptor|, |value|) constructor, when invoked, performs the following steps: 1. Let |elementType| be [=ToValueType=](|descriptor|["element"]). - 1. let |initial| be |descriptor|["initial"]. + 1. Let |initial| be |descriptor|["initial"]. 1. If |descriptor|["maximum"] [=map/exists=], let |maximum| be |descriptor|["maximum"]; otherwise, let |maximum| be empty. 1. If |maximum| is not empty and |maximum| < |initial|, throw a {{RangeError}} exception. 1. If |value| is missing, @@ -782,8 +777,6 @@ Each {{Table}} object has the following internal slots: 1. Let (|store|, |tableaddr|) be [=table_alloc=](|store|, |type|, |ref|). 1. Set the [=surrounding agent=]'s [=associated store=] to |store|. 1. [=initialize a table object|Initialize=] **this** from |tableaddr|. - 1. [=list/Empty=] **this**.\[[Values]]. - 1. [=list/Append=] |value| to **this**.\[[Values]] |initial| times.
@@ -802,7 +795,6 @@ Each {{Table}} object has the following internal slots: Note: The above exception can happen due to either insufficient memory or an invalid size parameter. 1. Set the [=surrounding agent=]'s [=associated store=] to |result|. - 1. [=list/Append=] |value| to **this**.\[[Values]] |delta| times. 1. Return |initialSize|.
@@ -819,14 +811,12 @@ Each {{Table}} object has the following internal slots: 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. Let |function| be the result of creating [=a new Exported Function=] from |result|. - 1. Return |function|. + 1. Return [=ToJSValue=](|result|).
The set(|index|, |value|) method, when invoked, performs the following steps: 1. Let |tableaddr| be **this**.\[[Table]]. - 1. Let |values| be **this**.\[[Values]]. 1. Let (limits, |elementType|) be [=table_type=](|tableaddr|). 1. If |value| is missing, 1. Let |ref| be [=DefaultValue=](|elementType|). @@ -897,7 +887,7 @@ which can be simultaneously referenced by multiple {{Instance}} objects. Each 1. If |s| equals "i64", return [=i64=]. 1. If |s| equals "f32", return [=f32=]. 1. If |s| equals "f64", return [=f64=]. - 1. If |s| equals "funcref", return [=funcref=]. + 1. If |s| equals "anyfunc", return [=funcref=]. 1. If |s| equals "externref", return [=externref=]. 1. Assert: This step is not reached.
@@ -908,6 +898,7 @@ which can be simultaneously referenced by multiple {{Instance}} objects. Each 1. If |valuetype| equals [=i64=], return [=i64.const=] 0. 1. If |valuetype| equals [=f32=], return [=f32.const=] 0. 1. If |valuetype| equals [=f64=], return [=f64.const=] 0. + 1. If |valuetype| equals [=funcref=], return [=ref.null=] [=funcref=]. 1. If |valuetype| equals [=externref=], return [=ToWebAssemblyValue=](undefined, |valuetype|). 1. Assert: This step is not reached.
@@ -917,7 +908,7 @@ which can be simultaneously referenced by multiple {{Instance}} objects. Each 1. Let |mutable| be |descriptor|["mutable"]. 1. Let |valuetype| be [=ToValueType=](|descriptor|["value"]). 1. If |v| is missing, - 1. let |value| be [=DefaultValue=](|valuetype|). + 1. Let |value| be [=DefaultValue=](|valuetype|). 1. Otherwise, 1. Let |value| be [=ToWebAssemblyValue=](|v|, |valuetype|). 1. If |mutable| is true, let |globaltype| be [=var=] |valuetype|; otherwise, let |globaltype| be [=const=] |valuetype|. @@ -1088,10 +1079,13 @@ Note: Number values which are equal to NaN may have various observable NaN paylo
- For retrieving an extern value from a [=extern address=] |externaddr|, perform the following steps: - 1. Let |map| be the [=surrounding agent=]'s associated [=extern value cache=]. - 1. Assert: |map|[|externaddr|] [=map/exists=]. - 1. Return |map|[|externaddr|]. + +For retrieving an extern value from an [=extern address=] |externaddr|, perform the following steps: + +1. Let |map| be the [=surrounding agent=]'s associated [=extern value cache=]. +1. Assert: |map|[|externaddr|] [=map/exists=]. +1. Return |map|[|externaddr|]. +
@@ -1129,7 +1123,6 @@ The algorithm ToWebAssemblyValue(|v|, |type|) coerces a JavaScript va
-

Error Objects

WebAssembly defines the following Error classes: CompileError, LinkError, and RuntimeError. From dd924229529b3cd5f511a7440f6c33bd37202515 Mon Sep 17 00:00:00 2001 From: Ms2ger Date: Thu, 14 Jan 2021 12:09:14 +0100 Subject: [PATCH 13/24] [js-api] Explicitly disallow creating Tables with non-reftypes. (#129) --- document/js-api/index.bs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/document/js-api/index.bs b/document/js-api/index.bs index 79ccedfb17..1e4aa51d37 100644 --- a/document/js-api/index.bs +++ b/document/js-api/index.bs @@ -155,6 +155,7 @@ urlPrefix: https://webassembly.github.io/reference-types/core/; spec: WebAssembl text: f32 text: f64 url: syntax/types.html#syntax-reftype + text: reftype text: funcref text: externref text: function element; url: exec/runtime.html#syntax-funcelem @@ -765,6 +766,8 @@ 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. If |maximum| is not empty and |maximum| < |initial|, throw a {{RangeError}} exception. From 9ff8601dc397d676a8d104c70eb3b64c2142189d Mon Sep 17 00:00:00 2001 From: Andreas Rossberg Date: Wed, 20 Jan 2021 10:34:09 +0100 Subject: [PATCH 14/24] [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 54b9fd0048..feb99bd0d9 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 78f3e994a9..9d6ff9a434 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 15/24] [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 fd188d760c..8f2e2ba80e 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 16/24] [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 564dd6ee0a..3cc6108201 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 17/24] 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 9dc6727f43..b783f5d94e 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 18/24] 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 b783f5d94e..c54a8fc94f 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 19/24] [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 d65abf36f8..e840a94674 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 1ea2b06184..ce8ec1f60f 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 5241eb6e66..55d7447b19 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)) ) From 2251365f5be3af6385dc4b50d565518925798fe9 Mon Sep 17 00:00:00 2001 From: Andrei Maiboroda Date: Wed, 3 Feb 2021 13:07:17 +0100 Subject: [PATCH 20/24] [test] Improvements to select instruction tests (#1282) --- test/core/select.wast | 81 ++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 77 insertions(+), 4 deletions(-) diff --git a/test/core/select.wast b/test/core/select.wast index cee2054911..e40347e355 100644 --- a/test/core/select.wast +++ b/test/core/select.wast @@ -28,10 +28,19 @@ (unreachable) (select) (unreachable) (i32.const 0) (select) (unreachable) (i32.const 0) (i32.const 0) (select) + (unreachable) (i32.const 0) (i32.const 0) (i32.const 0) (select) (unreachable) (f32.const 0) (i32.const 0) (select) (unreachable) ) + (func (export "select_unreached_result_1") (result i32) + (unreachable) (i32.add (select)) + ) + + (func (export "select_unreached_result_2") (result i64) + (unreachable) (i64.add (select (i64.const 0) (i32.const 0))) + ) + ;; As the argument of control constructs and instructions (func (export "as-select-first") (param i32) (result i32) @@ -287,22 +296,22 @@ (assert_return (invoke "as-convert-operand" (i32.const 1)) (i32.const 1)) (assert_invalid - (module (func $arity-0 (select (nop) (nop) (i32.const 1)))) + (module (func $arity-0 (select (nop) (nop) (i32.const 1)) (drop))) "type mismatch" ) ;; The first two operands should have the same type as each other (assert_invalid - (module (func $type-num-vs-num (select (i32.const 1) (i64.const 1) (i32.const 1)))) + (module (func $type-num-vs-num (select (i32.const 1) (i64.const 1) (i32.const 1)) (drop))) "type mismatch" ) (assert_invalid - (module (func $type-num-vs-num (select (i32.const 1) (f32.const 1.0) (i32.const 1)))) + (module (func $type-num-vs-num (select (i32.const 1) (f32.const 1.0) (i32.const 1)) (drop))) "type mismatch" ) (assert_invalid - (module (func $type-num-vs-num (select (i32.const 1) (f64.const 1.0) (i32.const 1)))) + (module (func $type-num-vs-num (select (i32.const 1) (f64.const 1.0) (i32.const 1)) (drop))) "type mismatch" ) @@ -412,3 +421,67 @@ ) "type mismatch" ) + +;; Third operand must be i32 + +(assert_invalid + (module (func (select (i32.const 1) (i32.const 1) (i64.const 1)) (drop))) + "type mismatch" +) +(assert_invalid + (module (func (select (i32.const 1) (i32.const 1) (f32.const 1)) (drop))) + "type mismatch" +) +(assert_invalid + (module (func (select (i32.const 1) (i32.const 1) (f64.const 1)) (drop))) + "type mismatch" +) + +;; Result of select has type of first two operands + +(assert_invalid + (module (func (result i32) (select (i64.const 1) (i64.const 1) (i32.const 1)))) + "type mismatch" +) + +;; Validation after unreachable + +;; The first two operands should have the same type as each other +(assert_invalid + (module (func (unreachable) (select (i32.const 1) (i64.const 1) (i32.const 1)) (drop))) + "type mismatch" +) + +(assert_invalid + (module (func (unreachable) (select (i64.const 1) (i32.const 1) (i32.const 1)) (drop))) + "type mismatch" +) + +;; Third operand must be i32 +(assert_invalid + (module (func (unreachable) (select (i32.const 1) (i32.const 1) (i64.const 1)) (drop))) + "type mismatch" +) + +(assert_invalid + (module (func (unreachable) (select (i32.const 1) (i64.const 1)) (drop))) + "type mismatch" +) + +(assert_invalid + (module (func (unreachable) (select (i64.const 1)) (drop))) + "type mismatch" +) + +;; Result of select has type of first two operands (type of second operand when first one is omitted) +(assert_invalid + (module (func (result i32) (unreachable) (select (i64.const 1) (i32.const 1)))) + "type mismatch" +) + +;; select always has non-empty result +(assert_invalid + (module (func (unreachable) (select))) + "type mismatch" +) + From 9a0269bcf5431d664cde16532f35cb2e14b5ae07 Mon Sep 17 00:00:00 2001 From: Ng Zhi An Date: Wed, 3 Feb 2021 14:25:02 -0800 Subject: [PATCH 21/24] Fix step-by-step guide instruction cd-ed too deep into the tree, it doesn't not work with the next `make -C core` instruction. --- document/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/document/README.md b/document/README.md index 05624181c4..326fc9a38a 100644 --- a/document/README.md +++ b/document/README.md @@ -88,7 +88,7 @@ You will also need `npm` and `yarn` for all the LaTeX goodness. `npm` might alre ``` npm install -g yarn -cd document/core +cd document make -C core bikeshed ``` From a2196ec86f02e7e970e297f09fd73c24f5468624 Mon Sep 17 00:00:00 2001 From: Ng Zhi An Date: Thu, 4 Feb 2021 17:24:53 -0800 Subject: [PATCH 22/24] [interpreter] Make popcnt loop up to bitwidth This makes it work for Rep.bitwidth < 32. Otherwise it will keep checking all 32 bits and give the wrong result. --- interpreter/exec/int.ml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/interpreter/exec/int.ml b/interpreter/exec/int.ml index 7236c52831..ec23208d8e 100644 --- a/interpreter/exec/int.ml +++ b/interpreter/exec/int.ml @@ -199,7 +199,7 @@ struct let popcnt x = let rec loop acc i n = - if n = Rep.zero then + if i = 0 then acc else let acc' = if and_ n Rep.one = Rep.one then acc + 1 else acc in From 44b626beab73c265bcff798856a9153dda0a6919 Mon Sep 17 00:00:00 2001 From: Andreas Rossberg Date: Wed, 10 Feb 2021 11:07:56 +0100 Subject: [PATCH 23/24] [spec] Add missing immediates --- document/core/syntax/instructions.rst | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/document/core/syntax/instructions.rst b/document/core/syntax/instructions.rst index 7432a247ee..039d4cfb2f 100644 --- a/document/core/syntax/instructions.rst +++ b/document/core/syntax/instructions.rst @@ -268,8 +268,8 @@ Instructions in this group are concerned with tables :ref:`table ` \TABLESIZE~\tableidx \\&&|& \TABLEGROW~\tableidx \\&&|& \TABLEFILL~\tableidx \\&&|& - \TABLECOPY \\&&|& - \TABLEINIT~\elemidx \\&&|& + \TABLECOPY~\tableidx~\tableidx \\&&|& + \TABLEINIT~\tableidx~\elemidx \\&&|& \ELEMDROP~\elemidx \\ \end{array} @@ -281,7 +281,7 @@ It also takes an initialization value for the newly allocated entries. The |TABLEFILL| instruction sets all entries in a range to a given value. -The |TABLECOPY| instruction copies elements from a source table region to a possibly overlapping destination region. +The |TABLECOPY| instruction copies elements from a source table region to a possibly overlapping destination region; the first index denotes the destination. The |TABLEINIT| instruction copies elements from a :ref:`passive element segment ` into a table. The |ELEMDROP| instruction prevents further use of a passive element segment. This instruction is intended to be used as an optimization hint. After an element segment is dropped its elements can no longer be retrieved, so the memory used by this segment may be freed. From 8546739cc7b95238828a75ec16cdca8c8b7790b5 Mon Sep 17 00:00:00 2001 From: Andreas Rossberg Date: Thu, 11 Feb 2021 16:01:19 +0100 Subject: [PATCH 24/24] Merge upstream (#157) --- document/README.md | 2 +- document/core/Makefile | 8 +- .../core/appendix/gen-index-instructions.py | 346 +++++++++++++ document/core/appendix/index-instructions.rst | 482 ++++++++++-------- document/core/exec/instructions.rst | 4 +- document/core/exec/numerics.rst | 2 +- document/core/text/instructions.rst | 16 +- document/js-api/index.bs | 3 +- document/web-api/index.bs | 22 +- interpreter/Makefile | 28 +- interpreter/README.md | 30 ++ interpreter/exec/int.ml | 2 +- interpreter/host/spectest.ml | 6 +- test/core/binary-leb128.wast | 2 +- test/core/binary.wast | 73 ++- test/core/br_table.wast | 35 ++ test/core/data.wast | 123 +++++ test/core/elem.wast | 61 +++ test/core/exports.wast | 32 ++ test/core/global.wast | 92 ++++ test/core/imports.wast | 51 ++ test/core/local_get.wast | 12 +- test/core/local_tee.wast | 38 +- test/core/select.wast | 81 ++- 24 files changed, 1270 insertions(+), 281 deletions(-) create mode 100755 document/core/appendix/gen-index-instructions.py diff --git a/document/README.md b/document/README.md index 05624181c4..326fc9a38a 100644 --- a/document/README.md +++ b/document/README.md @@ -88,7 +88,7 @@ You will also need `npm` and `yarn` for all the LaTeX goodness. `npm` might alre ``` npm install -g yarn -cd document/core +cd document make -C core bikeshed ``` diff --git a/document/core/Makefile b/document/core/Makefile index aaa01b4f99..3ff1a87cbb 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 new file mode 100755 index 0000000000..bc1b9e23e9 --- /dev/null +++ b/document/core/appendix/gen-index-instructions.py @@ -0,0 +1,346 @@ +#!/usr/bin/env python3 + +# This script generates the `index-instructions.rst` file. The table in that +# file is particularly annoying to update by hand, since the Restructured Text +# format requires the header and columns to line up properly. This is +# especially tedious when merging changes from the upstream spec, or merging a +# proposal back to the spec when it is standardized. + +import os + +SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__)) +INDEX_INSTRUCTIONS_RST = os.path.join(SCRIPT_DIR, 'index-instructions.rst') + +HEADER = """\ +.. DO NOT EDIT: This file is auto-generated by the gen-index-instructions.py script. + +.. index:: instruction +.. _index-instr: + +Index of Instructions +--------------------- +""" + +COLUMNS = [ + 'Instruction', + 'Binary Opcode', + 'Type', + 'Validation', + 'Execution', +] + + +def MathWrap(s, default=''): + if s is None: + return default + else: + return f':math:`{s}`' + + +def RefWrap(s, kind): + if s is None: + return '' + else: + return f':ref:`{kind} <{s}>`' + + +def Instruction(name, opcode, type=None, validation=None, execution=None, operator=None): + if operator: + execution_str = ', '.join([RefWrap(execution, 'execution'), + RefWrap(operator, 'operator')]) + else: + execution_str = RefWrap(execution, 'execution') + + return ( + MathWrap(name, '(reserved)'), + MathWrap(opcode), + MathWrap(type), + RefWrap(validation, 'validation'), + execution_str + ) + + +INSTRUCTIONS = [ + Instruction(r'\UNREACHABLE', r'\hex{00}', r'[t_1^\ast] \to [t_2^\ast]', r'valid-unreachable', r'exec-unreachable'), + Instruction(r'\NOP', r'\hex{01}', r'[] \to []', r'valid-nop', r'exec-nop'), + Instruction(r'\BLOCK~\X{bt}', r'\hex{02}', r'[t_1^\ast] \to [t_2^\ast]', r'valid-block', r'exec-block'), + Instruction(r'\LOOP~\X{bt}', r'\hex{03}', r'[t_1^\ast] \to [t_2^\ast]', r'valid-loop', r'exec-loop'), + Instruction(r'\IF~\X{bt}', r'\hex{04}', r'[t_1^\ast] \to [t_2^\ast]', r'valid-if', r'exec-if'), + Instruction(r'\ELSE', r'\hex{05}'), + Instruction(None, r'\hex{06}'), + Instruction(None, r'\hex{07}'), + Instruction(None, r'\hex{08}'), + Instruction(None, r'\hex{09}'), + Instruction(None, r'\hex{0A}'), + Instruction(r'\END', r'\hex{0B}'), + Instruction(r'\BR~l', r'\hex{0C}', r'[t_1^\ast~t^\ast] \to [t_2^\ast]', r'valid-br', r'exec-br'), + Instruction(r'\BRIF~l', r'\hex{0D}', r'[t^\ast~\I32] \to [t^\ast]', r'valid-br_if', r'exec-br_if'), + Instruction(r'\BRTABLE~l^\ast~l', r'\hex{0E}', r'[t_1^\ast~t^\ast~\I32] \to [t_2^\ast]', r'valid-br_table', r'exec-br_table'), + Instruction(r'\RETURN', r'\hex{0F}', r'[t_1^\ast~t^\ast] \to [t_2^\ast]', r'valid-return', r'exec-return'), + Instruction(r'\CALL~x', r'\hex{10}', r'[t_1^\ast] \to [t_2^\ast]', r'valid-call', r'exec-call'), + Instruction(r'\CALLINDIRECT~x', r'\hex{11}', r'[t_1^\ast~\I32] \to [t_2^\ast]', r'valid-call_indirect', r'exec-call_indirect'), + Instruction(None, r'\hex{12}'), + Instruction(None, r'\hex{13}'), + Instruction(None, r'\hex{14}'), + Instruction(None, r'\hex{15}'), + Instruction(None, r'\hex{16}'), + Instruction(None, r'\hex{17}'), + Instruction(None, r'\hex{18}'), + Instruction(None, r'\hex{19}'), + Instruction(r'\DROP', r'\hex{1A}', r'[t] \to []', r'valid-drop', r'exec-drop'), + Instruction(r'\SELECT', r'\hex{1B}', r'[t~t~\I32] \to [t]', r'valid-select', r'exec-select'), + Instruction(None, r'\hex{1C}'), + Instruction(None, r'\hex{1D}'), + Instruction(None, r'\hex{1E}'), + Instruction(None, r'\hex{1F}'), + Instruction(r'\LOCALGET~x', r'\hex{20}', r'[] \to [t]', r'valid-local.get', r'exec-local.get'), + Instruction(r'\LOCALSET~x', r'\hex{21}', r'[t] \to []', r'valid-local.set', r'exec-local.set'), + Instruction(r'\LOCALTEE~x', r'\hex{22}', r'[t] \to [t]', r'valid-local.tee', r'exec-local.tee'), + Instruction(r'\GLOBALGET~x', r'\hex{23}', r'[] \to [t]', r'valid-global.get', r'exec-global.get'), + Instruction(r'\GLOBALSET~x', r'\hex{24}', r'[t] \to []', r'valid-global.set', r'exec-global.set'), + Instruction(None, r'\hex{25}'), + Instruction(None, r'\hex{26}'), + Instruction(None, r'\hex{27}'), + Instruction(r'\I32.\LOAD~\memarg', r'\hex{28}', r'[\I32] \to [\I32]', r'valid-load', r'exec-load'), + Instruction(r'\I64.\LOAD~\memarg', r'\hex{29}', r'[\I32] \to [\I64]', r'valid-load', r'exec-load'), + Instruction(r'\F32.\LOAD~\memarg', r'\hex{2A}', r'[\I32] \to [\F32]', r'valid-load', r'exec-load'), + Instruction(r'\F64.\LOAD~\memarg', r'\hex{2B}', r'[\I32] \to [\F64]', r'valid-load', r'exec-load'), + Instruction(r'\I32.\LOAD\K{8\_s}~\memarg', r'\hex{2C}', r'[\I32] \to [\I32]', r'valid-loadn', r'exec-loadn'), + Instruction(r'\I32.\LOAD\K{8\_u}~\memarg', r'\hex{2D}', r'[\I32] \to [\I32]', r'valid-loadn', r'exec-loadn'), + Instruction(r'\I32.\LOAD\K{16\_s}~\memarg', r'\hex{2E}', r'[\I32] \to [\I32]', r'valid-loadn', r'exec-loadn'), + Instruction(r'\I32.\LOAD\K{16\_u}~\memarg', r'\hex{2F}', r'[\I32] \to [\I32]', r'valid-loadn', r'exec-loadn'), + Instruction(r'\I64.\LOAD\K{8\_s}~\memarg', r'\hex{30}', r'[\I32] \to [\I64]', r'valid-loadn', r'exec-loadn'), + Instruction(r'\I64.\LOAD\K{8\_u}~\memarg', r'\hex{31}', r'[\I32] \to [\I64]', r'valid-loadn', r'exec-loadn'), + Instruction(r'\I64.\LOAD\K{16\_s}~\memarg', r'\hex{32}', r'[\I32] \to [\I64]', r'valid-loadn', r'exec-loadn'), + Instruction(r'\I64.\LOAD\K{16\_u}~\memarg', r'\hex{33}', r'[\I32] \to [\I64]', r'valid-loadn', r'exec-loadn'), + Instruction(r'\I64.\LOAD\K{32\_s}~\memarg', r'\hex{34}', r'[\I32] \to [\I64]', r'valid-loadn', r'exec-loadn'), + Instruction(r'\I64.\LOAD\K{32\_u}~\memarg', r'\hex{35}', r'[\I32] \to [\I64]', r'valid-loadn', r'exec-loadn'), + Instruction(r'\I32.\STORE~\memarg', r'\hex{36}', r'[\I32~\I32] \to []', r'valid-store', r'exec-store'), + Instruction(r'\I64.\STORE~\memarg', r'\hex{37}', r'[\I32~\I64] \to []', r'valid-store', r'exec-store'), + Instruction(r'\F32.\STORE~\memarg', r'\hex{38}', r'[\I32~\F32] \to []', r'valid-store', r'exec-store'), + Instruction(r'\F64.\STORE~\memarg', r'\hex{39}', r'[\I32~\F64] \to []', r'valid-store', r'exec-store'), + Instruction(r'\I32.\STORE\K{8}~\memarg', r'\hex{3A}', r'[\I32~\I32] \to []', r'valid-storen', r'exec-storen'), + Instruction(r'\I32.\STORE\K{16}~\memarg', r'\hex{3B}', r'[\I32~\I32] \to []', r'valid-storen', r'exec-storen'), + Instruction(r'\I64.\STORE\K{8}~\memarg', r'\hex{3C}', r'[\I32~\I64] \to []', r'valid-storen', r'exec-storen'), + Instruction(r'\I64.\STORE\K{16}~\memarg', r'\hex{3D}', r'[\I32~\I64] \to []', r'valid-storen', r'exec-storen'), + Instruction(r'\I64.\STORE\K{32}~\memarg', r'\hex{3E}', r'[\I32~\I64] \to []', r'valid-storen', r'exec-storen'), + Instruction(r'\MEMORYSIZE', r'\hex{3F}', r'[] \to [\I32]', r'valid-memory.size', r'exec-memory.size'), + Instruction(r'\MEMORYGROW', r'\hex{40}', r'[\I32] \to [\I32]', r'valid-memory.grow', r'exec-memory.grow'), + Instruction(r'\I32.\CONST~\i32', r'\hex{41}', r'[] \to [\I32]', r'valid-const', r'exec-const'), + Instruction(r'\I64.\CONST~\i64', r'\hex{42}', r'[] \to [\I64]', r'valid-const', r'exec-const'), + Instruction(r'\F32.\CONST~\f32', r'\hex{43}', r'[] \to [\F32]', r'valid-const', r'exec-const'), + Instruction(r'\F64.\CONST~\f64', r'\hex{44}', r'[] \to [\F64]', r'valid-const', r'exec-const'), + Instruction(r'\I32.\EQZ', r'\hex{45}', r'[\I32] \to [\I32]', r'valid-testop', r'exec-testop', r'op-ieqz'), + Instruction(r'\I32.\EQ', r'\hex{46}', r'[\I32~\I32] \to [\I32]', r'valid-relop', r'exec-relop', r'op-ieq'), + Instruction(r'\I32.\NE', r'\hex{47}', r'[\I32~\I32] \to [\I32]', r'valid-relop', r'exec-relop', r'op-ine'), + Instruction(r'\I32.\LT\K{\_s}', r'\hex{48}', r'[\I32~\I32] \to [\I32]', r'valid-relop', r'exec-relop', r'op-ilt_s'), + Instruction(r'\I32.\LT\K{\_u}', r'\hex{49}', r'[\I32~\I32] \to [\I32]', r'valid-relop', r'exec-relop', r'op-ilt_u'), + Instruction(r'\I32.\GT\K{\_s}', r'\hex{4A}', r'[\I32~\I32] \to [\I32]', r'valid-relop', r'exec-relop', r'op-igt_s'), + Instruction(r'\I32.\GT\K{\_u}', r'\hex{4B}', r'[\I32~\I32] \to [\I32]', r'valid-relop', r'exec-relop', r'op-igt_u'), + Instruction(r'\I32.\LE\K{\_s}', r'\hex{4C}', r'[\I32~\I32] \to [\I32]', r'valid-relop', r'exec-relop', r'op-ile_s'), + Instruction(r'\I32.\LE\K{\_u}', r'\hex{4D}', r'[\I32~\I32] \to [\I32]', r'valid-relop', r'exec-relop', r'op-ile_u'), + Instruction(r'\I32.\GE\K{\_s}', r'\hex{4E}', r'[\I32~\I32] \to [\I32]', r'valid-relop', r'exec-relop', r'op-ige_s'), + Instruction(r'\I32.\GE\K{\_u}', r'\hex{4F}', r'[\I32~\I32] \to [\I32]', r'valid-relop', r'exec-relop', r'op-ige_u'), + Instruction(r'\I64.\EQZ', r'\hex{50}', r'[\I64] \to [\I32]', r'valid-testop', r'exec-testop', r'op-ieqz'), + Instruction(r'\I64.\EQ', r'\hex{51}', r'[\I64~\I64] \to [\I32]', r'valid-relop', r'exec-relop', r'op-ieq'), + Instruction(r'\I64.\NE', r'\hex{52}', r'[\I64~\I64] \to [\I32]', r'valid-relop', r'exec-relop', r'op-ine'), + Instruction(r'\I64.\LT\K{\_s}', r'\hex{53}', r'[\I64~\I64] \to [\I32]', r'valid-relop', r'exec-relop', r'op-ilt_s'), + Instruction(r'\I64.\LT\K{\_u}', r'\hex{54}', r'[\I64~\I64] \to [\I32]', r'valid-relop', r'exec-relop', r'op-ilt_u'), + Instruction(r'\I64.\GT\K{\_s}', r'\hex{55}', r'[\I64~\I64] \to [\I32]', r'valid-relop', r'exec-relop', r'op-igt_s'), + Instruction(r'\I64.\GT\K{\_u}', r'\hex{56}', r'[\I64~\I64] \to [\I32]', r'valid-relop', r'exec-relop', r'op-igt_u'), + Instruction(r'\I64.\LE\K{\_s}', r'\hex{57}', r'[\I64~\I64] \to [\I32]', r'valid-relop', r'exec-relop', r'op-ile_s'), + Instruction(r'\I64.\LE\K{\_u}', r'\hex{58}', r'[\I64~\I64] \to [\I32]', r'valid-relop', r'exec-relop', r'op-ile_u'), + Instruction(r'\I64.\GE\K{\_s}', r'\hex{59}', r'[\I64~\I64] \to [\I32]', r'valid-relop', r'exec-relop', r'op-ige_s'), + Instruction(r'\I64.\GE\K{\_u}', r'\hex{5A}', r'[\I64~\I64] \to [\I32]', r'valid-relop', r'exec-relop', r'op-ige_u'), + Instruction(r'\F32.\EQ', r'\hex{5B}', r'[\F32~\F32] \to [\I32]', r'valid-relop', r'exec-relop', r'op-feq'), + Instruction(r'\F32.\NE', r'\hex{5C}', r'[\F32~\F32] \to [\I32]', r'valid-relop', r'exec-relop', r'op-fne'), + Instruction(r'\F32.\LT', r'\hex{5D}', r'[\F32~\F32] \to [\I32]', r'valid-relop', r'exec-relop', r'op-flt'), + Instruction(r'\F32.\GT', r'\hex{5E}', r'[\F32~\F32] \to [\I32]', r'valid-relop', r'exec-relop', r'op-fgt'), + Instruction(r'\F32.\LE', r'\hex{5F}', r'[\F32~\F32] \to [\I32]', r'valid-relop', r'exec-relop', r'op-fle'), + Instruction(r'\F32.\GE', r'\hex{60}', r'[\F32~\F32] \to [\I32]', r'valid-relop', r'exec-relop', r'op-fge'), + Instruction(r'\F64.\EQ', r'\hex{61}', r'[\F64~\F64] \to [\I32]', r'valid-relop', r'exec-relop', r'op-feq'), + Instruction(r'\F64.\NE', r'\hex{62}', r'[\F64~\F64] \to [\I32]', r'valid-relop', r'exec-relop', r'op-fne'), + Instruction(r'\F64.\LT', r'\hex{63}', r'[\F64~\F64] \to [\I32]', r'valid-relop', r'exec-relop', r'op-flt'), + Instruction(r'\F64.\GT', r'\hex{64}', r'[\F64~\F64] \to [\I32]', r'valid-relop', r'exec-relop', r'op-fgt'), + Instruction(r'\F64.\LE', r'\hex{65}', r'[\F64~\F64] \to [\I32]', r'valid-relop', r'exec-relop', r'op-fle'), + Instruction(r'\F64.\GE', r'\hex{66}', r'[\F64~\F64] \to [\I32]', r'valid-relop', r'exec-relop', r'op-fge'), + Instruction(r'\I32.\CLZ', r'\hex{67}', r'[\I32] \to [\I32]', r'valid-unop', r'exec-unop', r'op-iclz'), + Instruction(r'\I32.\CTZ', r'\hex{68}', r'[\I32] \to [\I32]', r'valid-unop', r'exec-unop', r'op-ictz'), + Instruction(r'\I32.\POPCNT', r'\hex{69}', r'[\I32] \to [\I32]', r'valid-unop', r'exec-unop', r'op-ipopcnt'), + Instruction(r'\I32.\ADD', r'\hex{6A}', r'[\I32~\I32] \to [\I32]', r'valid-binop', r'exec-binop', r'op-iadd'), + Instruction(r'\I32.\SUB', r'\hex{6B}', r'[\I32~\I32] \to [\I32]', r'valid-binop', r'exec-binop', r'op-isub'), + Instruction(r'\I32.\MUL', r'\hex{6C}', r'[\I32~\I32] \to [\I32]', r'valid-binop', r'exec-binop', r'op-imul'), + Instruction(r'\I32.\DIV\K{\_s}', r'\hex{6D}', r'[\I32~\I32] \to [\I32]', r'valid-binop', r'exec-binop', r'op-idiv_s'), + Instruction(r'\I32.\DIV\K{\_u}', r'\hex{6E}', r'[\I32~\I32] \to [\I32]', r'valid-binop', r'exec-binop', r'op-idiv_u'), + Instruction(r'\I32.\REM\K{\_s}', r'\hex{6F}', r'[\I32~\I32] \to [\I32]', r'valid-binop', r'exec-binop', r'op-irem_s'), + Instruction(r'\I32.\REM\K{\_u}', r'\hex{70}', r'[\I32~\I32] \to [\I32]', r'valid-binop', r'exec-binop', r'op-irem_u'), + Instruction(r'\I32.\AND', r'\hex{71}', r'[\I32~\I32] \to [\I32]', r'valid-binop', r'exec-binop', r'op-iand'), + Instruction(r'\I32.\OR', r'\hex{72}', r'[\I32~\I32] \to [\I32]', r'valid-binop', r'exec-binop', r'op-ior'), + Instruction(r'\I32.\XOR', r'\hex{73}', r'[\I32~\I32] \to [\I32]', r'valid-binop', r'exec-binop', r'op-ixor'), + Instruction(r'\I32.\SHL', r'\hex{74}', r'[\I32~\I32] \to [\I32]', r'valid-binop', r'exec-binop', r'op-ishl'), + Instruction(r'\I32.\SHR\K{\_s}', r'\hex{75}', r'[\I32~\I32] \to [\I32]', r'valid-binop', r'exec-binop', r'op-ishr_s'), + Instruction(r'\I32.\SHR\K{\_u}', r'\hex{76}', r'[\I32~\I32] \to [\I32]', r'valid-binop', r'exec-binop', r'op-ishr_u'), + Instruction(r'\I32.\ROTL', r'\hex{77}', r'[\I32~\I32] \to [\I32]', r'valid-binop', r'exec-binop', r'op-irotl'), + Instruction(r'\I32.\ROTR', r'\hex{78}', r'[\I32~\I32] \to [\I32]', r'valid-binop', r'exec-binop', r'op-irotr'), + Instruction(r'\I64.\CLZ', r'\hex{79}', r'[\I64] \to [\I64]', r'valid-unop', r'exec-unop', r'op-iclz'), + Instruction(r'\I64.\CTZ', r'\hex{7A}', r'[\I64] \to [\I64]', r'valid-unop', r'exec-unop', r'op-ictz'), + Instruction(r'\I64.\POPCNT', r'\hex{7B}', r'[\I64] \to [\I64]', r'valid-unop', r'exec-unop', r'op-ipopcnt'), + Instruction(r'\I64.\ADD', r'\hex{7C}', r'[\I64~\I64] \to [\I64]', r'valid-binop', r'exec-binop', r'op-iadd'), + Instruction(r'\I64.\SUB', r'\hex{7D}', r'[\I64~\I64] \to [\I64]', r'valid-binop', r'exec-binop', r'op-isub'), + Instruction(r'\I64.\MUL', r'\hex{7E}', r'[\I64~\I64] \to [\I64]', r'valid-binop', r'exec-binop', r'op-imul'), + Instruction(r'\I64.\DIV\K{\_s}', r'\hex{7F}', r'[\I64~\I64] \to [\I64]', r'valid-binop', r'exec-binop', r'op-idiv_s'), + Instruction(r'\I64.\DIV\K{\_u}', r'\hex{80}', r'[\I64~\I64] \to [\I64]', r'valid-binop', r'exec-binop', r'op-idiv_u'), + Instruction(r'\I64.\REM\K{\_s}', r'\hex{81}', r'[\I64~\I64] \to [\I64]', r'valid-binop', r'exec-binop', r'op-irem_s'), + Instruction(r'\I64.\REM\K{\_u}', r'\hex{82}', r'[\I64~\I64] \to [\I64]', r'valid-binop', r'exec-binop', r'op-irem_u'), + Instruction(r'\I64.\AND', r'\hex{83}', r'[\I64~\I64] \to [\I64]', r'valid-binop', r'exec-binop', r'op-iand'), + Instruction(r'\I64.\OR', r'\hex{84}', r'[\I64~\I64] \to [\I64]', r'valid-binop', r'exec-binop', r'op-ior'), + Instruction(r'\I64.\XOR', r'\hex{85}', r'[\I64~\I64] \to [\I64]', r'valid-binop', r'exec-binop', r'op-ixor'), + Instruction(r'\I64.\SHL', r'\hex{86}', r'[\I64~\I64] \to [\I64]', r'valid-binop', r'exec-binop', r'op-ishl'), + Instruction(r'\I64.\SHR\K{\_s}', r'\hex{87}', r'[\I64~\I64] \to [\I64]', r'valid-binop', r'exec-binop', r'op-ishr_s'), + Instruction(r'\I64.\SHR\K{\_u}', r'\hex{88}', r'[\I64~\I64] \to [\I64]', r'valid-binop', r'exec-binop', r'op-ishr_u'), + Instruction(r'\I64.\ROTL', r'\hex{89}', r'[\I64~\I64] \to [\I64]', r'valid-binop', r'exec-binop', r'op-irotl'), + Instruction(r'\I64.\ROTR', r'\hex{8A}', r'[\I64~\I64] \to [\I64]', r'valid-binop', r'exec-binop', r'op-irotr'), + Instruction(r'\F32.\ABS', r'\hex{8B}', r'[\F32] \to [\F32]', r'valid-unop', r'exec-unop', r'op-fabs'), + Instruction(r'\F32.\NEG', r'\hex{8C}', r'[\F32] \to [\F32]', r'valid-unop', r'exec-unop', r'op-fneg'), + Instruction(r'\F32.\CEIL', r'\hex{8D}', r'[\F32] \to [\F32]', r'valid-unop', r'exec-unop', r'op-fceil'), + Instruction(r'\F32.\FLOOR', r'\hex{8E}', r'[\F32] \to [\F32]', r'valid-unop', r'exec-unop', r'op-ffloor'), + Instruction(r'\F32.\TRUNC', r'\hex{8F}', r'[\F32] \to [\F32]', r'valid-unop', r'exec-unop', r'op-ftrunc'), + Instruction(r'\F32.\NEAREST', r'\hex{90}', r'[\F32] \to [\F32]', r'valid-unop', r'exec-unop', r'op-fnearest'), + Instruction(r'\F32.\SQRT', r'\hex{91}', r'[\F32] \to [\F32]', r'valid-unop', r'exec-unop', r'op-fsqrt'), + Instruction(r'\F32.\ADD', r'\hex{92}', r'[\F32~\F32] \to [\F32]', r'valid-binop', r'exec-binop', r'op-fadd'), + Instruction(r'\F32.\SUB', r'\hex{93}', r'[\F32~\F32] \to [\F32]', r'valid-binop', r'exec-binop', r'op-fsub'), + Instruction(r'\F32.\MUL', r'\hex{94}', r'[\F32~\F32] \to [\F32]', r'valid-binop', r'exec-binop', r'op-fmul'), + Instruction(r'\F32.\DIV', r'\hex{95}', r'[\F32~\F32] \to [\F32]', r'valid-binop', r'exec-binop', r'op-fdiv'), + Instruction(r'\F32.\FMIN', r'\hex{96}', r'[\F32~\F32] \to [\F32]', r'valid-binop', r'exec-binop', r'op-fmin'), + Instruction(r'\F32.\FMAX', r'\hex{97}', r'[\F32~\F32] \to [\F32]', r'valid-binop', r'exec-binop', r'op-fmax'), + Instruction(r'\F32.\COPYSIGN', r'\hex{98}', r'[\F32~\F32] \to [\F32]', r'valid-binop', r'exec-binop', r'op-fcopysign'), + Instruction(r'\F64.\ABS', r'\hex{99}', r'[\F64] \to [\F64]', r'valid-unop', r'exec-unop', r'op-fabs'), + Instruction(r'\F64.\NEG', r'\hex{9A}', r'[\F64] \to [\F64]', r'valid-unop', r'exec-unop', r'op-fneg'), + Instruction(r'\F64.\CEIL', r'\hex{9B}', r'[\F64] \to [\F64]', r'valid-unop', r'exec-unop', r'op-fceil'), + Instruction(r'\F64.\FLOOR', r'\hex{9C}', r'[\F64] \to [\F64]', r'valid-unop', r'exec-unop', r'op-ffloor'), + Instruction(r'\F64.\TRUNC', r'\hex{9D}', r'[\F64] \to [\F64]', r'valid-unop', r'exec-unop', r'op-ftrunc'), + Instruction(r'\F64.\NEAREST', r'\hex{9E}', r'[\F64] \to [\F64]', r'valid-unop', r'exec-unop', r'op-fnearest'), + Instruction(r'\F64.\SQRT', r'\hex{9F}', r'[\F64] \to [\F64]', r'valid-unop', r'exec-unop', r'op-fsqrt'), + Instruction(r'\F64.\ADD', r'\hex{A0}', r'[\F64~\F64] \to [\F64]', r'valid-binop', r'exec-binop', r'op-fadd'), + Instruction(r'\F64.\SUB', r'\hex{A1}', r'[\F64~\F64] \to [\F64]', r'valid-binop', r'exec-binop', r'op-fsub'), + Instruction(r'\F64.\MUL', r'\hex{A2}', r'[\F64~\F64] \to [\F64]', r'valid-binop', r'exec-binop', r'op-fmul'), + Instruction(r'\F64.\DIV', r'\hex{A3}', r'[\F64~\F64] \to [\F64]', r'valid-binop', r'exec-binop', r'op-fdiv'), + Instruction(r'\F64.\FMIN', r'\hex{A4}', r'[\F64~\F64] \to [\F64]', r'valid-binop', r'exec-binop', r'op-fmin'), + Instruction(r'\F64.\FMAX', r'\hex{A5}', r'[\F64~\F64] \to [\F64]', r'valid-binop', r'exec-binop', r'op-fmax'), + Instruction(r'\F64.\COPYSIGN', r'\hex{A6}', r'[\F64~\F64] \to [\F64]', r'valid-binop', r'exec-binop', r'op-fcopysign'), + Instruction(r'\I32.\WRAP\K{\_}\I64', r'\hex{A7}', r'[\I64] \to [\I32]', r'valid-cvtop', r'exec-cvtop', r'op-wrap'), + Instruction(r'\I32.\TRUNC\K{\_}\F32\K{\_s}', r'\hex{A8}', r'[\F32] \to [\I32]', r'valid-cvtop', r'exec-cvtop', r'op-trunc_s'), + Instruction(r'\I32.\TRUNC\K{\_}\F32\K{\_u}', r'\hex{A9}', r'[\F32] \to [\I32]', r'valid-cvtop', r'exec-cvtop', r'op-trunc_u'), + Instruction(r'\I32.\TRUNC\K{\_}\F64\K{\_s}', r'\hex{AA}', r'[\F64] \to [\I32]', r'valid-cvtop', r'exec-cvtop', r'op-trunc_s'), + Instruction(r'\I32.\TRUNC\K{\_}\F64\K{\_u}', r'\hex{AB}', r'[\F64] \to [\I32]', r'valid-cvtop', r'exec-cvtop', r'op-trunc_u'), + Instruction(r'\I64.\EXTEND\K{\_}\I32\K{\_s}', r'\hex{AC}', r'[\I32] \to [\I64]', r'valid-cvtop', r'exec-cvtop', r'op-extend_s'), + Instruction(r'\I64.\EXTEND\K{\_}\I32\K{\_u}', r'\hex{AD}', r'[\I32] \to [\I64]', r'valid-cvtop', r'exec-cvtop', r'op-extend_u'), + Instruction(r'\I64.\TRUNC\K{\_}\F32\K{\_s}', r'\hex{AE}', r'[\F32] \to [\I64]', r'valid-cvtop', r'exec-cvtop', r'op-trunc_s'), + Instruction(r'\I64.\TRUNC\K{\_}\F32\K{\_u}', r'\hex{AF}', r'[\F32] \to [\I64]', r'valid-cvtop', r'exec-cvtop', r'op-trunc_u'), + Instruction(r'\I64.\TRUNC\K{\_}\F64\K{\_s}', r'\hex{B0}', r'[\F64] \to [\I64]', r'valid-cvtop', r'exec-cvtop', r'op-trunc_s'), + Instruction(r'\I64.\TRUNC\K{\_}\F64\K{\_u}', r'\hex{B1}', r'[\F64] \to [\I64]', r'valid-cvtop', r'exec-cvtop', r'op-trunc_u'), + Instruction(r'\F32.\CONVERT\K{\_}\I32\K{\_s}', r'\hex{B2}', r'[\I32] \to [\F32]', r'valid-cvtop', r'exec-cvtop', r'op-convert_s'), + Instruction(r'\F32.\CONVERT\K{\_}\I32\K{\_u}', r'\hex{B3}', r'[\I32] \to [\F32]', r'valid-cvtop', r'exec-cvtop', r'op-convert_u'), + Instruction(r'\F32.\CONVERT\K{\_}\I64\K{\_s}', r'\hex{B4}', r'[\I64] \to [\F32]', r'valid-cvtop', r'exec-cvtop', r'op-convert_s'), + Instruction(r'\F32.\CONVERT\K{\_}\I64\K{\_u}', r'\hex{B5}', r'[\I64] \to [\F32]', r'valid-cvtop', r'exec-cvtop', r'op-convert_u'), + Instruction(r'\F32.\DEMOTE\K{\_}\F64', r'\hex{B6}', r'[\F64] \to [\F32]', r'valid-cvtop', r'exec-cvtop', r'op-demote'), + Instruction(r'\F64.\CONVERT\K{\_}\I32\K{\_s}', r'\hex{B7}', r'[\I32] \to [\F64]', r'valid-cvtop', r'exec-cvtop', r'op-convert_s'), + Instruction(r'\F64.\CONVERT\K{\_}\I32\K{\_u}', r'\hex{B8}', r'[\I32] \to [\F64]', r'valid-cvtop', r'exec-cvtop', r'op-convert_u'), + Instruction(r'\F64.\CONVERT\K{\_}\I64\K{\_s}', r'\hex{B9}', r'[\I64] \to [\F64]', r'valid-cvtop', r'exec-cvtop', r'op-convert_s'), + Instruction(r'\F64.\CONVERT\K{\_}\I64\K{\_u}', r'\hex{BA}', r'[\I64] \to [\F64]', r'valid-cvtop', r'exec-cvtop', r'op-convert_u'), + Instruction(r'\F64.\PROMOTE\K{\_}\F32', r'\hex{BB}', r'[\F32] \to [\F64]', r'valid-cvtop', r'exec-cvtop', r'op-promote'), + Instruction(r'\I32.\REINTERPRET\K{\_}\F32', r'\hex{BC}', r'[\F32] \to [\I32]', r'valid-cvtop', r'exec-cvtop', r'op-reinterpret'), + Instruction(r'\I64.\REINTERPRET\K{\_}\F64', r'\hex{BD}', r'[\F64] \to [\I64]', r'valid-cvtop', r'exec-cvtop', r'op-reinterpret'), + Instruction(r'\F32.\REINTERPRET\K{\_}\I32', r'\hex{BE}', r'[\I32] \to [\F32]', r'valid-cvtop', r'exec-cvtop', r'op-reinterpret'), + Instruction(r'\F64.\REINTERPRET\K{\_}\I64', r'\hex{BF}', r'[\I64] \to [\F64]', r'valid-cvtop', r'exec-cvtop', r'op-reinterpret'), + Instruction(r'\I32.\EXTEND\K{8\_s}', r'\hex{C0}', r'[\I32] \to [\I32]', r'valid-unop', r'exec-unop', r'op-iextendn_s'), + Instruction(r'\I32.\EXTEND\K{16\_s}', r'\hex{C1}', r'[\I32] \to [\I32]', r'valid-unop', r'exec-unop', r'op-iextendn_s'), + 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'), + Instruction(r'\I32.\TRUNC\K{\_sat\_}\F64\K{\_u}', r'\hex{FC}~~3', r'[\F64] \to [\I32]', r'valid-cvtop', r'exec-cvtop', r'op-trunc_sat_u'), + Instruction(r'\I64.\TRUNC\K{\_sat\_}\F32\K{\_s}', r'\hex{FC}~~4', r'[\F32] \to [\I64]', r'valid-cvtop', r'exec-cvtop', r'op-trunc_sat_s'), + Instruction(r'\I64.\TRUNC\K{\_sat\_}\F32\K{\_u}', r'\hex{FC}~~5', r'[\F32] \to [\I64]', r'valid-cvtop', r'exec-cvtop', r'op-trunc_sat_u'), + Instruction(r'\I64.\TRUNC\K{\_sat}\_\F64\K{\_s}', r'\hex{FC}~~6', r'[\F64] \to [\I64]', r'valid-cvtop', r'exec-cvtop', r'op-trunc_sat_s'), + Instruction(r'\I64.\TRUNC\K{\_sat\_}\F64\K{\_u}', r'\hex{FC}~~7', r'[\F64] \to [\I64]', r'valid-cvtop', r'exec-cvtop', r'op-trunc_sat_u'), +] + +def ColumnWidth(n): + return max([len(instr[n]) for instr in INSTRUCTIONS]) + +COLUMN_WIDTHS = [ColumnWidth(i) for i in range(len(COLUMNS))] +DIVIDER = ' '.join('=' * width for width in COLUMN_WIDTHS) + +def Row(columns): + return ' '.join(('{:%d}' % COLUMN_WIDTHS[i]).format(column) + for i, column in enumerate(columns)) + +if __name__ == '__main__': + with open(INDEX_INSTRUCTIONS_RST, 'w') as f: + print(HEADER, file=f) + print(DIVIDER, file=f) + print(Row(COLUMNS), file=f) + print(DIVIDER, file=f) + + for instr in INSTRUCTIONS: + print(Row(instr), file=f) + + print(DIVIDER, file=f) diff --git a/document/core/appendix/index-instructions.rst b/document/core/appendix/index-instructions.rst index 535549484c..cb988b288e 100644 --- a/document/core/appendix/index-instructions.rst +++ b/document/core/appendix/index-instructions.rst @@ -1,222 +1,272 @@ +.. DO NOT EDIT: This file is auto-generated by the gen-index-instructions.py script. + .. index:: instruction .. _index-instr: Index of Instructions --------------------- -========================================= ==================== ============================================= ======================================= =============================================================== -Instruction Binary Opcode Type Validation Execution -========================================= ==================== ============================================= ======================================= =============================================================== -:math:`\UNREACHABLE` :math:`\hex{00}` :math:`[t_1^\ast] \to [t_2^\ast]` :ref:`validation ` :ref:`execution ` -:math:`\NOP` :math:`\hex{01}` :math:`[] \to []` :ref:`validation ` :ref:`execution ` -:math:`\BLOCK~\X{bt}` :math:`\hex{02}` :math:`[t_1^\ast] \to [t_2^\ast]` :ref:`validation ` :ref:`execution ` -:math:`\LOOP~\X{bt}` :math:`\hex{03}` :math:`[t_1^\ast] \to [t_2^\ast]` :ref:`validation ` :ref:`execution ` -:math:`\IF~\X{bt}` :math:`\hex{04}` :math:`[t_1^\ast] \to [t_2^\ast]` :ref:`validation ` :ref:`execution ` -:math:`\ELSE` :math:`\hex{05}` -(reserved) :math:`\hex{06}` -(reserved) :math:`\hex{07}` -(reserved) :math:`\hex{08}` -(reserved) :math:`\hex{09}` -(reserved) :math:`\hex{0A}` -:math:`\END` :math:`\hex{0B}` -:math:`\BR~l` :math:`\hex{0C}` :math:`[t_1^\ast~t^\ast] \to [t_2^\ast]` :ref:`validation ` :ref:`execution ` -:math:`\BRIF~l` :math:`\hex{0D}` :math:`[t^\ast~\I32] \to [t^\ast]` :ref:`validation ` :ref:`execution ` -:math:`\BRTABLE~l^\ast~l` :math:`\hex{0E}` :math:`[t_1^\ast~t^\ast~\I32] \to [t_2^\ast]` :ref:`validation ` :ref:`execution ` -:math:`\RETURN` :math:`\hex{0F}` :math:`[t_1^\ast~t^\ast] \to [t_2^\ast]` :ref:`validation ` :ref:`execution ` -:math:`\CALL~x` :math:`\hex{10}` :math:`[t_1^\ast] \to [t_2^\ast]` :ref:`validation ` :ref:`execution ` -:math:`\CALLINDIRECT~x` :math:`\hex{11}` :math:`[t_1^\ast~\I32] \to [t_2^\ast]` :ref:`validation ` :ref:`execution ` -(reserved) :math:`\hex{12}` -(reserved) :math:`\hex{13}` -(reserved) :math:`\hex{14}` -(reserved) :math:`\hex{15}` -(reserved) :math:`\hex{16}` -(reserved) :math:`\hex{17}` -(reserved) :math:`\hex{18}` -(reserved) :math:`\hex{19}` -:math:`\DROP` :math:`\hex{1A}` :math:`[t] \to []` :ref:`validation ` :ref:`execution ` -:math:`\SELECT` :math:`\hex{1B}` :math:`[t~t~\I32] \to [t]` :ref:`validation ` :ref:`execution ` -(reserved) :math:`\hex{1C}` -(reserved) :math:`\hex{1D}` -(reserved) :math:`\hex{1E}` -(reserved) :math:`\hex{1F}` -:math:`\LOCALGET~x` :math:`\hex{20}` :math:`[] \to [t]` :ref:`validation ` :ref:`execution ` -:math:`\LOCALSET~x` :math:`\hex{21}` :math:`[t] \to []` :ref:`validation ` :ref:`execution ` -:math:`\LOCALTEE~x` :math:`\hex{22}` :math:`[t] \to [t]` :ref:`validation ` :ref:`execution ` -:math:`\GLOBALGET~x` :math:`\hex{23}` :math:`[] \to [t]` :ref:`validation ` :ref:`execution ` -:math:`\GLOBALSET~x` :math:`\hex{24}` :math:`[t] \to []` :ref:`validation ` :ref:`execution ` -(reserved) :math:`\hex{25}` -(reserved) :math:`\hex{26}` -(reserved) :math:`\hex{27}` -:math:`\I32.\LOAD~\memarg` :math:`\hex{28}` :math:`[\I32] \to [\I32]` :ref:`validation ` :ref:`execution ` -:math:`\I64.\LOAD~\memarg` :math:`\hex{29}` :math:`[\I32] \to [\I64]` :ref:`validation ` :ref:`execution ` -:math:`\F32.\LOAD~\memarg` :math:`\hex{2A}` :math:`[\I32] \to [\F32]` :ref:`validation ` :ref:`execution ` -:math:`\F64.\LOAD~\memarg` :math:`\hex{2B}` :math:`[\I32] \to [\F64]` :ref:`validation ` :ref:`execution ` -:math:`\I32.\LOAD\K{8\_s}~\memarg` :math:`\hex{2C}` :math:`[\I32] \to [\I32]` :ref:`validation ` :ref:`execution ` -:math:`\I32.\LOAD\K{8\_u}~\memarg` :math:`\hex{2D}` :math:`[\I32] \to [\I32]` :ref:`validation ` :ref:`execution ` -:math:`\I32.\LOAD\K{16\_s}~\memarg` :math:`\hex{2E}` :math:`[\I32] \to [\I32]` :ref:`validation ` :ref:`execution ` -:math:`\I32.\LOAD\K{16\_u}~\memarg` :math:`\hex{2F}` :math:`[\I32] \to [\I32]` :ref:`validation ` :ref:`execution ` -:math:`\I64.\LOAD\K{8\_s}~\memarg` :math:`\hex{30}` :math:`[\I32] \to [\I64]` :ref:`validation ` :ref:`execution ` -:math:`\I64.\LOAD\K{8\_u}~\memarg` :math:`\hex{31}` :math:`[\I32] \to [\I64]` :ref:`validation ` :ref:`execution ` -:math:`\I64.\LOAD\K{16\_s}~\memarg` :math:`\hex{32}` :math:`[\I32] \to [\I64]` :ref:`validation ` :ref:`execution ` -:math:`\I64.\LOAD\K{16\_u}~\memarg` :math:`\hex{33}` :math:`[\I32] \to [\I64]` :ref:`validation ` :ref:`execution ` -:math:`\I64.\LOAD\K{32\_s}~\memarg` :math:`\hex{34}` :math:`[\I32] \to [\I64]` :ref:`validation ` :ref:`execution ` -:math:`\I64.\LOAD\K{32\_u}~\memarg` :math:`\hex{35}` :math:`[\I32] \to [\I64]` :ref:`validation ` :ref:`execution ` -:math:`\I32.\STORE~\memarg` :math:`\hex{36}` :math:`[\I32~\I32] \to []` :ref:`validation ` :ref:`execution ` -:math:`\I64.\STORE~\memarg` :math:`\hex{37}` :math:`[\I32~\I64] \to []` :ref:`validation ` :ref:`execution ` -:math:`\F32.\STORE~\memarg` :math:`\hex{38}` :math:`[\I32~\F32] \to []` :ref:`validation ` :ref:`execution ` -:math:`\F64.\STORE~\memarg` :math:`\hex{39}` :math:`[\I32~\F64] \to []` :ref:`validation ` :ref:`execution ` -:math:`\I32.\STORE\K{8}~\memarg` :math:`\hex{3A}` :math:`[\I32~\I32] \to []` :ref:`validation ` :ref:`execution ` -:math:`\I32.\STORE\K{16}~\memarg` :math:`\hex{3B}` :math:`[\I32~\I32] \to []` :ref:`validation ` :ref:`execution ` -:math:`\I64.\STORE\K{8}~\memarg` :math:`\hex{3C}` :math:`[\I32~\I64] \to []` :ref:`validation ` :ref:`execution ` -:math:`\I64.\STORE\K{16}~\memarg` :math:`\hex{3D}` :math:`[\I32~\I64] \to []` :ref:`validation ` :ref:`execution ` -:math:`\I64.\STORE\K{32}~\memarg` :math:`\hex{3E}` :math:`[\I32~\I64] \to []` :ref:`validation ` :ref:`execution ` -:math:`\MEMORYSIZE` :math:`\hex{3F}` :math:`[] \to [\I32]` :ref:`validation ` :ref:`execution ` -:math:`\MEMORYGROW` :math:`\hex{40}` :math:`[\I32] \to [\I32]` :ref:`validation ` :ref:`execution ` -:math:`\I32.\CONST~\i32` :math:`\hex{41}` :math:`[] \to [\I32]` :ref:`validation ` :ref:`execution ` -:math:`\I64.\CONST~\i64` :math:`\hex{42}` :math:`[] \to [\I64]` :ref:`validation ` :ref:`execution ` -:math:`\F32.\CONST~\f32` :math:`\hex{43}` :math:`[] \to [\F32]` :ref:`validation ` :ref:`execution ` -:math:`\F64.\CONST~\f64` :math:`\hex{44}` :math:`[] \to [\F64]` :ref:`validation ` :ref:`execution ` -:math:`\I32.\EQZ` :math:`\hex{45}` :math:`[\I32] \to [\I32]` :ref:`validation ` :ref:`execution `, :ref:`operator ` -:math:`\I32.\EQ` :math:`\hex{46}` :math:`[\I32~\I32] \to [\I32]` :ref:`validation ` :ref:`execution `, :ref:`operator ` -:math:`\I32.\NE` :math:`\hex{47}` :math:`[\I32~\I32] \to [\I32]` :ref:`validation ` :ref:`execution `, :ref:`operator ` -:math:`\I32.\LT\K{\_s}` :math:`\hex{48}` :math:`[\I32~\I32] \to [\I32]` :ref:`validation ` :ref:`execution `, :ref:`operator ` -:math:`\I32.\LT\K{\_u}` :math:`\hex{49}` :math:`[\I32~\I32] \to [\I32]` :ref:`validation ` :ref:`execution `, :ref:`operator ` -:math:`\I32.\GT\K{\_s}` :math:`\hex{4A}` :math:`[\I32~\I32] \to [\I32]` :ref:`validation ` :ref:`execution `, :ref:`operator ` -:math:`\I32.\GT\K{\_u}` :math:`\hex{4B}` :math:`[\I32~\I32] \to [\I32]` :ref:`validation ` :ref:`execution `, :ref:`operator ` -:math:`\I32.\LE\K{\_s}` :math:`\hex{4C}` :math:`[\I32~\I32] \to [\I32]` :ref:`validation ` :ref:`execution `, :ref:`operator ` -:math:`\I32.\LE\K{\_u}` :math:`\hex{4D}` :math:`[\I32~\I32] \to [\I32]` :ref:`validation ` :ref:`execution `, :ref:`operator ` -:math:`\I32.\GE\K{\_s}` :math:`\hex{4E}` :math:`[\I32~\I32] \to [\I32]` :ref:`validation ` :ref:`execution `, :ref:`operator ` -:math:`\I32.\GE\K{\_u}` :math:`\hex{4F}` :math:`[\I32~\I32] \to [\I32]` :ref:`validation ` :ref:`execution `, :ref:`operator ` -:math:`\I64.\EQZ` :math:`\hex{50}` :math:`[\I64] \to [\I32]` :ref:`validation ` :ref:`execution `, :ref:`operator ` -:math:`\I64.\EQ` :math:`\hex{51}` :math:`[\I64~\I64] \to [\I32]` :ref:`validation ` :ref:`execution `, :ref:`operator ` -:math:`\I64.\NE` :math:`\hex{52}` :math:`[\I64~\I64] \to [\I32]` :ref:`validation ` :ref:`execution `, :ref:`operator ` -:math:`\I64.\LT\K{\_s}` :math:`\hex{53}` :math:`[\I64~\I64] \to [\I32]` :ref:`validation ` :ref:`execution `, :ref:`operator ` -:math:`\I64.\LT\K{\_u}` :math:`\hex{54}` :math:`[\I64~\I64] \to [\I32]` :ref:`validation ` :ref:`execution `, :ref:`operator ` -:math:`\I64.\GT\K{\_s}` :math:`\hex{55}` :math:`[\I64~\I64] \to [\I32]` :ref:`validation ` :ref:`execution `, :ref:`operator ` -:math:`\I64.\GT\K{\_u}` :math:`\hex{56}` :math:`[\I64~\I64] \to [\I32]` :ref:`validation ` :ref:`execution `, :ref:`operator ` -:math:`\I64.\LE\K{\_s}` :math:`\hex{57}` :math:`[\I64~\I64] \to [\I32]` :ref:`validation ` :ref:`execution `, :ref:`operator ` -:math:`\I64.\LE\K{\_u}` :math:`\hex{58}` :math:`[\I64~\I64] \to [\I32]` :ref:`validation ` :ref:`execution `, :ref:`operator ` -:math:`\I64.\GE\K{\_s}` :math:`\hex{59}` :math:`[\I64~\I64] \to [\I32]` :ref:`validation ` :ref:`execution `, :ref:`operator ` -:math:`\I64.\GE\K{\_u}` :math:`\hex{5A}` :math:`[\I64~\I64] \to [\I32]` :ref:`validation ` :ref:`execution `, :ref:`operator ` -:math:`\F32.\EQ` :math:`\hex{5B}` :math:`[\F32~\F32] \to [\I32]` :ref:`validation ` :ref:`execution `, :ref:`operator ` -:math:`\F32.\NE` :math:`\hex{5C}` :math:`[\F32~\F32] \to [\I32]` :ref:`validation ` :ref:`execution `, :ref:`operator ` -:math:`\F32.\LT` :math:`\hex{5D}` :math:`[\F32~\F32] \to [\I32]` :ref:`validation ` :ref:`execution `, :ref:`operator ` -:math:`\F32.\GT` :math:`\hex{5E}` :math:`[\F32~\F32] \to [\I32]` :ref:`validation ` :ref:`execution `, :ref:`operator ` -:math:`\F32.\LE` :math:`\hex{5F}` :math:`[\F32~\F32] \to [\I32]` :ref:`validation ` :ref:`execution `, :ref:`operator ` -:math:`\F32.\GE` :math:`\hex{60}` :math:`[\F32~\F32] \to [\I32]` :ref:`validation ` :ref:`execution `, :ref:`operator ` -:math:`\F64.\EQ` :math:`\hex{61}` :math:`[\F64~\F64] \to [\I32]` :ref:`validation ` :ref:`execution `, :ref:`operator ` -:math:`\F64.\NE` :math:`\hex{62}` :math:`[\F64~\F64] \to [\I32]` :ref:`validation ` :ref:`execution `, :ref:`operator ` -:math:`\F64.\LT` :math:`\hex{63}` :math:`[\F64~\F64] \to [\I32]` :ref:`validation ` :ref:`execution `, :ref:`operator ` -:math:`\F64.\GT` :math:`\hex{64}` :math:`[\F64~\F64] \to [\I32]` :ref:`validation ` :ref:`execution `, :ref:`operator ` -:math:`\F64.\LE` :math:`\hex{65}` :math:`[\F64~\F64] \to [\I32]` :ref:`validation ` :ref:`execution `, :ref:`operator ` -:math:`\F64.\GE` :math:`\hex{66}` :math:`[\F64~\F64] \to [\I32]` :ref:`validation ` :ref:`execution `, :ref:`operator ` -:math:`\I32.\CLZ` :math:`\hex{67}` :math:`[\I32] \to [\I32]` :ref:`validation ` :ref:`execution `, :ref:`operator ` -:math:`\I32.\CTZ` :math:`\hex{68}` :math:`[\I32] \to [\I32]` :ref:`validation ` :ref:`execution `, :ref:`operator ` -:math:`\I32.\POPCNT` :math:`\hex{69}` :math:`[\I32] \to [\I32]` :ref:`validation ` :ref:`execution `, :ref:`operator ` -:math:`\I32.\ADD` :math:`\hex{6A}` :math:`[\I32~\I32] \to [\I32]` :ref:`validation ` :ref:`execution `, :ref:`operator ` -:math:`\I32.\SUB` :math:`\hex{6B}` :math:`[\I32~\I32] \to [\I32]` :ref:`validation ` :ref:`execution `, :ref:`operator ` -:math:`\I32.\MUL` :math:`\hex{6C}` :math:`[\I32~\I32] \to [\I32]` :ref:`validation ` :ref:`execution `, :ref:`operator ` -:math:`\I32.\DIV\K{\_s}` :math:`\hex{6D}` :math:`[\I32~\I32] \to [\I32]` :ref:`validation ` :ref:`execution `, :ref:`operator ` -:math:`\I32.\DIV\K{\_u}` :math:`\hex{6E}` :math:`[\I32~\I32] \to [\I32]` :ref:`validation ` :ref:`execution `, :ref:`operator ` -:math:`\I32.\REM\K{\_s}` :math:`\hex{6F}` :math:`[\I32~\I32] \to [\I32]` :ref:`validation ` :ref:`execution `, :ref:`operator ` -:math:`\I32.\REM\K{\_u}` :math:`\hex{70}` :math:`[\I32~\I32] \to [\I32]` :ref:`validation ` :ref:`execution `, :ref:`operator ` -:math:`\I32.\AND` :math:`\hex{71}` :math:`[\I32~\I32] \to [\I32]` :ref:`validation ` :ref:`execution `, :ref:`operator ` -:math:`\I32.\OR` :math:`\hex{72}` :math:`[\I32~\I32] \to [\I32]` :ref:`validation ` :ref:`execution `, :ref:`operator ` -:math:`\I32.\XOR` :math:`\hex{73}` :math:`[\I32~\I32] \to [\I32]` :ref:`validation ` :ref:`execution `, :ref:`operator ` -:math:`\I32.\SHL` :math:`\hex{74}` :math:`[\I32~\I32] \to [\I32]` :ref:`validation ` :ref:`execution `, :ref:`operator ` -:math:`\I32.\SHR\K{\_s}` :math:`\hex{75}` :math:`[\I32~\I32] \to [\I32]` :ref:`validation ` :ref:`execution `, :ref:`operator ` -:math:`\I32.\SHR\K{\_u}` :math:`\hex{76}` :math:`[\I32~\I32] \to [\I32]` :ref:`validation ` :ref:`execution `, :ref:`operator ` -:math:`\I32.\ROTL` :math:`\hex{77}` :math:`[\I32~\I32] \to [\I32]` :ref:`validation ` :ref:`execution `, :ref:`operator ` -:math:`\I32.\ROTR` :math:`\hex{78}` :math:`[\I32~\I32] \to [\I32]` :ref:`validation ` :ref:`execution `, :ref:`operator ` -:math:`\I64.\CLZ` :math:`\hex{79}` :math:`[\I64] \to [\I64]` :ref:`validation ` :ref:`execution `, :ref:`operator ` -:math:`\I64.\CTZ` :math:`\hex{7A}` :math:`[\I64] \to [\I64]` :ref:`validation ` :ref:`execution `, :ref:`operator ` -:math:`\I64.\POPCNT` :math:`\hex{7B}` :math:`[\I64] \to [\I64]` :ref:`validation ` :ref:`execution `, :ref:`operator ` -:math:`\I64.\ADD` :math:`\hex{7C}` :math:`[\I64~\I64] \to [\I64]` :ref:`validation ` :ref:`execution `, :ref:`operator ` -:math:`\I64.\SUB` :math:`\hex{7D}` :math:`[\I64~\I64] \to [\I64]` :ref:`validation ` :ref:`execution `, :ref:`operator ` -:math:`\I64.\MUL` :math:`\hex{7E}` :math:`[\I64~\I64] \to [\I64]` :ref:`validation ` :ref:`execution `, :ref:`operator ` -:math:`\I64.\DIV\K{\_s}` :math:`\hex{7F}` :math:`[\I64~\I64] \to [\I64]` :ref:`validation ` :ref:`execution `, :ref:`operator ` -:math:`\I64.\DIV\K{\_u}` :math:`\hex{80}` :math:`[\I64~\I64] \to [\I64]` :ref:`validation ` :ref:`execution `, :ref:`operator ` -:math:`\I64.\REM\K{\_s}` :math:`\hex{81}` :math:`[\I64~\I64] \to [\I64]` :ref:`validation ` :ref:`execution `, :ref:`operator ` -:math:`\I64.\REM\K{\_u}` :math:`\hex{82}` :math:`[\I64~\I64] \to [\I64]` :ref:`validation ` :ref:`execution `, :ref:`operator ` -:math:`\I64.\AND` :math:`\hex{83}` :math:`[\I64~\I64] \to [\I64]` :ref:`validation ` :ref:`execution `, :ref:`operator ` -:math:`\I64.\OR` :math:`\hex{84}` :math:`[\I64~\I64] \to [\I64]` :ref:`validation ` :ref:`execution `, :ref:`operator ` -:math:`\I64.\XOR` :math:`\hex{85}` :math:`[\I64~\I64] \to [\I64]` :ref:`validation ` :ref:`execution `, :ref:`operator ` -:math:`\I64.\SHL` :math:`\hex{86}` :math:`[\I64~\I64] \to [\I64]` :ref:`validation ` :ref:`execution `, :ref:`operator ` -:math:`\I64.\SHR\K{\_s}` :math:`\hex{87}` :math:`[\I64~\I64] \to [\I64]` :ref:`validation ` :ref:`execution `, :ref:`operator ` -:math:`\I64.\SHR\K{\_u}` :math:`\hex{88}` :math:`[\I64~\I64] \to [\I64]` :ref:`validation ` :ref:`execution `, :ref:`operator ` -:math:`\I64.\ROTL` :math:`\hex{89}` :math:`[\I64~\I64] \to [\I64]` :ref:`validation ` :ref:`execution `, :ref:`operator ` -:math:`\I64.\ROTR` :math:`\hex{8A}` :math:`[\I64~\I64] \to [\I64]` :ref:`validation ` :ref:`execution `, :ref:`operator ` -:math:`\F32.\ABS` :math:`\hex{8B}` :math:`[\F32] \to [\F32]` :ref:`validation ` :ref:`execution `, :ref:`operator ` -:math:`\F32.\NEG` :math:`\hex{8C}` :math:`[\F32] \to [\F32]` :ref:`validation ` :ref:`execution `, :ref:`operator ` -:math:`\F32.\CEIL` :math:`\hex{8D}` :math:`[\F32] \to [\F32]` :ref:`validation ` :ref:`execution `, :ref:`operator ` -:math:`\F32.\FLOOR` :math:`\hex{8E}` :math:`[\F32] \to [\F32]` :ref:`validation ` :ref:`execution `, :ref:`operator ` -:math:`\F32.\TRUNC` :math:`\hex{8F}` :math:`[\F32] \to [\F32]` :ref:`validation ` :ref:`execution `, :ref:`operator ` -:math:`\F32.\NEAREST` :math:`\hex{90}` :math:`[\F32] \to [\F32]` :ref:`validation ` :ref:`execution `, :ref:`operator ` -:math:`\F32.\SQRT` :math:`\hex{91}` :math:`[\F32] \to [\F32]` :ref:`validation ` :ref:`execution `, :ref:`operator ` -:math:`\F32.\ADD` :math:`\hex{92}` :math:`[\F32~\F32] \to [\F32]` :ref:`validation ` :ref:`execution `, :ref:`operator ` -:math:`\F32.\SUB` :math:`\hex{93}` :math:`[\F32~\F32] \to [\F32]` :ref:`validation ` :ref:`execution `, :ref:`operator ` -:math:`\F32.\MUL` :math:`\hex{94}` :math:`[\F32~\F32] \to [\F32]` :ref:`validation ` :ref:`execution `, :ref:`operator ` -:math:`\F32.\DIV` :math:`\hex{95}` :math:`[\F32~\F32] \to [\F32]` :ref:`validation ` :ref:`execution `, :ref:`operator ` -:math:`\F32.\FMIN` :math:`\hex{96}` :math:`[\F32~\F32] \to [\F32]` :ref:`validation ` :ref:`execution `, :ref:`operator ` -:math:`\F32.\FMAX` :math:`\hex{97}` :math:`[\F32~\F32] \to [\F32]` :ref:`validation ` :ref:`execution `, :ref:`operator ` -:math:`\F32.\COPYSIGN` :math:`\hex{98}` :math:`[\F32~\F32] \to [\F32]` :ref:`validation ` :ref:`execution `, :ref:`operator ` -:math:`\F64.\ABS` :math:`\hex{99}` :math:`[\F64] \to [\F64]` :ref:`validation ` :ref:`execution `, :ref:`operator ` -:math:`\F64.\NEG` :math:`\hex{9A}` :math:`[\F64] \to [\F64]` :ref:`validation ` :ref:`execution `, :ref:`operator ` -:math:`\F64.\CEIL` :math:`\hex{9B}` :math:`[\F64] \to [\F64]` :ref:`validation ` :ref:`execution `, :ref:`operator ` -:math:`\F64.\FLOOR` :math:`\hex{9C}` :math:`[\F64] \to [\F64]` :ref:`validation ` :ref:`execution `, :ref:`operator ` -:math:`\F64.\TRUNC` :math:`\hex{9D}` :math:`[\F64] \to [\F64]` :ref:`validation ` :ref:`execution `, :ref:`operator ` -:math:`\F64.\NEAREST` :math:`\hex{9E}` :math:`[\F64] \to [\F64]` :ref:`validation ` :ref:`execution `, :ref:`operator ` -:math:`\F64.\SQRT` :math:`\hex{9F}` :math:`[\F64] \to [\F64]` :ref:`validation ` :ref:`execution `, :ref:`operator ` -:math:`\F64.\ADD` :math:`\hex{A0}` :math:`[\F64~\F64] \to [\F64]` :ref:`validation ` :ref:`execution `, :ref:`operator ` -:math:`\F64.\SUB` :math:`\hex{A1}` :math:`[\F64~\F64] \to [\F64]` :ref:`validation ` :ref:`execution `, :ref:`operator ` -:math:`\F64.\MUL` :math:`\hex{A2}` :math:`[\F64~\F64] \to [\F64]` :ref:`validation ` :ref:`execution `, :ref:`operator ` -:math:`\F64.\DIV` :math:`\hex{A3}` :math:`[\F64~\F64] \to [\F64]` :ref:`validation ` :ref:`execution `, :ref:`operator ` -:math:`\F64.\FMIN` :math:`\hex{A4}` :math:`[\F64~\F64] \to [\F64]` :ref:`validation ` :ref:`execution `, :ref:`operator ` -:math:`\F64.\FMAX` :math:`\hex{A5}` :math:`[\F64~\F64] \to [\F64]` :ref:`validation ` :ref:`execution `, :ref:`operator ` -:math:`\F64.\COPYSIGN` :math:`\hex{A6}` :math:`[\F64~\F64] \to [\F64]` :ref:`validation ` :ref:`execution `, :ref:`operator ` -:math:`\I32.\WRAP\K{\_}\I64` :math:`\hex{A7}` :math:`[\I64] \to [\I32]` :ref:`validation ` :ref:`execution `, :ref:`operator ` -:math:`\I32.\TRUNC\K{\_}\F32\K{\_s}` :math:`\hex{A8}` :math:`[\F32] \to [\I32]` :ref:`validation ` :ref:`execution `, :ref:`operator ` -:math:`\I32.\TRUNC\K{\_}\F32\K{\_u}` :math:`\hex{A9}` :math:`[\F32] \to [\I32]` :ref:`validation ` :ref:`execution `, :ref:`operator ` -:math:`\I32.\TRUNC\K{\_}\F64\K{\_s}` :math:`\hex{AA}` :math:`[\F64] \to [\I32]` :ref:`validation ` :ref:`execution `, :ref:`operator ` -:math:`\I32.\TRUNC\K{\_}\F64\K{\_u}` :math:`\hex{AB}` :math:`[\F64] \to [\I32]` :ref:`validation ` :ref:`execution `, :ref:`operator ` -:math:`\I64.\EXTEND\K{\_}\I32\K{\_s}` :math:`\hex{AC}` :math:`[\I32] \to [\I64]` :ref:`validation ` :ref:`execution `, :ref:`operator ` -:math:`\I64.\EXTEND\K{\_}\I32\K{\_u}` :math:`\hex{AD}` :math:`[\I32] \to [\I64]` :ref:`validation ` :ref:`execution `, :ref:`operator ` -:math:`\I64.\TRUNC\K{\_}\F32\K{\_s}` :math:`\hex{AE}` :math:`[\F32] \to [\I64]` :ref:`validation ` :ref:`execution `, :ref:`operator ` -:math:`\I64.\TRUNC\K{\_}\F32\K{\_u}` :math:`\hex{AF}` :math:`[\F32] \to [\I64]` :ref:`validation ` :ref:`execution `, :ref:`operator ` -:math:`\I64.\TRUNC\K{\_}\F64\K{\_s}` :math:`\hex{B0}` :math:`[\F64] \to [\I64]` :ref:`validation ` :ref:`execution `, :ref:`operator ` -:math:`\I64.\TRUNC\K{\_}\F64\K{\_u}` :math:`\hex{B1}` :math:`[\F64] \to [\I64]` :ref:`validation ` :ref:`execution `, :ref:`operator ` -:math:`\F32.\CONVERT\K{\_}\I32\K{\_s}` :math:`\hex{B2}` :math:`[\I32] \to [\F32]` :ref:`validation ` :ref:`execution `, :ref:`operator ` -:math:`\F32.\CONVERT\K{\_}\I32\K{\_u}` :math:`\hex{B3}` :math:`[\I32] \to [\F32]` :ref:`validation ` :ref:`execution `, :ref:`operator ` -:math:`\F32.\CONVERT\K{\_}\I64\K{\_s}` :math:`\hex{B4}` :math:`[\I64] \to [\F32]` :ref:`validation ` :ref:`execution `, :ref:`operator ` -:math:`\F32.\CONVERT\K{\_}\I64\K{\_u}` :math:`\hex{B5}` :math:`[\I64] \to [\F32]` :ref:`validation ` :ref:`execution `, :ref:`operator ` -:math:`\F32.\DEMOTE\K{\_}\F64` :math:`\hex{B6}` :math:`[\F64] \to [\F32]` :ref:`validation ` :ref:`execution `, :ref:`operator ` -:math:`\F64.\CONVERT\K{\_}\I32\K{\_s}` :math:`\hex{B7}` :math:`[\I32] \to [\F64]` :ref:`validation ` :ref:`execution `, :ref:`operator ` -:math:`\F64.\CONVERT\K{\_}\I32\K{\_u}` :math:`\hex{B8}` :math:`[\I32] \to [\F64]` :ref:`validation ` :ref:`execution `, :ref:`operator ` -:math:`\F64.\CONVERT\K{\_}\I64\K{\_s}` :math:`\hex{B9}` :math:`[\I64] \to [\F64]` :ref:`validation ` :ref:`execution `, :ref:`operator ` -:math:`\F64.\CONVERT\K{\_}\I64\K{\_u}` :math:`\hex{BA}` :math:`[\I64] \to [\F64]` :ref:`validation ` :ref:`execution `, :ref:`operator ` -:math:`\F64.\PROMOTE\K{\_}\F32` :math:`\hex{BB}` :math:`[\F32] \to [\F64]` :ref:`validation ` :ref:`execution `, :ref:`operator ` -:math:`\I32.\REINTERPRET\K{\_}\F32` :math:`\hex{BC}` :math:`[\F32] \to [\I32]` :ref:`validation ` :ref:`execution `, :ref:`operator ` -:math:`\I64.\REINTERPRET\K{\_}\F64` :math:`\hex{BD}` :math:`[\F64] \to [\I64]` :ref:`validation ` :ref:`execution `, :ref:`operator ` -:math:`\F32.\REINTERPRET\K{\_}\I32` :math:`\hex{BE}` :math:`[\I32] \to [\F32]` :ref:`validation ` :ref:`execution `, :ref:`operator ` -:math:`\F64.\REINTERPRET\K{\_}\I64` :math:`\hex{BF}` :math:`[\I64] \to [\F64]` :ref:`validation ` :ref:`execution `, :ref:`operator ` -:math:`\I32.\EXTEND\K{8\_s}` :math:`\hex{C0}` :math:`[\I32] \to [\I32]` :ref:`validation ` :ref:`execution `, :ref:`operator ` -:math:`\I32.\EXTEND\K{16\_s}` :math:`\hex{C1}` :math:`[\I32] \to [\I32]` :ref:`validation ` :ref:`execution `, :ref:`operator ` -: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 ` -: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 ` -:math:`\I32.\TRUNC\K{\_sat\_}\F64\K{\_u}` :math:`\hex{FC}~~3` :math:`[\F64] \to [\I32]` :ref:`validation ` :ref:`execution `, :ref:`operator ` -:math:`\I64.\TRUNC\K{\_sat\_}\F32\K{\_s}` :math:`\hex{FC}~~4` :math:`[\F32] \to [\I64]` :ref:`validation ` :ref:`execution `, :ref:`operator ` -:math:`\I64.\TRUNC\K{\_sat\_}\F32\K{\_u}` :math:`\hex{FC}~~5` :math:`[\F32] \to [\I64]` :ref:`validation ` :ref:`execution `, :ref:`operator ` -:math:`\I64.\TRUNC\K{\_sat}\_\F64\K{\_s}` :math:`\hex{FC}~~6` :math:`[\F64] \to [\I64]` :ref:`validation ` :ref:`execution `, :ref:`operator ` -:math:`\I64.\TRUNC\K{\_sat\_}\F64\K{\_u}` :math:`\hex{FC}~~7` :math:`[\F64] \to [\I64]` :ref:`validation ` :ref:`execution `, :ref:`operator ` -:math:`\MEMORYINIT` :math:`\hex{FC}~~8` :math:`[\I32~\I32~\I32] \to []` :ref:`validation ` :ref:`execution ` -:math:`\DATADROP` :math:`\hex{FC}~~9` :math:`[] \to []` :ref:`validation ` :ref:`execution ` -:math:`\MEMORYCOPY` :math:`\hex{FC}~~10` :math:`[\I32~\I32~\I32] \to []` :ref:`validation ` :ref:`execution ` -:math:`\MEMORYFILL` :math:`\hex{FC}~~11` :math:`[\I32~\I32~\I32] \to []` :ref:`validation ` :ref:`execution ` -:math:`\TABLEINIT` :math:`\hex{FC}~~12` :math:`[\I32~\I32~\I32] \to []` :ref:`validation ` :ref:`execution ` -:math:`\ELEMDROP` :math:`\hex{FC}~~13` :math:`[] \to []` :ref:`validation ` :ref:`execution ` -:math:`\TABLECOPY` :math:`\hex{FC}~~14` :math:`[\I32~\I32~\I32] \to []` :ref:`validation ` :ref:`execution ` -========================================= ==================== ============================================= ======================================= =============================================================== +========================================= =================== ============================================= ======================================= =============================================================== +Instruction Binary Opcode Type Validation Execution +========================================= =================== ============================================= ======================================= =============================================================== +:math:`\UNREACHABLE` :math:`\hex{00}` :math:`[t_1^\ast] \to [t_2^\ast]` :ref:`validation ` :ref:`execution ` +:math:`\NOP` :math:`\hex{01}` :math:`[] \to []` :ref:`validation ` :ref:`execution ` +:math:`\BLOCK~\X{bt}` :math:`\hex{02}` :math:`[t_1^\ast] \to [t_2^\ast]` :ref:`validation ` :ref:`execution ` +:math:`\LOOP~\X{bt}` :math:`\hex{03}` :math:`[t_1^\ast] \to [t_2^\ast]` :ref:`validation ` :ref:`execution ` +:math:`\IF~\X{bt}` :math:`\hex{04}` :math:`[t_1^\ast] \to [t_2^\ast]` :ref:`validation ` :ref:`execution ` +:math:`\ELSE` :math:`\hex{05}` +(reserved) :math:`\hex{06}` +(reserved) :math:`\hex{07}` +(reserved) :math:`\hex{08}` +(reserved) :math:`\hex{09}` +(reserved) :math:`\hex{0A}` +:math:`\END` :math:`\hex{0B}` +:math:`\BR~l` :math:`\hex{0C}` :math:`[t_1^\ast~t^\ast] \to [t_2^\ast]` :ref:`validation ` :ref:`execution ` +:math:`\BRIF~l` :math:`\hex{0D}` :math:`[t^\ast~\I32] \to [t^\ast]` :ref:`validation ` :ref:`execution ` +:math:`\BRTABLE~l^\ast~l` :math:`\hex{0E}` :math:`[t_1^\ast~t^\ast~\I32] \to [t_2^\ast]` :ref:`validation ` :ref:`execution ` +:math:`\RETURN` :math:`\hex{0F}` :math:`[t_1^\ast~t^\ast] \to [t_2^\ast]` :ref:`validation ` :ref:`execution ` +:math:`\CALL~x` :math:`\hex{10}` :math:`[t_1^\ast] \to [t_2^\ast]` :ref:`validation ` :ref:`execution ` +:math:`\CALLINDIRECT~x` :math:`\hex{11}` :math:`[t_1^\ast~\I32] \to [t_2^\ast]` :ref:`validation ` :ref:`execution ` +(reserved) :math:`\hex{12}` +(reserved) :math:`\hex{13}` +(reserved) :math:`\hex{14}` +(reserved) :math:`\hex{15}` +(reserved) :math:`\hex{16}` +(reserved) :math:`\hex{17}` +(reserved) :math:`\hex{18}` +(reserved) :math:`\hex{19}` +:math:`\DROP` :math:`\hex{1A}` :math:`[t] \to []` :ref:`validation ` :ref:`execution ` +:math:`\SELECT` :math:`\hex{1B}` :math:`[t~t~\I32] \to [t]` :ref:`validation ` :ref:`execution ` +(reserved) :math:`\hex{1C}` +(reserved) :math:`\hex{1D}` +(reserved) :math:`\hex{1E}` +(reserved) :math:`\hex{1F}` +:math:`\LOCALGET~x` :math:`\hex{20}` :math:`[] \to [t]` :ref:`validation ` :ref:`execution ` +:math:`\LOCALSET~x` :math:`\hex{21}` :math:`[t] \to []` :ref:`validation ` :ref:`execution ` +:math:`\LOCALTEE~x` :math:`\hex{22}` :math:`[t] \to [t]` :ref:`validation ` :ref:`execution ` +:math:`\GLOBALGET~x` :math:`\hex{23}` :math:`[] \to [t]` :ref:`validation ` :ref:`execution ` +:math:`\GLOBALSET~x` :math:`\hex{24}` :math:`[t] \to []` :ref:`validation ` :ref:`execution ` +(reserved) :math:`\hex{25}` +(reserved) :math:`\hex{26}` +(reserved) :math:`\hex{27}` +:math:`\I32.\LOAD~\memarg` :math:`\hex{28}` :math:`[\I32] \to [\I32]` :ref:`validation ` :ref:`execution ` +:math:`\I64.\LOAD~\memarg` :math:`\hex{29}` :math:`[\I32] \to [\I64]` :ref:`validation ` :ref:`execution ` +:math:`\F32.\LOAD~\memarg` :math:`\hex{2A}` :math:`[\I32] \to [\F32]` :ref:`validation ` :ref:`execution ` +:math:`\F64.\LOAD~\memarg` :math:`\hex{2B}` :math:`[\I32] \to [\F64]` :ref:`validation ` :ref:`execution ` +:math:`\I32.\LOAD\K{8\_s}~\memarg` :math:`\hex{2C}` :math:`[\I32] \to [\I32]` :ref:`validation ` :ref:`execution ` +:math:`\I32.\LOAD\K{8\_u}~\memarg` :math:`\hex{2D}` :math:`[\I32] \to [\I32]` :ref:`validation ` :ref:`execution ` +:math:`\I32.\LOAD\K{16\_s}~\memarg` :math:`\hex{2E}` :math:`[\I32] \to [\I32]` :ref:`validation ` :ref:`execution ` +:math:`\I32.\LOAD\K{16\_u}~\memarg` :math:`\hex{2F}` :math:`[\I32] \to [\I32]` :ref:`validation ` :ref:`execution ` +:math:`\I64.\LOAD\K{8\_s}~\memarg` :math:`\hex{30}` :math:`[\I32] \to [\I64]` :ref:`validation ` :ref:`execution ` +:math:`\I64.\LOAD\K{8\_u}~\memarg` :math:`\hex{31}` :math:`[\I32] \to [\I64]` :ref:`validation ` :ref:`execution ` +:math:`\I64.\LOAD\K{16\_s}~\memarg` :math:`\hex{32}` :math:`[\I32] \to [\I64]` :ref:`validation ` :ref:`execution ` +:math:`\I64.\LOAD\K{16\_u}~\memarg` :math:`\hex{33}` :math:`[\I32] \to [\I64]` :ref:`validation ` :ref:`execution ` +:math:`\I64.\LOAD\K{32\_s}~\memarg` :math:`\hex{34}` :math:`[\I32] \to [\I64]` :ref:`validation ` :ref:`execution ` +:math:`\I64.\LOAD\K{32\_u}~\memarg` :math:`\hex{35}` :math:`[\I32] \to [\I64]` :ref:`validation ` :ref:`execution ` +:math:`\I32.\STORE~\memarg` :math:`\hex{36}` :math:`[\I32~\I32] \to []` :ref:`validation ` :ref:`execution ` +:math:`\I64.\STORE~\memarg` :math:`\hex{37}` :math:`[\I32~\I64] \to []` :ref:`validation ` :ref:`execution ` +:math:`\F32.\STORE~\memarg` :math:`\hex{38}` :math:`[\I32~\F32] \to []` :ref:`validation ` :ref:`execution ` +:math:`\F64.\STORE~\memarg` :math:`\hex{39}` :math:`[\I32~\F64] \to []` :ref:`validation ` :ref:`execution ` +:math:`\I32.\STORE\K{8}~\memarg` :math:`\hex{3A}` :math:`[\I32~\I32] \to []` :ref:`validation ` :ref:`execution ` +:math:`\I32.\STORE\K{16}~\memarg` :math:`\hex{3B}` :math:`[\I32~\I32] \to []` :ref:`validation ` :ref:`execution ` +:math:`\I64.\STORE\K{8}~\memarg` :math:`\hex{3C}` :math:`[\I32~\I64] \to []` :ref:`validation ` :ref:`execution ` +:math:`\I64.\STORE\K{16}~\memarg` :math:`\hex{3D}` :math:`[\I32~\I64] \to []` :ref:`validation ` :ref:`execution ` +:math:`\I64.\STORE\K{32}~\memarg` :math:`\hex{3E}` :math:`[\I32~\I64] \to []` :ref:`validation ` :ref:`execution ` +:math:`\MEMORYSIZE` :math:`\hex{3F}` :math:`[] \to [\I32]` :ref:`validation ` :ref:`execution ` +:math:`\MEMORYGROW` :math:`\hex{40}` :math:`[\I32] \to [\I32]` :ref:`validation ` :ref:`execution ` +:math:`\I32.\CONST~\i32` :math:`\hex{41}` :math:`[] \to [\I32]` :ref:`validation ` :ref:`execution ` +:math:`\I64.\CONST~\i64` :math:`\hex{42}` :math:`[] \to [\I64]` :ref:`validation ` :ref:`execution ` +:math:`\F32.\CONST~\f32` :math:`\hex{43}` :math:`[] \to [\F32]` :ref:`validation ` :ref:`execution ` +:math:`\F64.\CONST~\f64` :math:`\hex{44}` :math:`[] \to [\F64]` :ref:`validation ` :ref:`execution ` +:math:`\I32.\EQZ` :math:`\hex{45}` :math:`[\I32] \to [\I32]` :ref:`validation ` :ref:`execution `, :ref:`operator ` +:math:`\I32.\EQ` :math:`\hex{46}` :math:`[\I32~\I32] \to [\I32]` :ref:`validation ` :ref:`execution `, :ref:`operator ` +:math:`\I32.\NE` :math:`\hex{47}` :math:`[\I32~\I32] \to [\I32]` :ref:`validation ` :ref:`execution `, :ref:`operator ` +:math:`\I32.\LT\K{\_s}` :math:`\hex{48}` :math:`[\I32~\I32] \to [\I32]` :ref:`validation ` :ref:`execution `, :ref:`operator ` +:math:`\I32.\LT\K{\_u}` :math:`\hex{49}` :math:`[\I32~\I32] \to [\I32]` :ref:`validation ` :ref:`execution `, :ref:`operator ` +:math:`\I32.\GT\K{\_s}` :math:`\hex{4A}` :math:`[\I32~\I32] \to [\I32]` :ref:`validation ` :ref:`execution `, :ref:`operator ` +:math:`\I32.\GT\K{\_u}` :math:`\hex{4B}` :math:`[\I32~\I32] \to [\I32]` :ref:`validation ` :ref:`execution `, :ref:`operator ` +:math:`\I32.\LE\K{\_s}` :math:`\hex{4C}` :math:`[\I32~\I32] \to [\I32]` :ref:`validation ` :ref:`execution `, :ref:`operator ` +:math:`\I32.\LE\K{\_u}` :math:`\hex{4D}` :math:`[\I32~\I32] \to [\I32]` :ref:`validation ` :ref:`execution `, :ref:`operator ` +:math:`\I32.\GE\K{\_s}` :math:`\hex{4E}` :math:`[\I32~\I32] \to [\I32]` :ref:`validation ` :ref:`execution `, :ref:`operator ` +:math:`\I32.\GE\K{\_u}` :math:`\hex{4F}` :math:`[\I32~\I32] \to [\I32]` :ref:`validation ` :ref:`execution `, :ref:`operator ` +:math:`\I64.\EQZ` :math:`\hex{50}` :math:`[\I64] \to [\I32]` :ref:`validation ` :ref:`execution `, :ref:`operator ` +:math:`\I64.\EQ` :math:`\hex{51}` :math:`[\I64~\I64] \to [\I32]` :ref:`validation ` :ref:`execution `, :ref:`operator ` +:math:`\I64.\NE` :math:`\hex{52}` :math:`[\I64~\I64] \to [\I32]` :ref:`validation ` :ref:`execution `, :ref:`operator ` +:math:`\I64.\LT\K{\_s}` :math:`\hex{53}` :math:`[\I64~\I64] \to [\I32]` :ref:`validation ` :ref:`execution `, :ref:`operator ` +:math:`\I64.\LT\K{\_u}` :math:`\hex{54}` :math:`[\I64~\I64] \to [\I32]` :ref:`validation ` :ref:`execution `, :ref:`operator ` +:math:`\I64.\GT\K{\_s}` :math:`\hex{55}` :math:`[\I64~\I64] \to [\I32]` :ref:`validation ` :ref:`execution `, :ref:`operator ` +:math:`\I64.\GT\K{\_u}` :math:`\hex{56}` :math:`[\I64~\I64] \to [\I32]` :ref:`validation ` :ref:`execution `, :ref:`operator ` +:math:`\I64.\LE\K{\_s}` :math:`\hex{57}` :math:`[\I64~\I64] \to [\I32]` :ref:`validation ` :ref:`execution `, :ref:`operator ` +:math:`\I64.\LE\K{\_u}` :math:`\hex{58}` :math:`[\I64~\I64] \to [\I32]` :ref:`validation ` :ref:`execution `, :ref:`operator ` +:math:`\I64.\GE\K{\_s}` :math:`\hex{59}` :math:`[\I64~\I64] \to [\I32]` :ref:`validation ` :ref:`execution `, :ref:`operator ` +:math:`\I64.\GE\K{\_u}` :math:`\hex{5A}` :math:`[\I64~\I64] \to [\I32]` :ref:`validation ` :ref:`execution `, :ref:`operator ` +:math:`\F32.\EQ` :math:`\hex{5B}` :math:`[\F32~\F32] \to [\I32]` :ref:`validation ` :ref:`execution `, :ref:`operator ` +:math:`\F32.\NE` :math:`\hex{5C}` :math:`[\F32~\F32] \to [\I32]` :ref:`validation ` :ref:`execution `, :ref:`operator ` +:math:`\F32.\LT` :math:`\hex{5D}` :math:`[\F32~\F32] \to [\I32]` :ref:`validation ` :ref:`execution `, :ref:`operator ` +:math:`\F32.\GT` :math:`\hex{5E}` :math:`[\F32~\F32] \to [\I32]` :ref:`validation ` :ref:`execution `, :ref:`operator ` +:math:`\F32.\LE` :math:`\hex{5F}` :math:`[\F32~\F32] \to [\I32]` :ref:`validation ` :ref:`execution `, :ref:`operator ` +:math:`\F32.\GE` :math:`\hex{60}` :math:`[\F32~\F32] \to [\I32]` :ref:`validation ` :ref:`execution `, :ref:`operator ` +:math:`\F64.\EQ` :math:`\hex{61}` :math:`[\F64~\F64] \to [\I32]` :ref:`validation ` :ref:`execution `, :ref:`operator ` +:math:`\F64.\NE` :math:`\hex{62}` :math:`[\F64~\F64] \to [\I32]` :ref:`validation ` :ref:`execution `, :ref:`operator ` +:math:`\F64.\LT` :math:`\hex{63}` :math:`[\F64~\F64] \to [\I32]` :ref:`validation ` :ref:`execution `, :ref:`operator ` +:math:`\F64.\GT` :math:`\hex{64}` :math:`[\F64~\F64] \to [\I32]` :ref:`validation ` :ref:`execution `, :ref:`operator ` +:math:`\F64.\LE` :math:`\hex{65}` :math:`[\F64~\F64] \to [\I32]` :ref:`validation ` :ref:`execution `, :ref:`operator ` +:math:`\F64.\GE` :math:`\hex{66}` :math:`[\F64~\F64] \to [\I32]` :ref:`validation ` :ref:`execution `, :ref:`operator ` +:math:`\I32.\CLZ` :math:`\hex{67}` :math:`[\I32] \to [\I32]` :ref:`validation ` :ref:`execution `, :ref:`operator ` +:math:`\I32.\CTZ` :math:`\hex{68}` :math:`[\I32] \to [\I32]` :ref:`validation ` :ref:`execution `, :ref:`operator ` +:math:`\I32.\POPCNT` :math:`\hex{69}` :math:`[\I32] \to [\I32]` :ref:`validation ` :ref:`execution `, :ref:`operator ` +:math:`\I32.\ADD` :math:`\hex{6A}` :math:`[\I32~\I32] \to [\I32]` :ref:`validation ` :ref:`execution `, :ref:`operator ` +:math:`\I32.\SUB` :math:`\hex{6B}` :math:`[\I32~\I32] \to [\I32]` :ref:`validation ` :ref:`execution `, :ref:`operator ` +:math:`\I32.\MUL` :math:`\hex{6C}` :math:`[\I32~\I32] \to [\I32]` :ref:`validation ` :ref:`execution `, :ref:`operator ` +:math:`\I32.\DIV\K{\_s}` :math:`\hex{6D}` :math:`[\I32~\I32] \to [\I32]` :ref:`validation ` :ref:`execution `, :ref:`operator ` +:math:`\I32.\DIV\K{\_u}` :math:`\hex{6E}` :math:`[\I32~\I32] \to [\I32]` :ref:`validation ` :ref:`execution `, :ref:`operator ` +:math:`\I32.\REM\K{\_s}` :math:`\hex{6F}` :math:`[\I32~\I32] \to [\I32]` :ref:`validation ` :ref:`execution `, :ref:`operator ` +:math:`\I32.\REM\K{\_u}` :math:`\hex{70}` :math:`[\I32~\I32] \to [\I32]` :ref:`validation ` :ref:`execution `, :ref:`operator ` +:math:`\I32.\AND` :math:`\hex{71}` :math:`[\I32~\I32] \to [\I32]` :ref:`validation ` :ref:`execution `, :ref:`operator ` +:math:`\I32.\OR` :math:`\hex{72}` :math:`[\I32~\I32] \to [\I32]` :ref:`validation ` :ref:`execution `, :ref:`operator ` +:math:`\I32.\XOR` :math:`\hex{73}` :math:`[\I32~\I32] \to [\I32]` :ref:`validation ` :ref:`execution `, :ref:`operator ` +:math:`\I32.\SHL` :math:`\hex{74}` :math:`[\I32~\I32] \to [\I32]` :ref:`validation ` :ref:`execution `, :ref:`operator ` +:math:`\I32.\SHR\K{\_s}` :math:`\hex{75}` :math:`[\I32~\I32] \to [\I32]` :ref:`validation ` :ref:`execution `, :ref:`operator ` +:math:`\I32.\SHR\K{\_u}` :math:`\hex{76}` :math:`[\I32~\I32] \to [\I32]` :ref:`validation ` :ref:`execution `, :ref:`operator ` +:math:`\I32.\ROTL` :math:`\hex{77}` :math:`[\I32~\I32] \to [\I32]` :ref:`validation ` :ref:`execution `, :ref:`operator ` +:math:`\I32.\ROTR` :math:`\hex{78}` :math:`[\I32~\I32] \to [\I32]` :ref:`validation ` :ref:`execution `, :ref:`operator ` +:math:`\I64.\CLZ` :math:`\hex{79}` :math:`[\I64] \to [\I64]` :ref:`validation ` :ref:`execution `, :ref:`operator ` +:math:`\I64.\CTZ` :math:`\hex{7A}` :math:`[\I64] \to [\I64]` :ref:`validation ` :ref:`execution `, :ref:`operator ` +:math:`\I64.\POPCNT` :math:`\hex{7B}` :math:`[\I64] \to [\I64]` :ref:`validation ` :ref:`execution `, :ref:`operator ` +:math:`\I64.\ADD` :math:`\hex{7C}` :math:`[\I64~\I64] \to [\I64]` :ref:`validation ` :ref:`execution `, :ref:`operator ` +:math:`\I64.\SUB` :math:`\hex{7D}` :math:`[\I64~\I64] \to [\I64]` :ref:`validation ` :ref:`execution `, :ref:`operator ` +:math:`\I64.\MUL` :math:`\hex{7E}` :math:`[\I64~\I64] \to [\I64]` :ref:`validation ` :ref:`execution `, :ref:`operator ` +:math:`\I64.\DIV\K{\_s}` :math:`\hex{7F}` :math:`[\I64~\I64] \to [\I64]` :ref:`validation ` :ref:`execution `, :ref:`operator ` +:math:`\I64.\DIV\K{\_u}` :math:`\hex{80}` :math:`[\I64~\I64] \to [\I64]` :ref:`validation ` :ref:`execution `, :ref:`operator ` +:math:`\I64.\REM\K{\_s}` :math:`\hex{81}` :math:`[\I64~\I64] \to [\I64]` :ref:`validation ` :ref:`execution `, :ref:`operator ` +:math:`\I64.\REM\K{\_u}` :math:`\hex{82}` :math:`[\I64~\I64] \to [\I64]` :ref:`validation ` :ref:`execution `, :ref:`operator ` +:math:`\I64.\AND` :math:`\hex{83}` :math:`[\I64~\I64] \to [\I64]` :ref:`validation ` :ref:`execution `, :ref:`operator ` +:math:`\I64.\OR` :math:`\hex{84}` :math:`[\I64~\I64] \to [\I64]` :ref:`validation ` :ref:`execution `, :ref:`operator ` +:math:`\I64.\XOR` :math:`\hex{85}` :math:`[\I64~\I64] \to [\I64]` :ref:`validation ` :ref:`execution `, :ref:`operator ` +:math:`\I64.\SHL` :math:`\hex{86}` :math:`[\I64~\I64] \to [\I64]` :ref:`validation ` :ref:`execution `, :ref:`operator ` +:math:`\I64.\SHR\K{\_s}` :math:`\hex{87}` :math:`[\I64~\I64] \to [\I64]` :ref:`validation ` :ref:`execution `, :ref:`operator ` +:math:`\I64.\SHR\K{\_u}` :math:`\hex{88}` :math:`[\I64~\I64] \to [\I64]` :ref:`validation ` :ref:`execution `, :ref:`operator ` +:math:`\I64.\ROTL` :math:`\hex{89}` :math:`[\I64~\I64] \to [\I64]` :ref:`validation ` :ref:`execution `, :ref:`operator ` +:math:`\I64.\ROTR` :math:`\hex{8A}` :math:`[\I64~\I64] \to [\I64]` :ref:`validation ` :ref:`execution `, :ref:`operator ` +:math:`\F32.\ABS` :math:`\hex{8B}` :math:`[\F32] \to [\F32]` :ref:`validation ` :ref:`execution `, :ref:`operator ` +:math:`\F32.\NEG` :math:`\hex{8C}` :math:`[\F32] \to [\F32]` :ref:`validation ` :ref:`execution `, :ref:`operator ` +:math:`\F32.\CEIL` :math:`\hex{8D}` :math:`[\F32] \to [\F32]` :ref:`validation ` :ref:`execution `, :ref:`operator ` +:math:`\F32.\FLOOR` :math:`\hex{8E}` :math:`[\F32] \to [\F32]` :ref:`validation ` :ref:`execution `, :ref:`operator ` +:math:`\F32.\TRUNC` :math:`\hex{8F}` :math:`[\F32] \to [\F32]` :ref:`validation ` :ref:`execution `, :ref:`operator ` +:math:`\F32.\NEAREST` :math:`\hex{90}` :math:`[\F32] \to [\F32]` :ref:`validation ` :ref:`execution `, :ref:`operator ` +:math:`\F32.\SQRT` :math:`\hex{91}` :math:`[\F32] \to [\F32]` :ref:`validation ` :ref:`execution `, :ref:`operator ` +:math:`\F32.\ADD` :math:`\hex{92}` :math:`[\F32~\F32] \to [\F32]` :ref:`validation ` :ref:`execution `, :ref:`operator ` +:math:`\F32.\SUB` :math:`\hex{93}` :math:`[\F32~\F32] \to [\F32]` :ref:`validation ` :ref:`execution `, :ref:`operator ` +:math:`\F32.\MUL` :math:`\hex{94}` :math:`[\F32~\F32] \to [\F32]` :ref:`validation ` :ref:`execution `, :ref:`operator ` +:math:`\F32.\DIV` :math:`\hex{95}` :math:`[\F32~\F32] \to [\F32]` :ref:`validation ` :ref:`execution `, :ref:`operator ` +:math:`\F32.\FMIN` :math:`\hex{96}` :math:`[\F32~\F32] \to [\F32]` :ref:`validation ` :ref:`execution `, :ref:`operator ` +:math:`\F32.\FMAX` :math:`\hex{97}` :math:`[\F32~\F32] \to [\F32]` :ref:`validation ` :ref:`execution `, :ref:`operator ` +:math:`\F32.\COPYSIGN` :math:`\hex{98}` :math:`[\F32~\F32] \to [\F32]` :ref:`validation ` :ref:`execution `, :ref:`operator ` +:math:`\F64.\ABS` :math:`\hex{99}` :math:`[\F64] \to [\F64]` :ref:`validation ` :ref:`execution `, :ref:`operator ` +:math:`\F64.\NEG` :math:`\hex{9A}` :math:`[\F64] \to [\F64]` :ref:`validation ` :ref:`execution `, :ref:`operator ` +:math:`\F64.\CEIL` :math:`\hex{9B}` :math:`[\F64] \to [\F64]` :ref:`validation ` :ref:`execution `, :ref:`operator ` +:math:`\F64.\FLOOR` :math:`\hex{9C}` :math:`[\F64] \to [\F64]` :ref:`validation ` :ref:`execution `, :ref:`operator ` +:math:`\F64.\TRUNC` :math:`\hex{9D}` :math:`[\F64] \to [\F64]` :ref:`validation ` :ref:`execution `, :ref:`operator ` +:math:`\F64.\NEAREST` :math:`\hex{9E}` :math:`[\F64] \to [\F64]` :ref:`validation ` :ref:`execution `, :ref:`operator ` +:math:`\F64.\SQRT` :math:`\hex{9F}` :math:`[\F64] \to [\F64]` :ref:`validation ` :ref:`execution `, :ref:`operator ` +:math:`\F64.\ADD` :math:`\hex{A0}` :math:`[\F64~\F64] \to [\F64]` :ref:`validation ` :ref:`execution `, :ref:`operator ` +:math:`\F64.\SUB` :math:`\hex{A1}` :math:`[\F64~\F64] \to [\F64]` :ref:`validation ` :ref:`execution `, :ref:`operator ` +:math:`\F64.\MUL` :math:`\hex{A2}` :math:`[\F64~\F64] \to [\F64]` :ref:`validation ` :ref:`execution `, :ref:`operator ` +:math:`\F64.\DIV` :math:`\hex{A3}` :math:`[\F64~\F64] \to [\F64]` :ref:`validation ` :ref:`execution `, :ref:`operator ` +:math:`\F64.\FMIN` :math:`\hex{A4}` :math:`[\F64~\F64] \to [\F64]` :ref:`validation ` :ref:`execution `, :ref:`operator ` +:math:`\F64.\FMAX` :math:`\hex{A5}` :math:`[\F64~\F64] \to [\F64]` :ref:`validation ` :ref:`execution `, :ref:`operator ` +:math:`\F64.\COPYSIGN` :math:`\hex{A6}` :math:`[\F64~\F64] \to [\F64]` :ref:`validation ` :ref:`execution `, :ref:`operator ` +:math:`\I32.\WRAP\K{\_}\I64` :math:`\hex{A7}` :math:`[\I64] \to [\I32]` :ref:`validation ` :ref:`execution `, :ref:`operator ` +:math:`\I32.\TRUNC\K{\_}\F32\K{\_s}` :math:`\hex{A8}` :math:`[\F32] \to [\I32]` :ref:`validation ` :ref:`execution `, :ref:`operator ` +:math:`\I32.\TRUNC\K{\_}\F32\K{\_u}` :math:`\hex{A9}` :math:`[\F32] \to [\I32]` :ref:`validation ` :ref:`execution `, :ref:`operator ` +:math:`\I32.\TRUNC\K{\_}\F64\K{\_s}` :math:`\hex{AA}` :math:`[\F64] \to [\I32]` :ref:`validation ` :ref:`execution `, :ref:`operator ` +:math:`\I32.\TRUNC\K{\_}\F64\K{\_u}` :math:`\hex{AB}` :math:`[\F64] \to [\I32]` :ref:`validation ` :ref:`execution `, :ref:`operator ` +:math:`\I64.\EXTEND\K{\_}\I32\K{\_s}` :math:`\hex{AC}` :math:`[\I32] \to [\I64]` :ref:`validation ` :ref:`execution `, :ref:`operator ` +:math:`\I64.\EXTEND\K{\_}\I32\K{\_u}` :math:`\hex{AD}` :math:`[\I32] \to [\I64]` :ref:`validation ` :ref:`execution `, :ref:`operator ` +:math:`\I64.\TRUNC\K{\_}\F32\K{\_s}` :math:`\hex{AE}` :math:`[\F32] \to [\I64]` :ref:`validation ` :ref:`execution `, :ref:`operator ` +:math:`\I64.\TRUNC\K{\_}\F32\K{\_u}` :math:`\hex{AF}` :math:`[\F32] \to [\I64]` :ref:`validation ` :ref:`execution `, :ref:`operator ` +:math:`\I64.\TRUNC\K{\_}\F64\K{\_s}` :math:`\hex{B0}` :math:`[\F64] \to [\I64]` :ref:`validation ` :ref:`execution `, :ref:`operator ` +:math:`\I64.\TRUNC\K{\_}\F64\K{\_u}` :math:`\hex{B1}` :math:`[\F64] \to [\I64]` :ref:`validation ` :ref:`execution `, :ref:`operator ` +:math:`\F32.\CONVERT\K{\_}\I32\K{\_s}` :math:`\hex{B2}` :math:`[\I32] \to [\F32]` :ref:`validation ` :ref:`execution `, :ref:`operator ` +:math:`\F32.\CONVERT\K{\_}\I32\K{\_u}` :math:`\hex{B3}` :math:`[\I32] \to [\F32]` :ref:`validation ` :ref:`execution `, :ref:`operator ` +:math:`\F32.\CONVERT\K{\_}\I64\K{\_s}` :math:`\hex{B4}` :math:`[\I64] \to [\F32]` :ref:`validation ` :ref:`execution `, :ref:`operator ` +:math:`\F32.\CONVERT\K{\_}\I64\K{\_u}` :math:`\hex{B5}` :math:`[\I64] \to [\F32]` :ref:`validation ` :ref:`execution `, :ref:`operator ` +:math:`\F32.\DEMOTE\K{\_}\F64` :math:`\hex{B6}` :math:`[\F64] \to [\F32]` :ref:`validation ` :ref:`execution `, :ref:`operator ` +:math:`\F64.\CONVERT\K{\_}\I32\K{\_s}` :math:`\hex{B7}` :math:`[\I32] \to [\F64]` :ref:`validation ` :ref:`execution `, :ref:`operator ` +:math:`\F64.\CONVERT\K{\_}\I32\K{\_u}` :math:`\hex{B8}` :math:`[\I32] \to [\F64]` :ref:`validation ` :ref:`execution `, :ref:`operator ` +:math:`\F64.\CONVERT\K{\_}\I64\K{\_s}` :math:`\hex{B9}` :math:`[\I64] \to [\F64]` :ref:`validation ` :ref:`execution `, :ref:`operator ` +:math:`\F64.\CONVERT\K{\_}\I64\K{\_u}` :math:`\hex{BA}` :math:`[\I64] \to [\F64]` :ref:`validation ` :ref:`execution `, :ref:`operator ` +:math:`\F64.\PROMOTE\K{\_}\F32` :math:`\hex{BB}` :math:`[\F32] \to [\F64]` :ref:`validation ` :ref:`execution `, :ref:`operator ` +:math:`\I32.\REINTERPRET\K{\_}\F32` :math:`\hex{BC}` :math:`[\F32] \to [\I32]` :ref:`validation ` :ref:`execution `, :ref:`operator ` +:math:`\I64.\REINTERPRET\K{\_}\F64` :math:`\hex{BD}` :math:`[\F64] \to [\I64]` :ref:`validation ` :ref:`execution `, :ref:`operator ` +:math:`\F32.\REINTERPRET\K{\_}\I32` :math:`\hex{BE}` :math:`[\I32] \to [\F32]` :ref:`validation ` :ref:`execution `, :ref:`operator ` +:math:`\F64.\REINTERPRET\K{\_}\I64` :math:`\hex{BF}` :math:`[\I64] \to [\F64]` :ref:`validation ` :ref:`execution `, :ref:`operator ` +:math:`\I32.\EXTEND\K{8\_s}` :math:`\hex{C0}` :math:`[\I32] \to [\I32]` :ref:`validation ` :ref:`execution `, :ref:`operator ` +:math:`\I32.\EXTEND\K{16\_s}` :math:`\hex{C1}` :math:`[\I32] \to [\I32]` :ref:`validation ` :ref:`execution `, :ref:`operator ` +: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 ` +:math:`\I32.\TRUNC\K{\_sat\_}\F64\K{\_u}` :math:`\hex{FC}~~3` :math:`[\F64] \to [\I32]` :ref:`validation ` :ref:`execution `, :ref:`operator ` +:math:`\I64.\TRUNC\K{\_sat\_}\F32\K{\_s}` :math:`\hex{FC}~~4` :math:`[\F32] \to [\I64]` :ref:`validation ` :ref:`execution `, :ref:`operator ` +:math:`\I64.\TRUNC\K{\_sat\_}\F32\K{\_u}` :math:`\hex{FC}~~5` :math:`[\F32] \to [\I64]` :ref:`validation ` :ref:`execution `, :ref:`operator ` +:math:`\I64.\TRUNC\K{\_sat}\_\F64\K{\_s}` :math:`\hex{FC}~~6` :math:`[\F64] \to [\I64]` :ref:`validation ` :ref:`execution `, :ref:`operator ` +:math:`\I64.\TRUNC\K{\_sat\_}\F64\K{\_u}` :math:`\hex{FC}~~7` :math:`[\F64] \to [\I64]` :ref:`validation ` :ref:`execution `, :ref:`operator ` +========================================= =================== ============================================= ======================================= =============================================================== diff --git a/document/core/exec/instructions.rst b/document/core/exec/instructions.rst index a7e8233c09..88410b7282 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@{}} diff --git a/document/core/exec/numerics.rst b/document/core/exec/numerics.rst index 04783a4424..748ca605aa 100644 --- a/document/core/exec/numerics.rst +++ b/document/core/exec/numerics.rst @@ -1603,7 +1603,7 @@ Conversions .. math:: \begin{array}{lll@{\qquad}l} - \convertu_{M,N}(i) &=& \ieee_N(\signed_M(i)) \\ + \converts_{M,N}(i) &=& \ieee_N(\signed_M(i)) \\ \end{array} diff --git a/document/core/text/instructions.rst b/document/core/text/instructions.rst index bb00e75e6d..737ebe8e5f 100644 --- a/document/core/text/instructions.rst +++ b/document/core/text/instructions.rst @@ -430,20 +430,20 @@ Numeric Instructions \text{i32.trunc\_f32\_u} &\Rightarrow& \I32.\TRUNC\K{\_}\F32\K{\_u} \\ &&|& \text{i32.trunc\_f64\_s} &\Rightarrow& \I32.\TRUNC\K{\_}\F64\K{\_s} \\ &&|& \text{i32.trunc\_f64\_u} &\Rightarrow& \I32.\TRUNC\K{\_}\F64\K{\_u} \\ &&|& - \text{i32.trunc\_sat_f32\_s} &\Rightarrow& \I32.\TRUNC\K{\_sat\_}\F32\K{\_s} \\ &&|& - \text{i32.trunc\_sat_f32\_u} &\Rightarrow& \I32.\TRUNC\K{\_sat\_}\F32\K{\_u} \\ &&|& - \text{i32.trunc\_sat_f64\_s} &\Rightarrow& \I32.\TRUNC\K{\_sat\_}\F64\K{\_s} \\ &&|& - \text{i32.trunc\_sat_f64\_u} &\Rightarrow& \I32.\TRUNC\K{\_sat\_}\F64\K{\_u} \\ &&|& + \text{i32.trunc\_sat\_f32\_s} &\Rightarrow& \I32.\TRUNC\K{\_sat\_}\F32\K{\_s} \\ &&|& + \text{i32.trunc\_sat\_f32\_u} &\Rightarrow& \I32.\TRUNC\K{\_sat\_}\F32\K{\_u} \\ &&|& + \text{i32.trunc\_sat\_f64\_s} &\Rightarrow& \I32.\TRUNC\K{\_sat\_}\F64\K{\_s} \\ &&|& + \text{i32.trunc\_sat\_f64\_u} &\Rightarrow& \I32.\TRUNC\K{\_sat\_}\F64\K{\_u} \\ &&|& \text{i64.extend\_i32\_s} &\Rightarrow& \I64.\EXTEND\K{\_}\I32\K{\_s} \\ &&|& \text{i64.extend\_i32\_u} &\Rightarrow& \I64.\EXTEND\K{\_}\I32\K{\_u} \\ &&|& \text{i64.trunc\_f32\_s} &\Rightarrow& \I64.\TRUNC\K{\_}\F32\K{\_s} \\ &&|& \text{i64.trunc\_f32\_u} &\Rightarrow& \I64.\TRUNC\K{\_}\F32\K{\_u} \\ &&|& \text{i64.trunc\_f64\_s} &\Rightarrow& \I64.\TRUNC\K{\_}\F64\K{\_s} \\ &&|& \text{i64.trunc\_f64\_u} &\Rightarrow& \I64.\TRUNC\K{\_}\F64\K{\_u} \\ &&|& - \text{i64.trunc\_sat_f32\_s} &\Rightarrow& \I64.\TRUNC\K{\_sat\_}\F32\K{\_s} \\ &&|& - \text{i64.trunc\_sat_f32\_u} &\Rightarrow& \I64.\TRUNC\K{\_sat\_}\F32\K{\_u} \\ &&|& - \text{i64.trunc\_sat_f64\_s} &\Rightarrow& \I64.\TRUNC\K{\_sat\_}\F64\K{\_s} \\ &&|& - \text{i64.trunc\_sat_f64\_u} &\Rightarrow& \I64.\TRUNC\K{\_sat\_}\F64\K{\_u} \\ &&|& + \text{i64.trunc\_sat\_f32\_s} &\Rightarrow& \I64.\TRUNC\K{\_sat\_}\F32\K{\_s} \\ &&|& + \text{i64.trunc\_sat\_f32\_u} &\Rightarrow& \I64.\TRUNC\K{\_sat\_}\F32\K{\_u} \\ &&|& + \text{i64.trunc\_sat\_f64\_s} &\Rightarrow& \I64.\TRUNC\K{\_sat\_}\F64\K{\_s} \\ &&|& + \text{i64.trunc\_sat\_f64\_u} &\Rightarrow& \I64.\TRUNC\K{\_sat\_}\F64\K{\_u} \\ &&|& \text{f32.convert\_i32\_s} &\Rightarrow& \F32.\CONVERT\K{\_}\I32\K{\_s} \\ &&|& \text{f32.convert\_i32\_u} &\Rightarrow& \F32.\CONVERT\K{\_}\I32\K{\_u} \\ &&|& \text{f32.convert\_i64\_s} &\Rightarrow& \F32.\CONVERT\K{\_}\I64\K{\_s} \\ &&|& diff --git a/document/js-api/index.bs b/document/js-api/index.bs index 9af7e69620..91fc509859 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]]. diff --git a/document/web-api/index.bs b/document/web-api/index.bs index 564dd6ee0a..3cc6108201 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:
diff --git a/interpreter/Makefile b/interpreter/Makefile index eee4935cdf..c745311b9d 100644 --- a/interpreter/Makefile +++ b/interpreter/Makefile @@ -112,22 +112,36 @@ $(WINMAKE): clean # Executing test suite -.PHONY: test debugtest +TESTDIR = ../test/core +TESTFILES = $(shell cd $(TESTDIR); ls *.wast) +TESTS = $(TESTFILES:%.wast=%) + +.PHONY: test debugtest partest test: $(OPT) - ../test/core/run.py --wasm `pwd`/$(OPT) $(if $(JS),--js '$(JS)',) + $(TESTDIR)/run.py --wasm `pwd`/$(OPT) $(if $(JS),--js '$(JS)',) debugtest: $(UNOPT) - ../test/core/run.py --wasm `pwd`/$(UNOPT) $(if $(JS),--js '$(JS)',) + $(TESTDIR)/run.py --wasm `pwd`/$(UNOPT) $(if $(JS),--js '$(JS)',) test/%: $(OPT) - ../test/core/run.py --wasm `pwd`/$(OPT) $(if $(JS),--js '$(JS)',) $(@:test/%=../test/core/%.wast) + $(TESTDIR)/run.py --wasm `pwd`/$(OPT) $(if $(JS),--js '$(JS)',) $(TESTDIR)/$(@F).wast debugtest/%: $(UNOPT) - ../test/core/run.py --wasm `pwd`/$(UNOPT) $(if $(JS),--js '$(JS)',) $(@:debugtest/%=../test/core/%.wast) + $(TESTDIR)/run.py --wasm `pwd`/$(UNOPT) $(if $(JS),--js '$(JS)',) $(TESTDIR)/$(@F).wast run/%: $(OPT) - ./$(OPT) $(@:run/%=../test/core/%.wast) + ./$(OPT) $(TESTDIR)/$(@F).wast debug/%: $(UNOPT) - ./$(UNOPT) $(@:debug/%=../test/core/%.wast) + ./$(UNOPT) $(TESTDIR)/$(@F).wast + +partest: $(TESTS:%=quiettest/%) + @echo All tests passed. + +quiettest/%: $(OPT) + @ ( \ + $(TESTDIR)/run.py 2>$(@F).out --wasm `pwd`/$(OPT) $(if $(JS),--js '$(JS)',) $(@F:%=$(TESTDIR)/%.wast) && \ + rm $(@F).out \ + ) || \ + cat $(@F).out || rm $(@F).out || exit 1 # Miscellaneous targets diff --git a/interpreter/README.md b/interpreter/README.md index 9e210f63bf..b430f83871 100644 --- a/interpreter/README.md +++ b/interpreter/README.md @@ -370,6 +370,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/exec/int.ml b/interpreter/exec/int.ml index 7236c52831..ec23208d8e 100644 --- a/interpreter/exec/int.ml +++ b/interpreter/exec/int.ml @@ -199,7 +199,7 @@ struct let popcnt x = let rec loop acc i n = - if n = Rep.zero then + if i = 0 then acc else let acc' = if and_ n Rep.one = Rep.one then acc + 1 else acc in diff --git a/interpreter/host/spectest.ml b/interpreter/host/spectest.ml index 78f3e994a9..9d6ff9a434 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 diff --git a/test/core/binary-leb128.wast b/test/core/binary-leb128.wast index 6e015e3d00..1d67219583 100644 --- a/test/core/binary-leb128.wast +++ b/test/core/binary-leb128.wast @@ -853,7 +853,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 ) diff --git a/test/core/binary.wast b/test/core/binary.wast index c1ebddfce9..94c39a92ef 100644 --- a/test/core/binary.wast +++ b/test/core/binary.wast @@ -51,6 +51,21 @@ (assert_malformed (module binary "\00asm" "\01\00\00\00" "\81\00\01\00") "malformed section id") (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 @@ -335,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" @@ -352,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" @@ -934,10 +984,25 @@ "\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 ) - "invalid elements segment kind" + "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" ) ;; 1 elem segment declared, 2 given diff --git a/test/core/br_table.wast b/test/core/br_table.wast index 58abe38a4f..d03068744e 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 diff --git a/test/core/data.wast b/test/core/data.wast index aabe1021b2..edf640b14c 100644 --- a/test/core/data.wast +++ b/test/core/data.wast @@ -296,6 +296,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\07\01" ;; data section + "\02\01\41\00\0b" ;; active 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\07\01" ;; data section + "\02\01\41\00\0b" ;; active 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\45\01" ;; data section + "\02\01" ;; active segment, 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\45\01" ;; data section + "\02\01" ;; active segment, 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 @@ -306,6 +369,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) @@ -343,3 +440,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" +) diff --git a/test/core/elem.wast b/test/core/elem.wast index a50a1a2b36..3db092f07e 100644 --- a/test/core/elem.wast +++ b/test/core/elem.wast @@ -314,6 +314,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) @@ -352,6 +387,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/exports.wast b/test/core/exports.wast index ef1c4c17eb..0c44694dbf 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" diff --git a/test/core/global.wast b/test/core/global.wast index ef1fccbbde..55d7447b19 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))) @@ -268,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" @@ -288,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" @@ -298,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)) ) @@ -356,6 +386,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 diff --git a/test/core/imports.wast b/test/core/imports.wast index d987775ecb..733e63e34f 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" diff --git a/test/core/local_get.wast b/test/core/local_get.wast index ab564cbed0..6acab3988f 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 dde7321ec1..a158f0c7c2 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" ) diff --git a/test/core/select.wast b/test/core/select.wast index cee2054911..e40347e355 100644 --- a/test/core/select.wast +++ b/test/core/select.wast @@ -28,10 +28,19 @@ (unreachable) (select) (unreachable) (i32.const 0) (select) (unreachable) (i32.const 0) (i32.const 0) (select) + (unreachable) (i32.const 0) (i32.const 0) (i32.const 0) (select) (unreachable) (f32.const 0) (i32.const 0) (select) (unreachable) ) + (func (export "select_unreached_result_1") (result i32) + (unreachable) (i32.add (select)) + ) + + (func (export "select_unreached_result_2") (result i64) + (unreachable) (i64.add (select (i64.const 0) (i32.const 0))) + ) + ;; As the argument of control constructs and instructions (func (export "as-select-first") (param i32) (result i32) @@ -287,22 +296,22 @@ (assert_return (invoke "as-convert-operand" (i32.const 1)) (i32.const 1)) (assert_invalid - (module (func $arity-0 (select (nop) (nop) (i32.const 1)))) + (module (func $arity-0 (select (nop) (nop) (i32.const 1)) (drop))) "type mismatch" ) ;; The first two operands should have the same type as each other (assert_invalid - (module (func $type-num-vs-num (select (i32.const 1) (i64.const 1) (i32.const 1)))) + (module (func $type-num-vs-num (select (i32.const 1) (i64.const 1) (i32.const 1)) (drop))) "type mismatch" ) (assert_invalid - (module (func $type-num-vs-num (select (i32.const 1) (f32.const 1.0) (i32.const 1)))) + (module (func $type-num-vs-num (select (i32.const 1) (f32.const 1.0) (i32.const 1)) (drop))) "type mismatch" ) (assert_invalid - (module (func $type-num-vs-num (select (i32.const 1) (f64.const 1.0) (i32.const 1)))) + (module (func $type-num-vs-num (select (i32.const 1) (f64.const 1.0) (i32.const 1)) (drop))) "type mismatch" ) @@ -412,3 +421,67 @@ ) "type mismatch" ) + +;; Third operand must be i32 + +(assert_invalid + (module (func (select (i32.const 1) (i32.const 1) (i64.const 1)) (drop))) + "type mismatch" +) +(assert_invalid + (module (func (select (i32.const 1) (i32.const 1) (f32.const 1)) (drop))) + "type mismatch" +) +(assert_invalid + (module (func (select (i32.const 1) (i32.const 1) (f64.const 1)) (drop))) + "type mismatch" +) + +;; Result of select has type of first two operands + +(assert_invalid + (module (func (result i32) (select (i64.const 1) (i64.const 1) (i32.const 1)))) + "type mismatch" +) + +;; Validation after unreachable + +;; The first two operands should have the same type as each other +(assert_invalid + (module (func (unreachable) (select (i32.const 1) (i64.const 1) (i32.const 1)) (drop))) + "type mismatch" +) + +(assert_invalid + (module (func (unreachable) (select (i64.const 1) (i32.const 1) (i32.const 1)) (drop))) + "type mismatch" +) + +;; Third operand must be i32 +(assert_invalid + (module (func (unreachable) (select (i32.const 1) (i32.const 1) (i64.const 1)) (drop))) + "type mismatch" +) + +(assert_invalid + (module (func (unreachable) (select (i32.const 1) (i64.const 1)) (drop))) + "type mismatch" +) + +(assert_invalid + (module (func (unreachable) (select (i64.const 1)) (drop))) + "type mismatch" +) + +;; Result of select has type of first two operands (type of second operand when first one is omitted) +(assert_invalid + (module (func (result i32) (unreachable) (select (i64.const 1) (i32.const 1)))) + "type mismatch" +) + +;; select always has non-empty result +(assert_invalid + (module (func (unreachable) (select))) + "type mismatch" +) +