From 49e87dc14e5e018bc30cb07d4ba54d6501f4de68 Mon Sep 17 00:00:00 2001 From: Keith Winstein Date: Thu, 27 Apr 2023 01:45:50 -0700 Subject: [PATCH 01/25] [test] Add test for init expr with missing end marker (#1645) --- test/core/binary.wast | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/test/core/binary.wast b/test/core/binary.wast index 526e0a20e..4e748e700 100644 --- a/test/core/binary.wast +++ b/test/core/binary.wast @@ -470,6 +470,19 @@ "section size mismatch" ) +;; Init expression with missing end marker +(assert_malformed + (module binary + "\00asm" "\01\00\00\00" + "\01\04\01\60\00\00" ;; Type section: 1 type + "\03\02\01\00" ;; Function section: 1 function + "\06\05\01\7f\00\41\00" ;; Global section: 1 entry with missing end marker + ;; Missing end marker here + "\0a\04\01\02\00\0b" ;; Code section: 1 function + ) + "illegal opcode" +) + ;; Unsigned LEB128 must not be overlong (assert_malformed (module binary From dec27387d723ab7da2667f0dc36dd117eba844d9 Mon Sep 17 00:00:00 2001 From: gahaas Date: Tue, 2 May 2023 07:24:28 +0200 Subject: [PATCH 02/25] Add test for the module size limit (#1642) * Add test for the module size limit The limits test did not test the maximum supported module size of 1GB yet. This PR adds tests which create modules consisting of a single custom section. The first test checks if a module of size 1GB is allowed, the second test checks that a module of size 1GB + 1 byte gets rejected. * Some cleanup --- test/js-api/limits.any.js | 50 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) diff --git a/test/js-api/limits.any.js b/test/js-api/limits.any.js index 7e690cad9..91f058d68 100644 --- a/test/js-api/limits.any.js +++ b/test/js-api/limits.any.js @@ -244,3 +244,53 @@ test(() => { () => memory.grow(kJSEmbeddingMaxTableSize)); }, `Grow WebAssembly.Table object beyond the embedder-defined limit`); +function testModuleSizeLimit(size, expectPass) { + // We do not use `testLimit` here to avoid OOMs due to having multiple big + // modules alive at the same time. + + // Define a WebAssembly module that consists of a single custom section which + // has an empty name. The module size will be `size`. + const buffer = new Uint8Array(size); + const header = [ + kWasmH0, kWasmH1, kWasmH2, kWasmH3, // magic word + kWasmV0, kWasmV1, kWasmV2, kWasmV3, // version + 0 // custom section + ]; + // We calculate the section length so that the total module size is `size`. + // For that we have to calculate the length of the leb encoding of the section + // length. + const sectionLength = size - header.length - + wasmSignedLeb(size).length; + const lengthBytes = wasmSignedLeb(sectionLength); + buffer.set(header); + buffer.set(lengthBytes, header.length); + + if (expectPass) { + test(() => { + assert_true(WebAssembly.validate(buffer)); + }, `Validate module size limit`); + test(() => { + new WebAssembly.Module(buffer); + }, `Compile module size limit`); + promise_test(t => { + return WebAssembly.compile(buffer); + }, `Async compile module size limit`); + } else { + test(() => { + assert_false(WebAssembly.validate(buffer)); + }, `Validate module size over limit`); + test(() => { + assert_throws( + new WebAssembly.CompileError(), + () => new WebAssembly.Module(buffer)); + }, `Compile module size over limit`); + promise_test(t => { + return promise_rejects( + t, new WebAssembly.CompileError(), + WebAssembly.compile(buffer)); + }, `Async compile module size over limit`); + } +} + +testModuleSizeLimit(kJSEmbeddingMaxModuleSize, true); +testModuleSizeLimit(kJSEmbeddingMaxModuleSize + 1, false); From b72a1aae7f1a44e16178541b3107e49fba91cfe6 Mon Sep 17 00:00:00 2001 From: Clemens Backes Date: Wed, 10 May 2023 16:20:24 +0200 Subject: [PATCH 03/25] [test] Disable tests that become valid with memory64 (#1648) --- test/core/binary.wast | 237 ++++++++++++++++++++++-------------------- 1 file changed, 122 insertions(+), 115 deletions(-) diff --git a/test/core/binary.wast b/test/core/binary.wast index 4e748e700..1aae74aa3 100644 --- a/test/core/binary.wast +++ b/test/core/binary.wast @@ -492,25 +492,27 @@ ) "integer representation too long" ) -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\01\04\01\60\00\00" ;; Type section - "\03\02\01\00" ;; Function section - "\05\03\01\00\01" ;; Memory section - "\0a\11\01" ;; Code section - ;; function 0 - "\0f\01\01" ;; local type count - "\7f" ;; i32 - "\41\00" ;; i32.const 0 - "\28" ;; i32.load - "\02" ;; alignment 2 - "\82\80\80\80\80\00" ;; offset 2 with one byte too many - "\1a" ;; drop - "\0b" ;; end - ) - "integer representation too long" -) +;; The memory offset will be decoded as u64 in the memory64 proposal. +;; TODO: Re-enable this test as assert_trap test in the memory64 repo. +;; (assert_malformed +;; (module binary +;; "\00asm" "\01\00\00\00" +;; "\01\04\01\60\00\00" ;; Type section +;; "\03\02\01\00" ;; Function section +;; "\05\03\01\00\01" ;; Memory section +;; "\0a\11\01" ;; Code section +;; ;; function 0 +;; "\0f\01\01" ;; local type count +;; "\7f" ;; i32 +;; "\41\00" ;; i32.const 0 +;; "\28" ;; i32.load +;; "\02" ;; alignment 2 +;; "\82\80\80\80\80\00" ;; offset 2 with one byte too many +;; "\1a" ;; drop +;; "\0b" ;; end +;; ) +;; "integer representation too long" +;; ) (assert_malformed (module binary "\00asm" "\01\00\00\00" @@ -549,25 +551,27 @@ ) "integer representation too long" ) -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\01\04\01\60\00\00" ;; Type section - "\03\02\01\00" ;; Function section - "\05\03\01\00\01" ;; Memory section - "\0a\12\01" ;; Code section - ;; function 0 - "\10\01\01" ;; local type count - "\7f" ;; i32 - "\41\00" ;; i32.const 0 - "\41\03" ;; i32.const 3 - "\36" ;; i32.store - "\02" ;; alignment 2 - "\82\80\80\80\80\00" ;; offset 2 with one byte too many - "\0b" ;; end - ) - "integer representation too long" -) +;; The memory offset will be decoded as u64 in the memory64 proposal. +;; TODO: Re-enable this test as assert_trap test in the memory64 repo. +;; (assert_malformed +;; (module binary +;; "\00asm" "\01\00\00\00" +;; "\01\04\01\60\00\00" ;; Type section +;; "\03\02\01\00" ;; Function section +;; "\05\03\01\00\01" ;; Memory section +;; "\0a\12\01" ;; Code section +;; ;; function 0 +;; "\10\01\01" ;; local type count +;; "\7f" ;; i32 +;; "\41\00" ;; i32.const 0 +;; "\41\03" ;; i32.const 3 +;; "\36" ;; i32.store +;; "\02" ;; alignment 2 +;; "\82\80\80\80\80\00" ;; offset 2 with one byte too many +;; "\0b" ;; end +;; ) +;; "integer representation too long" +;; ) ;; Signed LEB128 must not be overlong (assert_malformed @@ -629,44 +633,46 @@ ) "integer too large" ) -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\01\04\01\60\00\00" ;; Type section - "\03\02\01\00" ;; Function section - "\05\03\01\00\01" ;; Memory section - "\0a\10\01" ;; Code section - ;; function 0 - "\0e\01\01" ;; local type count - "\7f" ;; i32 - "\41\00" ;; i32.const 0 - "\28" ;; i32.load - "\02" ;; alignment 2 - "\82\80\80\80\10" ;; offset 2 with unused bits set - "\1a" ;; drop - "\0b" ;; end - ) - "integer too large" -) -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\01\04\01\60\00\00" ;; Type section - "\03\02\01\00" ;; Function section - "\05\03\01\00\01" ;; Memory section - "\0a\10\01" ;; Code section - ;; function 0 - "\0e\01\01" ;; local type count - "\7f" ;; i32 - "\41\00" ;; i32.const 0 - "\28" ;; i32.load - "\02" ;; alignment 2 - "\82\80\80\80\40" ;; offset 2 with some unused bits set - "\1a" ;; drop - "\0b" ;; end - ) - "integer too large" -) +;; The memory offset will be decoded as u64 in the memory64 proposal. +;; TODO: Re-enable this test as assert_trap test in the memory64 repo. +;; (assert_malformed +;; (module binary +;; "\00asm" "\01\00\00\00" +;; "\01\04\01\60\00\00" ;; Type section +;; "\03\02\01\00" ;; Function section +;; "\05\03\01\00\01" ;; Memory section +;; "\0a\10\01" ;; Code section +;; ;; function 0 +;; "\0e\01\01" ;; local type count +;; "\7f" ;; i32 +;; "\41\00" ;; i32.const 0 +;; "\28" ;; i32.load +;; "\02" ;; alignment 2 +;; "\82\80\80\80\10" ;; offset 2 with unused bits set +;; "\1a" ;; drop +;; "\0b" ;; end +;; ) +;; "integer too large" +;; ) +;; (assert_malformed +;; (module binary +;; "\00asm" "\01\00\00\00" +;; "\01\04\01\60\00\00" ;; Type section +;; "\03\02\01\00" ;; Function section +;; "\05\03\01\00\01" ;; Memory section +;; "\0a\10\01" ;; Code section +;; ;; function 0 +;; "\0e\01\01" ;; local type count +;; "\7f" ;; i32 +;; "\41\00" ;; i32.const 0 +;; "\28" ;; i32.load +;; "\02" ;; alignment 2 +;; "\82\80\80\80\40" ;; offset 2 with some unused bits set +;; "\1a" ;; drop +;; "\0b" ;; end +;; ) +;; "integer too large" +;; ) (assert_malformed (module binary "\00asm" "\01\00\00\00" @@ -742,45 +748,46 @@ ) "integer too large" ) -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\01\04\01\60\00\00" ;; Type section - "\03\02\01\00" ;; Function section - "\05\03\01\00\01" ;; Memory section - "\0a\11\01" ;; Code section - ;; function 0 - "\0f\01\01" ;; local type count - "\7f" ;; i32 - "\41\00" ;; i32.const 0 - "\41\03" ;; i32.const 3 - "\36" ;; i32.store - "\02" ;; alignment 2 - "\82\80\80\80\10" ;; offset 2 with unused bits set - "\0b" ;; end - ) - "integer too large" -) -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\01\04\01\60\00\00" ;; Type section - "\03\02\01\00" ;; Function section - "\05\03\01\00\01" ;; Memory section - "\0a\11\01" ;; Code section - - ;; function 0 - "\0f\01\01" ;; local type count - "\7f" ;; i32 - "\41\00" ;; i32.const 0 - "\41\03" ;; i32.const 3 - "\36" ;; i32.store - "\02" ;; alignment 2 - "\82\80\80\80\40" ;; offset 2 with some unused bits set - "\0b" ;; end - ) - "integer too large" -) +;; The memory offset will be decoded as u64 in the memory64 proposal. +;; TODO: Re-enable this test as assert_trap test in the memory64 repo. +;; (assert_malformed +;; (module binary +;; "\00asm" "\01\00\00\00" +;; "\01\04\01\60\00\00" ;; Type section +;; "\03\02\01\00" ;; Function section +;; "\05\03\01\00\01" ;; Memory section +;; "\0a\11\01" ;; Code section +;; ;; function 0 +;; "\0f\01\01" ;; local type count +;; "\7f" ;; i32 +;; "\41\00" ;; i32.const 0 +;; "\41\03" ;; i32.const 3 +;; "\36" ;; i32.store +;; "\02" ;; alignment 2 +;; "\82\80\80\80\10" ;; offset 2 with unused bits set +;; "\0b" ;; end +;; ) +;; "integer too large" +;; ) +;; (assert_malformed +;; (module binary +;; "\00asm" "\01\00\00\00" +;; "\01\04\01\60\00\00" ;; Type section +;; "\03\02\01\00" ;; Function section +;; "\05\03\01\00\01" ;; Memory section +;; "\0a\11\01" ;; Code section +;; ;; function 0 +;; "\0f\01\01" ;; local type count +;; "\7f" ;; i32 +;; "\41\00" ;; i32.const 0 +;; "\41\03" ;; i32.const 3 +;; "\36" ;; i32.store +;; "\02" ;; alignment 2 +;; "\82\80\80\80\40" ;; offset 2 with some unused bits set +;; "\0b" ;; end +;; ) +;; "integer too large" +;; ) ;; Signed LEB128s sign-extend (assert_malformed From 0a190c98bf18fe42de359e953a103651702b9d4a Mon Sep 17 00:00:00 2001 From: Clemens Backes Date: Wed, 10 May 2023 18:14:24 +0200 Subject: [PATCH 04/25] Remove duplicated binary tests (#1649) * Remove duplicated binary tests Those tests were moved to `binary-leb128.wast` in #1019, but #1287 brought them back. * Remove more duplicated tests --- test/core/binary.wast | 673 ------------------------------------------ 1 file changed, 673 deletions(-) diff --git a/test/core/binary.wast b/test/core/binary.wast index 1aae74aa3..329b8a5a5 100644 --- a/test/core/binary.wast +++ b/test/core/binary.wast @@ -51,95 +51,6 @@ (assert_malformed (module binary "\00asm" "\01\00\00\00" "\81\01\00\01\01\00") "malformed section id") (assert_malformed (module binary "\00asm" "\01\00\00\00" "\ff\01\00\01\01\00") "malformed section id") -;; Unsigned LEB128 can have non-minimal length -(module binary - "\00asm" "\01\00\00\00" - "\05\04\01" ;; Memory section with 1 entry - "\00\82\00" ;; no max, minimum 2 -) -(module binary - "\00asm" "\01\00\00\00" - "\05\07\01" ;; Memory section with 1 entry - "\00\82\80\80\80\00" ;; no max, minimum 2 -) - -;; Signed LEB128 can have non-minimal length -(module binary - "\00asm" "\01\00\00\00" - "\06\07\01" ;; Global section with 1 entry - "\7f\00" ;; i32, immutable - "\41\80\00" ;; i32.const 0 - "\0b" ;; end -) -(module binary - "\00asm" "\01\00\00\00" - "\06\07\01" ;; Global section with 1 entry - "\7f\00" ;; i32, immutable - "\41\ff\7f" ;; i32.const -1 - "\0b" ;; end -) -(module binary - "\00asm" "\01\00\00\00" - "\06\0a\01" ;; Global section with 1 entry - "\7f\00" ;; i32, immutable - "\41\80\80\80\80\00" ;; i32.const 0 - "\0b" ;; end -) -(module binary - "\00asm" "\01\00\00\00" - "\06\0a\01" ;; Global section with 1 entry - "\7f\00" ;; i32, immutable - "\41\ff\ff\ff\ff\7f" ;; i32.const -1 - "\0b" ;; end -) - -(module binary - "\00asm" "\01\00\00\00" - "\06\07\01" ;; Global section with 1 entry - "\7e\00" ;; i64, immutable - "\42\80\00" ;; i64.const 0 with unused bits set - "\0b" ;; end -) -(module binary - "\00asm" "\01\00\00\00" - "\06\07\01" ;; Global section with 1 entry - "\7e\00" ;; i64, immutable - "\42\ff\7f" ;; i64.const -1 with unused bits unset - "\0b" ;; end -) -(module binary - "\00asm" "\01\00\00\00" - "\06\0f\01" ;; Global section with 1 entry - "\7e\00" ;; i64, immutable - "\42\80\80\80\80\80\80\80\80\80\00" ;; i64.const 0 with unused bits set - "\0b" ;; end -) -(module binary - "\00asm" "\01\00\00\00" - "\06\0f\01" ;; Global section with 1 entry - "\7e\00" ;; i64, immutable - "\42\ff\ff\ff\ff\ff\ff\ff\ff\ff\7f" ;; i64.const -1 with unused bits unset - "\0b" ;; end -) - -(module binary - "\00asm" "\01\00\00\00" - "\05\03\01" ;; Memory section with 1 entry - "\00\00" ;; no max, minimum 0 - "\0b\06\01" ;; Data section with 1 entry - "\00" ;; Memory index 0 - "\41\00\0b\00" ;; (i32.const 0) with contents "" -) - -(module binary - "\00asm" "\01\00\00\00" - "\04\04\01" ;; Table section with 1 entry - "\70\00\00" ;; no max, minimum 0, funcref - "\09\06\01" ;; Element section with 1 entry - "\00" ;; Table index 0 - "\41\00\0b\00" ;; (i32.const 0) with no elements -) - ;; Data segment tags and memory index can have non-minimal length (module binary "\00asm" "\01\00\00\00" @@ -218,201 +129,6 @@ "integer representation too long" ) -;; Unsigned LEB128 must not be overlong -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\05\08\01" ;; Memory section with 1 entry - "\00\82\80\80\80\80\00" ;; no max, minimum 2 with one byte too many - ) - "integer representation too long" -) - -;; Signed LEB128 must not be overlong -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\06\0b\01" ;; Global section with 1 entry - "\7f\00" ;; i32, immutable - "\41\80\80\80\80\80\00" ;; i32.const 0 with one byte too many - "\0b" ;; end - ) - "integer representation too long" -) -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\06\0b\01" ;; Global section with 1 entry - "\7f\00" ;; i32, immutable - "\41\ff\ff\ff\ff\ff\7f" ;; i32.const -1 with one byte too many - "\0b" ;; end - ) - "integer representation too long" -) - -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\06\10\01" ;; Global section with 1 entry - "\7e\00" ;; i64, immutable - "\42\80\80\80\80\80\80\80\80\80\80\00" ;; i64.const 0 with one byte too many - "\0b" ;; end - ) - "integer representation too long" -) -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\06\10\01" ;; Global section with 1 entry - "\7e\00" ;; i64, immutable - "\42\ff\ff\ff\ff\ff\ff\ff\ff\ff\ff\7f" ;; i64.const -1 with one byte too many - "\0b" ;; end - ) - "integer representation too long" -) - -;; Unsigned LEB128s zero-extend -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\05\07\01" ;; Memory section with 1 entry - "\00\82\80\80\80\70" ;; no max, minimum 2 with unused bits set - ) - "integer too large" -) -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\05\07\01" ;; Memory section with 1 entry - "\00\82\80\80\80\40" ;; no max, minimum 2 with some unused bits set - ) - "integer too large" -) - -;; Signed LEB128s sign-extend -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\06\0a\01" ;; Global section with 1 entry - "\7f\00" ;; i32, immutable - "\41\80\80\80\80\70" ;; i32.const 0 with unused bits set - "\0b" ;; end - ) - "integer too large" -) -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\06\0a\01" ;; Global section with 1 entry - "\7f\00" ;; i32, immutable - "\41\ff\ff\ff\ff\0f" ;; i32.const -1 with unused bits unset - "\0b" ;; end - ) - "integer too large" -) -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\06\0a\01" ;; Global section with 1 entry - "\7f\00" ;; i32, immutable - "\41\80\80\80\80\1f" ;; i32.const 0 with some unused bits set - "\0b" ;; end - ) - "integer too large" -) -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\06\0a\01" ;; Global section with 1 entry - "\7f\00" ;; i32, immutable - "\41\ff\ff\ff\ff\4f" ;; i32.const -1 with some unused bits unset - "\0b" ;; end - ) - "integer too large" -) - -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\06\0f\01" ;; Global section with 1 entry - "\7e\00" ;; i64, immutable - "\42\80\80\80\80\80\80\80\80\80\7e" ;; i64.const 0 with unused bits set - "\0b" ;; end - ) - "integer too large" -) -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\06\0f\01" ;; Global section with 1 entry - "\7e\00" ;; i64, immutable - "\42\ff\ff\ff\ff\ff\ff\ff\ff\ff\01" ;; i64.const -1 with unused bits unset - "\0b" ;; end - ) - "integer too large" -) -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\06\0f\01" ;; Global section with 1 entry - "\7e\00" ;; i64, immutable - "\42\80\80\80\80\80\80\80\80\80\02" ;; i64.const 0 with some unused bits set - "\0b" ;; end - ) - "integer too large" -) -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\06\0f\01" ;; Global section with 1 entry - "\7e\00" ;; i64, immutable - "\42\ff\ff\ff\ff\ff\ff\ff\ff\ff\41" ;; i64.const -1 with some unused bits unset - "\0b" ;; end - ) - "integer too large" -) - -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\06\0f\01" ;; Global section with 1 entry - "\7e\00" ;; i64, immutable - "\42\80\80\80\80\80\80\80\80\80\7e" ;; i64.const 0 with unused bits set - "\0b" ;; end - ) - "integer too large" -) -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\06\0f\01" ;; Global section with 1 entry - "\7e\00" ;; i64, immutable - "\42\ff\ff\ff\ff\ff\ff\ff\ff\ff\01" ;; i64.const -1 with unused bits unset - "\0b" ;; end - ) - "integer too large" -) -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\06\0f\01" ;; Global section with 1 entry - "\7e\00" ;; i64, immutable - "\42\80\80\80\80\80\80\80\80\80\02" ;; i64.const 0 with some unused bits set - "\0b" ;; end - ) - "integer too large" -) -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\06\0f\01" ;; Global section with 1 entry - "\7e\00" ;; i64, immutable - "\42\ff\ff\ff\ff\ff\ff\ff\ff\ff\41" ;; i64.const -1 with some unused bits unset - "\0b" ;; end - ) - "integer too large" -) - ;; Function with missing end marker (between two functions) (assert_malformed (module binary @@ -483,395 +199,6 @@ "illegal opcode" ) -;; Unsigned LEB128 must not be overlong -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\05\08\01" ;; Memory section with 1 entry - "\00\82\80\80\80\80\00" ;; no max, minimum 2 with one byte too many - ) - "integer representation too long" -) -;; The memory offset will be decoded as u64 in the memory64 proposal. -;; TODO: Re-enable this test as assert_trap test in the memory64 repo. -;; (assert_malformed -;; (module binary -;; "\00asm" "\01\00\00\00" -;; "\01\04\01\60\00\00" ;; Type section -;; "\03\02\01\00" ;; Function section -;; "\05\03\01\00\01" ;; Memory section -;; "\0a\11\01" ;; Code section -;; ;; function 0 -;; "\0f\01\01" ;; local type count -;; "\7f" ;; i32 -;; "\41\00" ;; i32.const 0 -;; "\28" ;; i32.load -;; "\02" ;; alignment 2 -;; "\82\80\80\80\80\00" ;; offset 2 with one byte too many -;; "\1a" ;; drop -;; "\0b" ;; end -;; ) -;; "integer representation too long" -;; ) -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\01\04\01\60\00\00" ;; Type section - "\03\02\01\00" ;; Function section - "\05\03\01\00\01" ;; Memory section - "\0a\11\01" ;; Code section - ;; function 0 - "\0f\01\01" ;; local type count - "\7f" ;; i32 - "\41\00" ;; i32.const 0 - "\28" ;; i32.load - "\82\80\80\80\80\00" ;; alignment 2 with one byte too many - "\00" ;; offset 0 - "\1a" ;; drop - "\0b" ;; end - ) - "integer representation too long" -) -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\01\04\01\60\00\00" ;; Type section - "\03\02\01\00" ;; Function section - "\05\03\01\00\01" ;; Memory section - "\0a\12\01" ;; Code section - ;; function 0 - "\10\01\01" ;; local type count - "\7f" ;; i32 - "\41\00" ;; i32.const 0 - "\41\03" ;; i32.const 3 - "\36" ;; i32.store - "\82\80\80\80\80\00" ;; alignment 2 with one byte too many - "\03" ;; offset 3 - "\0b" ;; end - ) - "integer representation too long" -) -;; The memory offset will be decoded as u64 in the memory64 proposal. -;; TODO: Re-enable this test as assert_trap test in the memory64 repo. -;; (assert_malformed -;; (module binary -;; "\00asm" "\01\00\00\00" -;; "\01\04\01\60\00\00" ;; Type section -;; "\03\02\01\00" ;; Function section -;; "\05\03\01\00\01" ;; Memory section -;; "\0a\12\01" ;; Code section -;; ;; function 0 -;; "\10\01\01" ;; local type count -;; "\7f" ;; i32 -;; "\41\00" ;; i32.const 0 -;; "\41\03" ;; i32.const 3 -;; "\36" ;; i32.store -;; "\02" ;; alignment 2 -;; "\82\80\80\80\80\00" ;; offset 2 with one byte too many -;; "\0b" ;; end -;; ) -;; "integer representation too long" -;; ) - -;; Signed LEB128 must not be overlong -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\06\0b\01" ;; Global section with 1 entry - "\7f\00" ;; i32, immutable - "\41\80\80\80\80\80\00" ;; i32.const 0 with one byte too many - "\0b" ;; end - ) - "integer representation too long" -) -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\06\0b\01" ;; Global section with 1 entry - "\7f\00" ;; i32, immutable - "\41\ff\ff\ff\ff\ff\7f" ;; i32.const -1 with one byte too many - "\0b" ;; end - ) - "integer representation too long" -) - -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\06\10\01" ;; Global section with 1 entry - "\7e\00" ;; i64, immutable - "\42\80\80\80\80\80\80\80\80\80\80\00" ;; i64.const 0 with one byte too many - "\0b" ;; end - ) - "integer representation too long" -) -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\06\10\01" ;; Global section with 1 entry - "\7e\00" ;; i64, immutable - "\42\ff\ff\ff\ff\ff\ff\ff\ff\ff\ff\7f" ;; i64.const -1 with one byte too many - "\0b" ;; end - ) - "integer representation too long" -) - -;; Unsigned LEB128s zero-extend -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\05\07\01" ;; Memory section with 1 entry - "\00\82\80\80\80\70" ;; no max, minimum 2 with unused bits set - ) - "integer too large" -) -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\05\07\01" ;; Memory section with 1 entry - "\00\82\80\80\80\40" ;; no max, minimum 2 with some unused bits set - ) - "integer too large" -) -;; The memory offset will be decoded as u64 in the memory64 proposal. -;; TODO: Re-enable this test as assert_trap test in the memory64 repo. -;; (assert_malformed -;; (module binary -;; "\00asm" "\01\00\00\00" -;; "\01\04\01\60\00\00" ;; Type section -;; "\03\02\01\00" ;; Function section -;; "\05\03\01\00\01" ;; Memory section -;; "\0a\10\01" ;; Code section -;; ;; function 0 -;; "\0e\01\01" ;; local type count -;; "\7f" ;; i32 -;; "\41\00" ;; i32.const 0 -;; "\28" ;; i32.load -;; "\02" ;; alignment 2 -;; "\82\80\80\80\10" ;; offset 2 with unused bits set -;; "\1a" ;; drop -;; "\0b" ;; end -;; ) -;; "integer too large" -;; ) -;; (assert_malformed -;; (module binary -;; "\00asm" "\01\00\00\00" -;; "\01\04\01\60\00\00" ;; Type section -;; "\03\02\01\00" ;; Function section -;; "\05\03\01\00\01" ;; Memory section -;; "\0a\10\01" ;; Code section -;; ;; function 0 -;; "\0e\01\01" ;; local type count -;; "\7f" ;; i32 -;; "\41\00" ;; i32.const 0 -;; "\28" ;; i32.load -;; "\02" ;; alignment 2 -;; "\82\80\80\80\40" ;; offset 2 with some unused bits set -;; "\1a" ;; drop -;; "\0b" ;; end -;; ) -;; "integer too large" -;; ) -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\01\04\01\60\00\00" ;; Type section - "\03\02\01\00" ;; Function section - "\05\03\01\00\01" ;; Memory section - "\0a\10\01" ;; Code section - "\0e\01\01" ;; local type count - "\7f" ;; i32 - "\41\00" ;; i32.const 0 - "\28" ;; i32.load - "\82\80\80\80\10" ;; alignment 2 with unused bits set - "\00" ;; offset 0 - "\1a" ;; drop - "\0b" ;; end - ) - "integer too large" -) -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\01\04\01\60\00\00" ;; Type section - "\03\02\01\00" ;; Function section - "\05\03\01\00\01" ;; Memory section - "\0a\10\01" ;; Code section - ;; function 0 - "\0e\01\01" ;; local type count - "\7f" ;; i32 - "\41\00" ;; i32.const 0 - "\28" ;; i32.load - "\82\80\80\80\40" ;; alignment 2 with some unused bits set - "\00" ;; offset 0 - "\1a" ;; drop - "\0b" ;; end - ) - "integer too large" -) -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\01\04\01\60\00\00" ;; Type section - "\03\02\01\00" ;; Function section - "\05\03\01\00\01" ;; Memory section - "\0a\11\01" ;; Code section - ;; function 0 - "\0f\01\01" ;; local type count - "\7f" ;; i32 - "\41\00" ;; i32.const 0 - "\41\03" ;; i32.const 3 - "\36" ;; i32.store - "\82\80\80\80\10" ;; alignment 2 with unused bits set - "\03" ;; offset 3 - "\0b" ;; end - ) - "integer too large" -) -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\01\04\01\60\00\00" ;; Type section - "\03\02\01\00" ;; Function section - "\05\03\01\00\01" ;; Memory section - "\0a\11\01" ;; Code section - ;; function 0 - "\0f\01\01" ;; local type count - "\7f" ;; i32 - "\41\00" ;; i32.const 0 - "\41\03" ;; i32.const 3 - "\36" ;; i32.store - "\82\80\80\80\40" ;; alignment 2 with some unused bits set - "\03" ;; offset 3 - "\0b" ;; end - ) - "integer too large" -) -;; The memory offset will be decoded as u64 in the memory64 proposal. -;; TODO: Re-enable this test as assert_trap test in the memory64 repo. -;; (assert_malformed -;; (module binary -;; "\00asm" "\01\00\00\00" -;; "\01\04\01\60\00\00" ;; Type section -;; "\03\02\01\00" ;; Function section -;; "\05\03\01\00\01" ;; Memory section -;; "\0a\11\01" ;; Code section -;; ;; function 0 -;; "\0f\01\01" ;; local type count -;; "\7f" ;; i32 -;; "\41\00" ;; i32.const 0 -;; "\41\03" ;; i32.const 3 -;; "\36" ;; i32.store -;; "\02" ;; alignment 2 -;; "\82\80\80\80\10" ;; offset 2 with unused bits set -;; "\0b" ;; end -;; ) -;; "integer too large" -;; ) -;; (assert_malformed -;; (module binary -;; "\00asm" "\01\00\00\00" -;; "\01\04\01\60\00\00" ;; Type section -;; "\03\02\01\00" ;; Function section -;; "\05\03\01\00\01" ;; Memory section -;; "\0a\11\01" ;; Code section -;; ;; function 0 -;; "\0f\01\01" ;; local type count -;; "\7f" ;; i32 -;; "\41\00" ;; i32.const 0 -;; "\41\03" ;; i32.const 3 -;; "\36" ;; i32.store -;; "\02" ;; alignment 2 -;; "\82\80\80\80\40" ;; offset 2 with some unused bits set -;; "\0b" ;; end -;; ) -;; "integer too large" -;; ) - -;; Signed LEB128s sign-extend -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\06\0a\01" ;; Global section with 1 entry - "\7f\00" ;; i32, immutable - "\41\80\80\80\80\70" ;; i32.const 0 with unused bits set - "\0b" ;; end - ) - "integer too large" -) -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\06\0a\01" ;; Global section with 1 entry - "\7f\00" ;; i32, immutable - "\41\ff\ff\ff\ff\0f" ;; i32.const -1 with unused bits unset - "\0b" ;; end - ) - "integer too large" -) -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\06\0a\01" ;; Global section with 1 entry - "\7f\00" ;; i32, immutable - "\41\80\80\80\80\1f" ;; i32.const 0 with some unused bits set - "\0b" ;; end - ) - "integer too large" -) -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\06\0a\01" ;; Global section with 1 entry - "\7f\00" ;; i32, immutable - "\41\ff\ff\ff\ff\4f" ;; i32.const -1 with some unused bits unset - "\0b" ;; end - ) - "integer too large" -) - -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\06\0f\01" ;; Global section with 1 entry - "\7e\00" ;; i64, immutable - "\42\80\80\80\80\80\80\80\80\80\7e" ;; i64.const 0 with unused bits set - "\0b" ;; end - ) - "integer too large" -) -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\06\0f\01" ;; Global section with 1 entry - "\7e\00" ;; i64, immutable - "\42\ff\ff\ff\ff\ff\ff\ff\ff\ff\01" ;; i64.const -1 with unused bits unset - "\0b" ;; end - ) - "integer too large" -) -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\06\0f\01" ;; Global section with 1 entry - "\7e\00" ;; i64, immutable - "\42\80\80\80\80\80\80\80\80\80\02" ;; i64.const 0 with some unused bits set - "\0b" ;; end - ) - "integer too large" -) -(assert_malformed - (module binary - "\00asm" "\01\00\00\00" - "\06\0f\01" ;; Global section with 1 entry - "\7e\00" ;; i64, immutable - "\42\ff\ff\ff\ff\ff\ff\ff\ff\ff\41" ;; i64.const -1 with some unused bits unset - "\0b" ;; end - ) - "integer too large" -) - ;; memory.grow reserved byte equal to zero. (assert_malformed (module binary From 86b6a183594d770ab37e868e1d755495d44cf243 Mon Sep 17 00:00:00 2001 From: Clemens Backes Date: Wed, 10 May 2023 18:14:50 +0200 Subject: [PATCH 05/25] Make binary-leb128 test memory64-ready (#1650) This merges part of WebAssembly/memory64#14 to make the tests fail both before and after memory64. This allows engines to enable memory64 without failing spec tests. --- test/core/binary-leb128.wast | 165 ++++++++++++++++++----------------- 1 file changed, 84 insertions(+), 81 deletions(-) diff --git a/test/core/binary-leb128.wast b/test/core/binary-leb128.wast index 1b642261a..e4a67d6b2 100644 --- a/test/core/binary-leb128.wast +++ b/test/core/binary-leb128.wast @@ -404,19 +404,19 @@ (assert_malformed (module binary "\00asm" "\01\00\00\00" - "\01\04\01\60\00\00" ;; Type section - "\03\02\01\00" ;; Function section - "\05\03\01\00\01" ;; Memory section - "\0a\11\01" ;; Code section + "\01\04\01\60\00\00" ;; Type section + "\03\02\01\00" ;; Function section + "\05\03\01\00\01" ;; Memory section + "\0a\11\01" ;; Code section ;; function 0 - "\0f\01\01" ;; local type count - "\7f" ;; i32 - "\41\00" ;; i32.const 0 - "\28" ;; i32.load - "\02" ;; alignment 2 - "\82\80\80\80\80\00" ;; offset 2 with one byte too many - "\1a" ;; drop - "\0b" ;; end + "\0f\01\01" ;; local type count + "\7f" ;; i32 + "\41\00" ;; i32.const 0 + "\28" ;; i32.load + "\02" ;; alignment 2 + "\82\80\80\80\80\80\80\80\80\80\00" ;; offset 2 with one byte too many + "\1a" ;; drop + "\0b" ;; end ) "integer representation too long" ) @@ -461,19 +461,19 @@ (assert_malformed (module binary "\00asm" "\01\00\00\00" - "\01\04\01\60\00\00" ;; Type section - "\03\02\01\00" ;; Function section - "\05\03\01\00\01" ;; Memory section - "\0a\12\01" ;; Code section + "\01\04\01\60\00\00" ;; Type section + "\03\02\01\00" ;; Function section + "\05\03\01\00\01" ;; Memory section + "\0a\12\01" ;; Code section ;; function 0 - "\10\01\01" ;; local type count - "\7f" ;; i32 - "\41\00" ;; i32.const 0 - "\41\03" ;; i32.const 3 - "\36" ;; i32.store - "\02" ;; alignment 2 - "\82\80\80\80\80\00" ;; offset 2 with one byte too many - "\0b" ;; end + "\10\01\01" ;; local type count + "\7f" ;; i32 + "\41\00" ;; i32.const 0 + "\41\03" ;; i32.const 3 + "\36" ;; i32.store + "\02" ;; alignment 2 + "\82\80\80\80\80\80\80\80\80\80\00" ;; offset 2 with one byte too many + "\0b" ;; end ) "integer representation too long" ) @@ -730,40 +730,42 @@ (assert_malformed (module binary "\00asm" "\01\00\00\00" - "\01\04\01\60\00\00" ;; Type section - "\03\02\01\00" ;; Function section - "\05\03\01\00\01" ;; Memory section - "\0a\10\01" ;; Code section + "\01\04\01\60\00\00" ;; Type section + "\03\02\01\00" ;; Function section + "\05\03\01\00\01" ;; Memory section + "\0a\10\01" ;; Code section ;; function 0 - "\0e\01\01" ;; local type count - "\7f" ;; i32 - "\41\00" ;; i32.const 0 - "\28" ;; i32.load - "\02" ;; alignment 2 - "\82\80\80\80\10" ;; offset 2 with unused bits set - "\1a" ;; drop - "\0b" ;; end - ) - "integer too large" + "\0e\01\01" ;; local type count + "\7f" ;; i32 + "\41\00" ;; i32.const 0 + "\28" ;; i32.load + "\02" ;; alignment 2 + "\82\80\80\80\80\80\80\80\80\10" ;; offset 2 with unused bits set + "\1a" ;; drop + "\0b" ;; end + ) + ;; TODO: This changes to "integer too large" with memory64. + "integer representation too long" ) (assert_malformed (module binary "\00asm" "\01\00\00\00" - "\01\04\01\60\00\00" ;; Type section - "\03\02\01\00" ;; Function section - "\05\03\01\00\01" ;; Memory section - "\0a\10\01" ;; Code section + "\01\04\01\60\00\00" ;; Type section + "\03\02\01\00" ;; Function section + "\05\03\01\00\01" ;; Memory section + "\0a\10\01" ;; Code section ;; function 0 - "\0e\01\01" ;; local type count - "\7f" ;; i32 - "\41\00" ;; i32.const 0 - "\28" ;; i32.load - "\02" ;; alignment 2 - "\82\80\80\80\40" ;; offset 2 with some unused bits set - "\1a" ;; drop - "\0b" ;; end - ) - "integer too large" + "\0e\01\01" ;; local type count + "\7f" ;; i32 + "\41\00" ;; i32.const 0 + "\28" ;; i32.load + "\02" ;; alignment 2 + "\82\80\80\80\80\80\80\80\80\40" ;; offset 2 with some unused bits set + "\1a" ;; drop + "\0b" ;; end + ) + ;; TODO: This changes to "integer too large" with memory64. + "integer representation too long" ) (assert_malformed (module binary @@ -843,41 +845,42 @@ (assert_malformed (module binary "\00asm" "\01\00\00\00" - "\01\04\01\60\00\00" ;; Type section - "\03\02\01\00" ;; Function section - "\05\03\01\00\01" ;; Memory section - "\0a\11\01" ;; Code section + "\01\04\01\60\00\00" ;; Type section + "\03\02\01\00" ;; Function section + "\05\03\01\00\01" ;; Memory section + "\0a\11\01" ;; Code section ;; function 0 - "\0f\01\01" ;; local type count - "\7f" ;; i32 - "\41\00" ;; i32.const 0 - "\41\03" ;; i32.const 3 - "\36" ;; i32.store - "\02" ;; alignment 2 - "\82\80\80\80\10" ;; offset 2 with unused bits set - "\0b" ;; end - ) - "integer too large" + "\0f\01\01" ;; local type count + "\7f" ;; i32 + "\41\00" ;; i32.const 0 + "\41\03" ;; i32.const 3 + "\36" ;; i32.store + "\02" ;; alignment 2 + "\82\80\80\80\80\80\80\80\80\10" ;; offset 2 with unused bits set + "\0b" ;; end + ) + ;; TODO: This changes to "integer too large" with memory64. + "integer representation too long" ) (assert_malformed (module binary "\00asm" "\01\00\00\00" - "\01\04\01\60\00\00" ;; Type section - "\03\02\01\00" ;; Function section - "\05\03\01\00\01" ;; Memory section - "\0a\11\01" ;; Code section - + "\01\04\01\60\00\00" ;; Type section + "\03\02\01\00" ;; Function section + "\05\03\01\00\01" ;; Memory section + "\0a\11\01" ;; Code section ;; function 0 - "\0f\01\01" ;; local type count - "\7f" ;; i32 - "\41\00" ;; i32.const 0 - "\41\03" ;; i32.const 3 - "\36" ;; i32.store - "\02" ;; alignment 2 - "\82\80\80\80\40" ;; offset 2 with some unused bits set - "\0b" ;; end - ) - "integer too large" + "\0f\01\01" ;; local type count + "\7f" ;; i32 + "\41\00" ;; i32.const 0 + "\41\03" ;; i32.const 3 + "\36" ;; i32.store + "\02" ;; alignment 2 + "\82\80\80\80\80\80\80\80\80\40" ;; offset 2 with some unused bits set + "\0b" ;; end + ) + ;; TODO: This changes to "integer too large" with memory64. + "integer representation too long" ) ;; Signed LEB128s sign-extend From fe355113fdc439f3cc06b720089168fc853247e5 Mon Sep 17 00:00:00 2001 From: Clemens Backes Date: Wed, 10 May 2023 19:40:24 +0200 Subject: [PATCH 06/25] Move more LEB128 tests to binary-leb128 (#1651) Tests for LEB128 should be in the separate `binary-leb128.wast` test file. --- test/core/binary-leb128.wast | 79 +++++++++++++++++++++++++++++++++++- test/core/binary.wast | 78 ----------------------------------- 2 files changed, 78 insertions(+), 79 deletions(-) diff --git a/test/core/binary-leb128.wast b/test/core/binary-leb128.wast index e4a67d6b2..335496f08 100644 --- a/test/core/binary-leb128.wast +++ b/test/core/binary-leb128.wast @@ -966,7 +966,6 @@ "integer too large" ) - (module binary "\00asm" "\01\00\00\00" "\01\04\01" ;; type section @@ -1003,3 +1002,81 @@ ) "integer representation too long" ) + +;; Data segment tags and memory index can have non-minimal length +(module binary + "\00asm" "\01\00\00\00" + "\05\03\01" ;; Memory section with 1 entry + "\00\00" ;; no max, minimum 0 + "\0b\07\01" ;; Data section with 1 entry + "\80\00" ;; Active segment, encoded with 2 bytes + "\41\00\0b\00" ;; (i32.const 0) with contents "" +) +(module binary + "\00asm" "\01\00\00\00" + "\05\03\01" ;; Memory section with 1 entry + "\00\00" ;; no max, minimum 0 + "\0b\08\01" ;; Data section with 1 entry + "\82\00" ;; Active segment, encoded with 2 bytes + "\00" ;; explicit memory index + "\41\00\0b\00" ;; (i32.const 0) with contents "" +) +(module binary + "\00asm" "\01\00\00\00" + "\05\03\01" ;; Memory section with 1 entry + "\00\00" ;; no max, minimum 0 + "\0b\09\01" ;; Data section with 1 entry + "\82\00" ;; Active segment, encoded with 2 bytes + "\80\00" ;; explicit memory index, encoded with 2 bytes + "\41\00\0b\00" ;; (i32.const 0) with contents "" +) + +;; Element segment tags and table index can have non-minimal length +(module binary + "\00asm" "\01\00\00\00" + "\04\04\01" ;; Table section with 1 entry + "\70\00\00" ;; no max, minimum 0, funcref + "\09\07\01" ;; Element section with 1 entry + "\80\00" ;; Active segment + "\41\00\0b\00" ;; (i32.const 0) with no elements +) +(module binary + "\00asm" "\01\00\00\00" + "\04\04\01" ;; Table section with 1 entry + "\70\00\00" ;; no max, minimum 0, funcref + "\09\09\01" ;; Element section with 1 entry + "\02" ;; Active segment + "\80\00" ;; explicit table index, encoded with 2 bytes + "\41\00\0b\00\00" ;; (i32.const 0) with no elements +) +(module binary + "\00asm" "\01\00\00\00" + "\04\04\01" ;; Table section with 1 entry + "\70\00\00" ;; no max, minimum 0, funcref + "\09\09\01" ;; Element section with 1 entry + "\82\00" ;; Active segment, encoded with 2 bytes + "\00" ;; explicit table index + "\41\00\0b\00\00" ;; (i32.const 0) with no elements +) +(module binary + "\00asm" "\01\00\00\00" + "\04\04\01" ;; Table section with 1 entry + "\70\00\00" ;; no max, minimum 0, funcref + "\09\0a\01" ;; Element section with 1 entry + "\82\00" ;; Active segment, encoded with 2 bytes + "\80\00" ;; explicit table index, encoded with 2 bytes + "\41\00\0b\00\00" ;; (i32.const 0) with no elements +) + +;; 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" +) diff --git a/test/core/binary.wast b/test/core/binary.wast index 329b8a5a5..c777bebb0 100644 --- a/test/core/binary.wast +++ b/test/core/binary.wast @@ -51,84 +51,6 @@ (assert_malformed (module binary "\00asm" "\01\00\00\00" "\81\01\00\01\01\00") "malformed section id") (assert_malformed (module binary "\00asm" "\01\00\00\00" "\ff\01\00\01\01\00") "malformed section id") -;; Data segment tags and memory index can have non-minimal length -(module binary - "\00asm" "\01\00\00\00" - "\05\03\01" ;; Memory section with 1 entry - "\00\00" ;; no max, minimum 0 - "\0b\07\01" ;; Data section with 1 entry - "\80\00" ;; Active segment, encoded with 2 bytes - "\41\00\0b\00" ;; (i32.const 0) with contents "" -) -(module binary - "\00asm" "\01\00\00\00" - "\05\03\01" ;; Memory section with 1 entry - "\00\00" ;; no max, minimum 0 - "\0b\08\01" ;; Data section with 1 entry - "\82\00" ;; Active segment, encoded with 2 bytes - "\00" ;; explicit memory index - "\41\00\0b\00" ;; (i32.const 0) with contents "" -) -(module binary - "\00asm" "\01\00\00\00" - "\05\03\01" ;; Memory section with 1 entry - "\00\00" ;; no max, minimum 0 - "\0b\09\01" ;; Data section with 1 entry - "\82\00" ;; Active segment, encoded with 2 bytes - "\80\00" ;; explicit memory index, encoded with 2 bytes - "\41\00\0b\00" ;; (i32.const 0) with contents "" -) - -;; Element segment tags and table index can have non-minimal length -(module binary - "\00asm" "\01\00\00\00" - "\04\04\01" ;; Table section with 1 entry - "\70\00\00" ;; no max, minimum 0, funcref - "\09\07\01" ;; Element section with 1 entry - "\80\00" ;; Active segment - "\41\00\0b\00" ;; (i32.const 0) with no elements -) -(module binary - "\00asm" "\01\00\00\00" - "\04\04\01" ;; Table section with 1 entry - "\70\00\00" ;; no max, minimum 0, funcref - "\09\09\01" ;; Element section with 1 entry - "\02" ;; Active segment - "\80\00" ;; explicit table index, encoded with 2 bytes - "\41\00\0b\00\00" ;; (i32.const 0) with no elements -) -(module binary - "\00asm" "\01\00\00\00" - "\04\04\01" ;; Table section with 1 entry - "\70\00\00" ;; no max, minimum 0, funcref - "\09\09\01" ;; Element section with 1 entry - "\82\00" ;; Active segment, encoded with 2 bytes - "\00" ;; explicit table index - "\41\00\0b\00\00" ;; (i32.const 0) with no elements -) -(module binary - "\00asm" "\01\00\00\00" - "\04\04\01" ;; Table section with 1 entry - "\70\00\00" ;; no max, minimum 0, funcref - "\09\0a\01" ;; Element section with 1 entry - "\82\00" ;; Active segment, encoded with 2 bytes - "\80\00" ;; explicit table index, encoded with 2 bytes - "\41\00\0b\00\00" ;; (i32.const 0) with no elements -) - -;; 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" -) - ;; Function with missing end marker (between two functions) (assert_malformed (module binary From 2e8912e88a3118a46b90e8ccb659e24b4e8f3c23 Mon Sep 17 00:00:00 2001 From: Clemens Backes Date: Fri, 12 May 2023 12:20:37 +0200 Subject: [PATCH 07/25] Allow test for module size limit to fail (#1653) * Allow test for module size limit to fail Allocating a 1GB Uint8Array can fail. In particular, it will always fail on 32-bit systems in V8, where the maximum size of a TypedArray is 2^30-1, thus 1 byte too little. --- test/js-api/limits.any.js | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/test/js-api/limits.any.js b/test/js-api/limits.any.js index 91f058d68..d913c6c7a 100644 --- a/test/js-api/limits.any.js +++ b/test/js-api/limits.any.js @@ -250,7 +250,16 @@ function testModuleSizeLimit(size, expectPass) { // Define a WebAssembly module that consists of a single custom section which // has an empty name. The module size will be `size`. - const buffer = new Uint8Array(size); + let buffer; + try { + buffer = new Uint8Array(size); + } catch (e) { + if (e instanceof RangeError) { + // Allocation of a big TypedArray may fail. + return; + } + throw e; + } const header = [ kWasmH0, kWasmH1, kWasmH2, kWasmH3, // magic word kWasmV0, kWasmV1, kWasmV2, kWasmV3, // version From 083f24cad6f181c7e393ab840e21c0f001cf4615 Mon Sep 17 00:00:00 2001 From: Phosra Date: Mon, 29 May 2023 23:30:51 -0700 Subject: [PATCH 08/25] [spec] Fix table_alloc signature (#1658) --- document/core/appendix/embedding.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/document/core/appendix/embedding.rst b/document/core/appendix/embedding.rst index 27aac4b31..96fa6b2fc 100644 --- a/document/core/appendix/embedding.rst +++ b/document/core/appendix/embedding.rst @@ -323,7 +323,7 @@ Tables .. _embed-table-alloc: -:math:`\F{table\_alloc}(\store, \tabletype) : (\store, \tableaddr, \reff)` +:math:`\F{table\_alloc}(\store, \tabletype, \reff) : (\store, \tableaddr)` .......................................................................... 1. Pre-condition: :math:`\tabletype` is :ref:`valid `. From 933d2dd95be2357bd936d4e400e853f8ec728ebd Mon Sep 17 00:00:00 2001 From: Andreas Rossberg Date: Tue, 30 May 2023 11:09:55 +0200 Subject: [PATCH 09/25] [interpreter] Tweak parser --- interpreter/text/parser.mly | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/interpreter/text/parser.mly b/interpreter/text/parser.mly index 7489acf72..e29be3ae3 100644 --- a/interpreter/text/parser.mly +++ b/interpreter/text/parser.mly @@ -732,11 +732,11 @@ elem_expr_list : elem_var_list : | var_list { let f = function {at; _} as x -> [ref_func x @@ at] @@ at in - fun c lookup -> List.map f ($1 c lookup) } + fun c -> List.map f ($1 c func) } elem_list : | elem_kind elem_var_list - { ($1, fun c -> $2 c func) } + { ($1, fun c -> $2 c) } | ref_type elem_expr_list { ($1, fun c -> $2 c) } @@ -768,7 +768,7 @@ elem : { let at = at () in fun c -> ignore ($3 c anon_elem bind_elem); fun () -> - { etype = FuncRefType; einit = $5 c func; + { etype = FuncRefType; einit = $5 c; emode = Active {index = 0l @@ at; offset = $4 c} @@ at } @@ at } table : @@ -788,19 +788,19 @@ table_fields : | inline_export table_fields /* Sugar */ { fun c x at -> let tabs, elems, ims, exs = $2 c x at in tabs, elems, ims, $1 (TableExport x) c :: exs } - | ref_type LPAR ELEM elem_var_list RPAR /* Sugar */ + | ref_type LPAR ELEM elem_expr elem_expr_list RPAR /* Sugar */ { fun c x at -> let offset = [i32_const (0l @@ at) @@ at] @@ at in - let einit = $4 c func in + let einit = $4 c :: $5 c in let size = Lib.List32.length einit in let emode = Active {index = x; offset} @@ at in [{ttype = TableType ({min = size; max = Some size}, $1)} @@ at], - [{etype = FuncRefType; einit; emode} @@ at], + [{etype = $1; einit; emode} @@ at], [], [] } - | ref_type LPAR ELEM elem_expr elem_expr_list RPAR /* Sugar */ + | ref_type LPAR ELEM elem_var_list RPAR /* Sugar */ { fun c x at -> let offset = [i32_const (0l @@ at) @@ at] @@ at in - let einit = (fun c -> $4 c :: $5 c) c in + let einit = $4 c in let size = Lib.List32.length einit in let emode = Active {index = x; offset} @@ at in [{ttype = TableType ({min = size; max = Some size}, $1)} @@ at], From b55d740054915ffc9089e709c99f3319ae6baabc Mon Sep 17 00:00:00 2001 From: Tom Stuart Date: Tue, 30 May 2023 10:57:59 +0100 Subject: [PATCH 10/25] [spec] Include reftype in inline element segment abbreviations (#1657) --- document/core/text/modules.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/document/core/text/modules.rst b/document/core/text/modules.rst index c34077326..5aab9b32c 100644 --- a/document/core/text/modules.rst +++ b/document/core/text/modules.rst @@ -292,7 +292,7 @@ An :ref:`element segment ` can be given inline with a table definitio \production{module field} & \text{(}~\text{table}~~\Tid^?~~\Treftype~~\text{(}~\text{elem}~~\expr^n{:}\Tvec(\Telemexpr)~\text{)}~\text{)} \quad\equiv \\ & \qquad \text{(}~\text{table}~~\Tid'~~n~~n~~\Treftype~\text{)} \\ & \qquad - \text{(}~\text{elem}~~\text{(}~\text{table}~~\Tid'~\text{)}~~\text{(}~\text{i32.const}~~\text{0}~\text{)}~~\Tvec(\Telemexpr)~\text{)} + \text{(}~\text{elem}~~\text{(}~\text{table}~~\Tid'~\text{)}~~\text{(}~\text{i32.const}~~\text{0}~\text{)}~~\Treftype~~\Tvec(\Telemexpr)~\text{)} \\ & \qquad\qquad (\iff \Tid^? \neq \epsilon \wedge \Tid' = \Tid^? \vee \Tid^? = \epsilon \wedge \Tid' \idfresh) \\ \end{array} @@ -302,7 +302,7 @@ An :ref:`element segment ` can be given inline with a table definitio \production{module field} & \text{(}~\text{table}~~\Tid^?~~\Treftype~~\text{(}~\text{elem}~~x^n{:}\Tvec(\Tfuncidx)~\text{)}~\text{)} \quad\equiv \\ & \qquad \text{(}~\text{table}~~\Tid'~~n~~n~~\Treftype~\text{)} \\ & \qquad - \text{(}~\text{elem}~~\text{(}~\text{table}~~\Tid'~\text{)}~~\text{(}~\text{i32.const}~~\text{0}~\text{)}~~\Tvec(\Tfuncidx)~\text{)} + \text{(}~\text{elem}~~\text{(}~\text{table}~~\Tid'~\text{)}~~\text{(}~\text{i32.const}~~\text{0}~\text{)}~~\text{func}~~\Tvec(\Tfuncidx)~\text{)} \\ & \qquad\qquad (\iff \Tid^? \neq \epsilon \wedge \Tid' = \Tid^? \vee \Tid^? = \epsilon \wedge \Tid' \idfresh) \\ \end{array} From e19508ade330025158cb2755fa4bbd1b53990a1b Mon Sep 17 00:00:00 2001 From: Reuben Dunnington Date: Mon, 5 Jun 2023 22:47:11 -0700 Subject: [PATCH 11/25] [spec] Fix copypaste error for V128.Load*_Zero instructions in index (#1662) --- document/core/appendix/index-instructions.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/document/core/appendix/index-instructions.py b/document/core/appendix/index-instructions.py index 2503a7ab0..c3ffc2a32 100755 --- a/document/core/appendix/index-instructions.py +++ b/document/core/appendix/index-instructions.py @@ -431,8 +431,8 @@ def Instruction(name, opcode, type=None, validation=None, execution=None, operat Instruction(r'\V128.\STORE\K{16\_lane}~\memarg~\laneidx', r'\hex{FD}~~\hex{59}', r'[\I32~\V128] \to []', r'valid-store-lane', r'exec-store-lane'), Instruction(r'\V128.\STORE\K{32\_lane}~\memarg~\laneidx', r'\hex{FD}~~\hex{5A}', r'[\I32~\V128] \to []', r'valid-store-lane', r'exec-store-lane'), Instruction(r'\V128.\STORE\K{64\_lane}~\memarg~\laneidx', r'\hex{FD}~~\hex{5B}', r'[\I32~\V128] \to []', r'valid-store-lane', r'exec-store-lane'), - Instruction(r'\V128.\LOAD\K{32\_zero}~\memarg~\laneidx', r'\hex{FD}~~\hex{5C}', r'[\I32] \to [\V128]', r'valid-load-zero', r'exec-load-zero'), - Instruction(r'\V128.\LOAD\K{64\_zero}~\memarg~\laneidx', r'\hex{FD}~~\hex{5D}', r'[\I32] \to [\V128]', r'valid-load-zero', r'exec-load-zero'), + Instruction(r'\V128.\LOAD\K{32\_zero}~\memarg', r'\hex{FD}~~\hex{5C}', r'[\I32] \to [\V128]', r'valid-load-zero', r'exec-load-zero'), + Instruction(r'\V128.\LOAD\K{64\_zero}~\memarg', r'\hex{FD}~~\hex{5D}', r'[\I32] \to [\V128]', r'valid-load-zero', r'exec-load-zero'), Instruction(r'\F32X4.\VDEMOTE\K{\_f64x2\_zero}', r'\hex{FD}~~\hex{5E}', r'[\V128] \to [\V128]', r'valid-vcvtop', r'exec-vcvtop', r'op-demote'), Instruction(r'\F64X2.\VPROMOTE\K{\_low\_f32x4}', r'\hex{FD}~~\hex{5F}', r'[\V128] \to [\V128]', r'valid-vcvtop', r'exec-vcvtop', r'op-promote'), Instruction(r'\I8X16.\VABS', r'\hex{FD}~~\hex{60}', r'[\V128] \to [\V128]', r'valid-vunop', r'exec-vunop', r'op-iabs'), From f2ab41511747ee8193b249e26e7908e645f3e373 Mon Sep 17 00:00:00 2001 From: zapashcanon Date: Tue, 13 Jun 2023 19:14:35 +0200 Subject: [PATCH 12/25] [interpreter] Use explicit bounds checks instead Invalid_argument (#1659) --- interpreter/exec/eval_num.ml | 1 - interpreter/exec/v128.ml | 2 +- interpreter/runtime/data.ml | 10 +++++++++- interpreter/runtime/elem.ml | 8 +++++++- interpreter/runtime/memory.ml | 6 ++++-- interpreter/runtime/table.ml | 11 +++++++---- interpreter/util/lib.ml | 6 +++--- 7 files changed, 31 insertions(+), 13 deletions(-) diff --git a/interpreter/exec/eval_num.ml b/interpreter/exec/eval_num.ml index f1245a133..40dd1be07 100644 --- a/interpreter/exec/eval_num.ml +++ b/interpreter/exec/eval_num.ml @@ -195,4 +195,3 @@ let eval_binop = op I32Op.binop I64Op.binop F32Op.binop F64Op.binop let eval_testop = op I32Op.testop I64Op.testop F32Op.testop F64Op.testop let eval_relop = op I32Op.relop I64Op.relop F32Op.relop F64Op.relop let eval_cvtop = op I32CvtOp.cvtop I64CvtOp.cvtop F32CvtOp.cvtop F64CvtOp.cvtop - diff --git a/interpreter/exec/v128.ml b/interpreter/exec/v128.ml index 550fd9bfa..873035ad3 100644 --- a/interpreter/exec/v128.ml +++ b/interpreter/exec/v128.ml @@ -477,7 +477,7 @@ let to_hex_string s = let of_strings shape ss = if List.length ss <> num_lanes shape then - raise (Invalid_argument "wrong length"); + invalid_arg "wrong length"; let open Bytes in let b = create bytewidth in (match shape with diff --git a/interpreter/runtime/data.ml b/interpreter/runtime/data.ml index e73cd2f31..f63a2aaa3 100644 --- a/interpreter/runtime/data.ml +++ b/interpreter/runtime/data.ml @@ -1,7 +1,15 @@ type data = string ref type t = data +exception Bounds + let alloc bs = ref bs + let size seg = I64.of_int_u (String.length !seg) -let load seg i = (!seg).[Int64.to_int i] + +let load seg i = + let i' = Int64.to_int i in + if i' < 0 || i' >= String.length !seg then raise Bounds; + !seg.[i'] + let drop seg = seg := "" diff --git a/interpreter/runtime/elem.ml b/interpreter/runtime/elem.ml index fe8997482..366ec6df0 100644 --- a/interpreter/runtime/elem.ml +++ b/interpreter/runtime/elem.ml @@ -1,7 +1,13 @@ type elem = Values.ref_ list ref type t = elem +exception Bounds + let alloc rs = ref rs let size seg = Lib.List32.length !seg -let load seg i = Lib.List32.nth !seg i + +let load seg i = + if i < 0l || i >= Lib.List32.length !seg then raise Bounds; + Lib.List32.nth !seg i + let drop seg = seg := [] diff --git a/interpreter/runtime/memory.ml b/interpreter/runtime/memory.ml index e2c1fbf70..682626d7a 100644 --- a/interpreter/runtime/memory.ml +++ b/interpreter/runtime/memory.ml @@ -62,10 +62,12 @@ let grow mem delta = mem.content <- after let load_byte mem a = - try Array1_64.get mem.content a with Invalid_argument _ -> raise Bounds + if a < 0L || a >= Array1_64.dim mem.content then raise Bounds; + Array1_64.get mem.content a let store_byte mem a b = - try Array1_64.set mem.content a b with Invalid_argument _ -> raise Bounds + if a < 0L || a >= Array1_64.dim mem.content then raise Bounds; + Array1_64.set mem.content a b let load_bytes mem a n = let buf = Buffer.create n in diff --git a/interpreter/runtime/table.ml b/interpreter/runtime/table.ml index bb10cab8b..e7fc317e8 100644 --- a/interpreter/runtime/table.ml +++ b/interpreter/runtime/table.ml @@ -47,14 +47,17 @@ let grow tab delta r = tab.content <- after let load tab i = - try Lib.Array32.get tab.content i with Invalid_argument _ -> raise Bounds + if i < 0l || i >= Lib.Array32.length tab.content then raise Bounds; + Lib.Array32.get tab.content i let store tab i r = let TableType (lim, t) = tab.ty in if type_of_ref r <> t then raise Type; - try Lib.Array32.set tab.content i r with Invalid_argument _ -> raise Bounds + if i < 0l || i >= Lib.Array32.length tab.content then raise Bounds; + Lib.Array32.set tab.content i r let blit tab offset rs = let data = Array.of_list rs in - try Lib.Array32.blit data 0l tab.content offset (Lib.Array32.length data) - with Invalid_argument _ -> raise Bounds + let len = Lib.Array32.length data in + if offset < 0l || offset > Int32.sub (Lib.Array32.length tab.content) len then raise Bounds; + Lib.Array32.blit data 0l tab.content offset len diff --git a/interpreter/util/lib.ml b/interpreter/util/lib.ml index 76757eb72..90c4e4fe0 100644 --- a/interpreter/util/lib.ml +++ b/interpreter/util/lib.ml @@ -156,7 +156,7 @@ module Array32 = struct let make n x = if n < 0l || Int64.of_int32 n > Int64.of_int max_int then - raise (Invalid_argument "Array32.make"); + invalid_arg "Array32.make"; Array.make (Int32.to_int n) x let length a = Int32.of_int (Array.length a) @@ -179,7 +179,7 @@ struct struct let create kind layout n = if n < 0L || n > Int64.of_int max_int then - raise (Invalid_argument "Bigarray.Array1_64.create"); + invalid_arg "Bigarray.Array1_64.create"; Array1.create kind layout (Int64.to_int n) let dim a = Int64.of_int (Array1.dim a) @@ -204,7 +204,7 @@ struct let force o = match o with | Some y -> y - | None -> raise (Invalid_argument "Option.force") + | None -> invalid_arg "Option.force" let map f = function | Some x -> Some (f x) From 905f42d3e4d03a44614bee85d50cab988d55869d Mon Sep 17 00:00:00 2001 From: Andreas Rossberg Date: Wed, 14 Jun 2023 19:14:41 +0200 Subject: [PATCH 13/25] [interpreter] Makefile tweak --- document/core/util/bikeshed_fixup.py | 2 +- interpreter/Makefile | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/document/core/util/bikeshed_fixup.py b/document/core/util/bikeshed_fixup.py index 05439207f..568c67b57 100755 --- a/document/core/util/bikeshed_fixup.py +++ b/document/core/util/bikeshed_fixup.py @@ -59,7 +59,7 @@ def Main(): ) data = data.replace( - """IEEE 754-2019""", + """IEEE 754""", "[[!IEEE-754-2019]]" ) diff --git a/interpreter/Makefile b/interpreter/Makefile index 3294e2682..014b98d55 100644 --- a/interpreter/Makefile +++ b/interpreter/Makefile @@ -41,7 +41,7 @@ all: unopt opt libunopt libopt test land: $(WINMAKE) all zip: $(ZIP) smallint: smallint.native -ci: land wast.js dunebuild +ci: land jslib dunebuild dunebuild: dune build From c674a0b2ee3f0fbaa5f3951d1a07327eaca2bd12 Mon Sep 17 00:00:00 2001 From: Andreas Rossberg Date: Tue, 27 Jun 2023 07:49:55 +0200 Subject: [PATCH 14/25] [spec] Tweak math layout --- document/core/exec/numerics.rst | 49 +++++++++++++++++---------------- document/core/util/macros.def | 4 +-- 2 files changed, 27 insertions(+), 26 deletions(-) diff --git a/document/core/exec/numerics.rst b/document/core/exec/numerics.rst index 71dfef6a9..fa03504eb 100644 --- a/document/core/exec/numerics.rst +++ b/document/core/exec/numerics.rst @@ -161,48 +161,49 @@ Floating-Point where :math:`M = \significand(N)` and :math:`E = \exponent(N)`. -.. index:: byte, little endian, memory -.. _aux-littleendian: -.. _aux-bytes: +.. index:: numeric vector, shape, lane +.. _aux-lanes: -Storage +Vectors ....... -When a number is stored into :ref:`memory `, it is converted into a sequence of :ref:`bytes ` in |LittleEndian|_ byte order: +Numeric vectors have the same underlying representation as an |i128|. +They can also be interpreted as a sequence of numeric values packed into a |V128| with a particular |shape|. .. math:: + \begin{array}{l} \begin{array}{lll@{\qquad}l} - \bytes_t(i) &=& \littleendian(\bits_t(i)) \\[1ex] - \littleendian(\epsilon) &=& \epsilon \\ - \littleendian(d^8~{d'}^\ast~) &=& \littleendian({d'}^\ast)~\ibits_8^{-1}(d^8) \\ + \lanes_{t\K{x}N}(c) &=& + c_0~\dots~c_{N-1} \\ + \end{array} + \\ \qquad + \begin{array}[t]{@{}r@{~}l@{}l@{~}l@{~}l} + (\where & B &=& |t| / 8 \\ + \wedge & b^{16} &=& \bytes_{\i128}(c) \\ + \wedge & c_i &=& \bytes_{t}^{-1}(b^{16}[i \cdot B \slice B])) + \end{array} \end{array} -Again these functions are invertible bijections. +These functions are bijections, so they are invertible. -.. index:: numeric vectors, shape -.. _aux-lanes: +.. index:: byte, little endian, memory +.. _aux-littleendian: +.. _aux-bytes: -Vectors +Storage ....... -Numeric vectors have the same underlying representation as an |i128|. They can also be interpreted as a sequence of numeric values packed into a |V128| with a particular |shape|. +When a number is stored into :ref:`memory `, it is converted into a sequence of :ref:`bytes ` in |LittleEndian|_ byte order: .. math:: - \begin{array}{l} \begin{array}{lll@{\qquad}l} - \lanes_{t\K{x}N}(c) &=& - c_0~\dots~c_{N-1} \\ - \end{array} - \\ \qquad - \begin{array}[t]{@{}r@{~}l@{}} - (\where & B = |t| / 8 \\ - \wedge & b^{16} = \bytes_{\i128}(c) \\ - \wedge & c_i = \bytes_{t}^{-1}(b^{16}[i \cdot B \slice B])) - \end{array} + \bytes_t(i) &=& \littleendian(\bits_t(i)) \\[1ex] + \littleendian(\epsilon) &=& \epsilon \\ + \littleendian(d^8~{d'}^\ast~) &=& \littleendian({d'}^\ast)~\ibits_8^{-1}(d^8) \\ \end{array} -These functions are bijections, so they are invertible. +Again these functions are invertible bijections. .. index:: integer diff --git a/document/core/util/macros.def b/document/core/util/macros.def index 3ab6d5480..12054c26a 100644 --- a/document/core/util/macros.def +++ b/document/core/util/macros.def @@ -1197,8 +1197,8 @@ .. |ieee| mathdef:: \xref{exec/numerics}{aux-ieee}{\F{float}} .. |nans| mathdef:: \xref{exec/numerics}{aux-nans}{\F{nans}} .. |trunc| mathdef:: \xref{exec/numerics}{aux-trunc}{\F{trunc}} -.. |satu| mathdef:: \xref{exec/numerics}{aux-sat_u}{\F{sat}^{\K{u}}} -.. |sats| mathdef:: \xref{exec/numerics}{aux-sat_s}{\F{sat}^{\K{s}}} +.. |satu| mathdef:: \xref{exec/numerics}{aux-sat_u}{\F{sat\_u}} +.. |sats| mathdef:: \xref{exec/numerics}{aux-sat_s}{\F{sat\_s}} .. |lanes| mathdef:: \xref{exec/numerics}{aux-lanes}{\F{lanes}} From 6315e12538c126683fc07174da84a8bca09a5276 Mon Sep 17 00:00:00 2001 From: Andreas Rossberg Date: Tue, 27 Jun 2023 08:24:28 +0200 Subject: [PATCH 15/25] [spec] Some tweaks to layout and SIMD ops (#1667) --- document/core/exec/instructions.rst | 57 ++++++++++++++------------- document/core/exec/numerics.rst | 10 +++-- document/core/syntax/instructions.rst | 2 +- document/core/syntax/values.rst | 2 +- document/core/util/macros.def | 4 +- 5 files changed, 40 insertions(+), 35 deletions(-) diff --git a/document/core/exec/instructions.rst b/document/core/exec/instructions.rst index 4f040d0e4..f86349b4e 100644 --- a/document/core/exec/instructions.rst +++ b/document/core/exec/instructions.rst @@ -20,8 +20,9 @@ The mapping of numeric instructions to their underlying operators is expressed b .. math:: \begin{array}{lll@{\qquad}l} - \X{op}_{\K{i}N}(n_1,\dots,n_k) &=& \F{i}\X{op}_N(n_1,\dots,n_k) \\ - \X{op}_{\K{f}N}(z_1,\dots,z_k) &=& \F{f}\X{op}_N(z_1,\dots,z_k) \\ + \X{op}_{\IN}(i_1,\dots,i_k) &=& \F{i}\X{op}_N(i_1,\dots,i_k) \\ + \X{op}_{\FN}(z_1,\dots,z_k) &=& \F{f}\X{op}_N(z_1,\dots,z_k) \\ + \X{op}_{\VN}(i_1,\dots,i_k) &=& \F{i}\X{op}_N(i_1,\dots,i_k) \\ \end{array} And for :ref:`conversion operators `: @@ -292,14 +293,14 @@ Most vector instructions are defined in terms of generic numeric operators appli 2. Pop the value :math:`\V128.\VCONST~c_1` from the stack. -3. Let :math:`c` be the result of computing :math:`\vvunop_{\I128}(c_1)`. +3. Let :math:`c` be the result of computing :math:`\vvunop_{\V128}(c_1)`. 4. Push the value :math:`\V128.\VCONST~c` to the stack. .. math:: \begin{array}{lcl@{\qquad}l} (\V128\K{.}\VCONST~c_1)~\V128\K{.}\vvunop &\stepto& (\V128\K{.}\VCONST~c) - & (\iff c = \vvunop_{\I128}(c_1)) \\ + & (\iff c = \vvunop_{\V128}(c_1)) \\ \end{array} @@ -314,14 +315,14 @@ Most vector instructions are defined in terms of generic numeric operators appli 3. Pop the value :math:`\V128.\VCONST~c_1` from the stack. -4. Let :math:`c` be the result of computing :math:`\vvbinop_{\I128}(c_1, c_2)`. +4. Let :math:`c` be the result of computing :math:`\vvbinop_{\V128}(c_1, c_2)`. 5. Push the value :math:`\V128.\VCONST~c` to the stack. .. math:: \begin{array}{lcl@{\qquad}l} (\V128\K{.}\VCONST~c_1)~(\V128\K{.}\VCONST~c_2)~\V128\K{.}\vvbinop &\stepto& (\V128\K{.}\VCONST~c) - & (\iff c = \vvbinop_{\I128}(c_1, c_2)) \\ + & (\iff c = \vvbinop_{\V128}(c_1, c_2)) \\ \end{array} @@ -338,14 +339,14 @@ Most vector instructions are defined in terms of generic numeric operators appli 4. Pop the value :math:`\V128.\VCONST~c_1` from the stack. -5. Let :math:`c` be the result of computing :math:`\vvternop_{\I128}(c_1, c_2, c_3)`. +5. Let :math:`c` be the result of computing :math:`\vvternop_{\V128}(c_1, c_2, c_3)`. 6. Push the value :math:`\V128.\VCONST~c` to the stack. .. math:: \begin{array}{lcl@{\qquad}l} (\V128\K{.}\VCONST~c_1)~(\V128\K{.}\VCONST~c_2)~(\V128\K{.}\VCONST~c_3)~\V128\K{.}\vvternop &\stepto& (\V128\K{.}\VCONST~c) - & (\iff c = \vvternop_{\I128}(c_1, c_2, c_3)) \\ + & (\iff c = \vvternop_{\V128}(c_1, c_2, c_3)) \\ \end{array} @@ -379,15 +380,15 @@ Most vector instructions are defined in terms of generic numeric operators appli 2. Pop the value :math:`\V128.\VCONST~c_2` from the stack. -3. Let :math:`i^\ast` be the result of computing :math:`\lanes_{i8x16}(c_2)`. +3. Let :math:`i^\ast` be the result of computing :math:`\lanes_{\I8X16}(c_2)`. 4. Pop the value :math:`\V128.\VCONST~c_1` from the stack. -5. Let :math:`j^\ast` be the result of computing :math:`\lanes_{i8x16}(c_1)`. +5. Let :math:`j^\ast` be the result of computing :math:`\lanes_{\I8X16}(c_1)`. 6. Let :math:`c^\ast` be the concatenation of the two sequences :math:`j^\ast` and :math:`0^{240}`. -7. Let :math:`c'` be the result of computing :math:`\lanes^{-1}_{i8x16}(c^\ast[ i^\ast[0] ] \dots c^\ast[ i^\ast[15] ])`. +7. Let :math:`c'` be the result of computing :math:`\lanes^{-1}_{\I8X16}(c^\ast[ i^\ast[0] ] \dots c^\ast[ i^\ast[15] ])`. 8. Push the value :math:`\V128.\VCONST~c'` onto the stack. @@ -398,9 +399,9 @@ Most vector instructions are defined in terms of generic numeric operators appli \end{array} \\ \qquad \begin{array}[t]{@{}r@{~}l@{}} - (\iff & i^\ast = \lanes_{i8x16}(c_2) \\ - \wedge & c^\ast = \lanes_{i8x16}(c_1)~0^{240} \\ - \wedge & c' = \lanes^{-1}_{i8x16}(c^\ast[ i^\ast[0] ] \dots c^\ast[ i^\ast[15] ])) + (\iff & i^\ast = \lanes_{\I8X16}(c_2) \\ + \wedge & c^\ast = \lanes_{\I8X16}(c_1)~0^{240} \\ + \wedge & c' = \lanes^{-1}_{\I8X16}(c^\ast[ i^\ast[0] ] \dots c^\ast[ i^\ast[15] ])) \end{array} \end{array} @@ -416,15 +417,15 @@ Most vector instructions are defined in terms of generic numeric operators appli 3. Pop the value :math:`\V128.\VCONST~c_2` from the stack. -4. Let :math:`i_2^\ast` be the result of computing :math:`\lanes_{i8x16}(c_2)`. +4. Let :math:`i_2^\ast` be the result of computing :math:`\lanes_{\I8X16}(c_2)`. 5. Pop the value :math:`\V128.\VCONST~c_1` from the stack. -6. Let :math:`i_1^\ast` be the result of computing :math:`\lanes_{i8x16}(c_1)`. +6. Let :math:`i_1^\ast` be the result of computing :math:`\lanes_{\I8X16}(c_1)`. 7. Let :math:`i^\ast` be the concatenation of the two sequences :math:`i_1^\ast` and :math:`i_2^\ast`. -8. Let :math:`c` be the result of computing :math:`\lanes^{-1}_{i8x16}(i^\ast[x^\ast[0]] \dots i^\ast[x^\ast[15]])`. +8. Let :math:`c` be the result of computing :math:`\lanes^{-1}_{\I8X16}(i^\ast[x^\ast[0]] \dots i^\ast[x^\ast[15]])`. 9. Push the value :math:`\V128.\VCONST~c` onto the stack. @@ -435,8 +436,8 @@ Most vector instructions are defined in terms of generic numeric operators appli \end{array} \\ \qquad \begin{array}[t]{@{}r@{~}l@{}} - (\iff & i^\ast = \lanes_{i8x16}(c_1)~\lanes_{i8x16}(c_2) \\ - \wedge & c = \lanes^{-1}_{i8x16}(i^\ast[x^\ast[0]] \dots i^\ast[x^\ast[15]])) + (\iff & i^\ast = \lanes_{\I8X16}(c_1)~\lanes_{\I8X16}(c_2) \\ + \wedge & c = \lanes^{-1}_{\I8X16}(i^\ast[x^\ast[0]] \dots i^\ast[x^\ast[15]])) \end{array} \end{array} @@ -1820,7 +1821,7 @@ Memory Instructions 13. Let :math:`n_k` be the result of computing :math:`\extend^{\sx}_{M,W}(m_k)`. -14. Let :math:`c` be the result of computing :math:`\lanes^{-1}_{\X{i}W\K{x}N}(n_0 \dots n_{N-1})`. +14. Let :math:`c` be the result of computing :math:`\lanes^{-1}_{\K{i}W\K{x}N}(n_0 \dots n_{N-1})`. 15. Push the value :math:`\V128.\CONST~c` to the stack. @@ -1837,7 +1838,7 @@ Memory Instructions \wedge & \X{ea} + M \cdot N / 8 \leq |S.\SMEMS[F.\AMODULE.\MIMEMS[0]].\MIDATA| \\ \wedge & \bytes_{\iM}(m_k) = S.\SMEMS[F.\AMODULE.\MIMEMS[0]].\MIDATA[\X{ea} + k \cdot M/8 \slice M/8] \\ \wedge & W = M \cdot 2 \\ - \wedge & c = \lanes^{-1}_{\X{i}W\K{x}N}(\extend^{\sx}_{M,W}(m_0) \dots \extend^{\sx}_{M,W}(m_{N-1}))) + \wedge & c = \lanes^{-1}_{\K{i}W\K{x}N}(\extend^{\sx}_{M,W}(m_0) \dots \extend^{\sx}_{M,W}(m_{N-1}))) \end{array} \\[1ex] \begin{array}{lcl@{\qquad}l} @@ -1879,7 +1880,7 @@ Memory Instructions 12. Let :math:`L` be the integer :math:`128 / N`. -13. Let :math:`c` be the result of computing :math:`\lanes^{-1}_{\iN\K{x}L}(n^L)`. +13. Let :math:`c` be the result of computing :math:`\lanes^{-1}_{\IN\K{x}L}(n^L)`. 14. Push the value :math:`\V128.\CONST~c` to the stack. @@ -1894,7 +1895,7 @@ Memory Instructions (\iff & \X{ea} = i + \memarg.\OFFSET \\ \wedge & \X{ea} + N/8 \leq |S.\SMEMS[F.\AMODULE.\MIMEMS[0]].\MIDATA| \\ \wedge & \bytes_{\iN}(n) = S.\SMEMS[F.\AMODULE.\MIMEMS[0]].\MIDATA[\X{ea} \slice N/8] \\ - \wedge & c = \lanes^{-1}_{\iN\K{x}L}(n^L)) + \wedge & c = \lanes^{-1}_{\IN\K{x}L}(n^L)) \end{array} \\[1ex] \begin{array}{lcl@{\qquad}l} @@ -1995,9 +1996,9 @@ Memory Instructions 14. Let :math:`L` be :math:`128 / N`. -15. Let :math:`j^\ast` be the result of computing :math:`\lanes_{\K{i}N\K{x}L}(v)`. +15. Let :math:`j^\ast` be the result of computing :math:`\lanes_{\IN\K{x}L}(v)`. -16. Let :math:`c` be the result of computing :math:`\lanes^{-1}_{\K{i}N\K{x}L}(j^\ast \with [x] = r)`. +16. Let :math:`c` be the result of computing :math:`\lanes^{-1}_{\IN\K{x}L}(j^\ast \with [x] = r)`. 17. Push the value :math:`\V128.\CONST~c` to the stack. @@ -2013,7 +2014,7 @@ Memory Instructions \wedge & \X{ea} + N/8 \leq |S.\SMEMS[F.\AMODULE.\MIMEMS[0]].\MIDATA| \\ \wedge & \bytes_{\iN}(r) = S.\SMEMS[F.\AMODULE.\MIMEMS[0]].\MIDATA[\X{ea} \slice N/8] \\ \wedge & L = 128/N \\ - \wedge & c = \lanes^{-1}_{\K{i}N\K{x}L}(\lanes_{\K{i}N\K{x}L}(v) \with [x] = r)) + \wedge & c = \lanes^{-1}_{\IN\K{x}L}(\lanes_{\IN\K{x}L}(v) \with [x] = r)) \end{array} \\[1ex] \begin{array}{lcl@{\qquad}l} @@ -2132,7 +2133,7 @@ Memory Instructions 12. Let :math:`L` be :math:`128/N`. -13. Let :math:`j^\ast` be the result of computing :math:`\lanes_{\K{i}N\K{x}L}(c)`. +13. Let :math:`j^\ast` be the result of computing :math:`\lanes_{\IN\K{x}L}(c)`. 14. Let :math:`b^\ast` be the result of computing :math:`\bytes_{\iN}(j^\ast[x])`. @@ -2149,7 +2150,7 @@ Memory Instructions (\iff & \X{ea} = i + \memarg.\OFFSET \\ \wedge & \X{ea} + N \leq |S.\SMEMS[F.\AMODULE.\MIMEMS[0]].\MIDATA| \\ \wedge & L = 128/N \\ - \wedge & S' = S \with \SMEMS[F.\AMODULE.\MIMEMS[0]].\MIDATA[\X{ea} \slice N/8] = \bytes_{\iN}(\lanes_{\K{i}N\K{x}L}(c)[x])) + \wedge & S' = S \with \SMEMS[F.\AMODULE.\MIMEMS[0]].\MIDATA[\X{ea} \slice N/8] = \bytes_{\iN}(\lanes_{\IN\K{x}L}(c)[x])) \end{array} \\[1ex] \begin{array}{lcl@{\qquad}l} diff --git a/document/core/exec/numerics.rst b/document/core/exec/numerics.rst index fa03504eb..f9eae6b9d 100644 --- a/document/core/exec/numerics.rst +++ b/document/core/exec/numerics.rst @@ -104,18 +104,19 @@ Conventions: -.. index:: bit, integer, floating-point +.. index:: bit, integer, floating-point, numeric vector .. _aux-bits: Representations ~~~~~~~~~~~~~~~ -Numbers have an underlying binary representation as a sequence of bits: +Numbers and numeric vectors have an underlying binary representation as a sequence of bits: .. math:: \begin{array}{lll@{\qquad}l} - \bits_{\K{i}N}(i) &=& \ibits_N(i) \\ - \bits_{\K{f}N}(z) &=& \fbits_N(z) \\ + \bits_{\IN}(i) &=& \ibits_N(i) \\ + \bits_{\FN}(z) &=& \fbits_N(z) \\ + \bits_{\VN}(i) &=& \ibits_N(i) \\ \end{array} Each of these functions is a bijection, hence they are invertible. @@ -163,6 +164,7 @@ where :math:`M = \significand(N)` and :math:`E = \exponent(N)`. .. index:: numeric vector, shape, lane .. _aux-lanes: +.. _syntax-i128: Vectors ....... diff --git a/document/core/syntax/instructions.rst b/document/core/syntax/instructions.rst index 9c48736b0..e22c42002 100644 --- a/document/core/syntax/instructions.rst +++ b/document/core/syntax/instructions.rst @@ -171,7 +171,7 @@ Occasionally, it is convenient to group operators together according to the foll \end{array} -.. index:: ! vector instruction, numeric vectors, number, value, value type, SIMD +.. index:: ! vector instruction, numeric vector, number, value, value type, SIMD pair: abstract syntax; instruction .. _syntax-laneidx: .. _syntax-shape: diff --git a/document/core/syntax/values.rst b/document/core/syntax/values.rst index 1b155df42..72ff7d3a0 100644 --- a/document/core/syntax/values.rst +++ b/document/core/syntax/values.rst @@ -148,7 +148,7 @@ Conventions * The meta variable :math:`z` ranges over floating-point values where clear from context. -.. index:: ! numeric vectors, integer, floating-point, lane, SIMD +.. index:: ! numeric vector, integer, floating-point, lane, SIMD pair: abstract syntax; vector .. _syntax-vecnum: diff --git a/document/core/util/macros.def b/document/core/util/macros.def index 12054c26a..df4af62f8 100644 --- a/document/core/util/macros.def +++ b/document/core/util/macros.def @@ -184,13 +184,15 @@ .. |F32| mathdef:: \xref{syntax/types}{syntax-valtype}{\K{f32}} .. |F64| mathdef:: \xref{syntax/types}{syntax-valtype}{\K{f64}} .. |V128| mathdef:: \xref{syntax/types}{syntax-valtype}{\K{v128}} +.. |IN| mathdef:: \xref{syntax/types}{syntax-valtype}{\K{i}N} +.. |FN| mathdef:: \xref{syntax/types}{syntax-valtype}{\K{f}N} +.. |VN| mathdef:: \xref{syntax/types}{syntax-valtype}{\K{v}N} .. |I8X16| mathdef:: \xref{syntax/types}{syntax-valtype}{\K{i8x16}} .. |I16X8| mathdef:: \xref{syntax/types}{syntax-valtype}{\K{i16x8}} .. |I32X4| mathdef:: \xref{syntax/types}{syntax-valtype}{\K{i32x4}} .. |I64X2| mathdef:: \xref{syntax/types}{syntax-valtype}{\K{i64x2}} .. |F32X4| mathdef:: \xref{syntax/types}{syntax-valtype}{\K{f32x4}} .. |F64X2| mathdef:: \xref{syntax/types}{syntax-valtype}{\K{f64x2}} -.. |I128| mathdef:: \K{i128} .. |FUNCREF| mathdef:: \xref{syntax/types}{syntax-reftype}{\K{funcref}} .. |EXTERNREF| mathdef:: \xref{syntax/types}{syntax-reftype}{\K{externref}} From 5b18d52295bc8fe0cbb9a24065e957a52e744c03 Mon Sep 17 00:00:00 2001 From: Ben Visness Date: Mon, 3 Jul 2023 10:52:27 -0500 Subject: [PATCH 16/25] [spec] Add missing type to elem.drop and store soundness (#1668) --- document/core/appendix/properties.rst | 4 ++-- document/core/exec/instructions.rst | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/document/core/appendix/properties.rst b/document/core/appendix/properties.rst index d9b6a3548..3804dd4aa 100644 --- a/document/core/appendix/properties.rst +++ b/document/core/appendix/properties.rst @@ -278,8 +278,8 @@ Module instances are classified by *module contexts*, which are regular :ref:`co .. index:: element instance, reference .. _valid-eleminst: -:ref:`Element Instances ` :math:`\{ \EIELEM~\X{fa}^\ast \}` -............................................................................ +:ref:`Element Instances ` :math:`\{ \EITYPE~t, \EIELEM~\reff^\ast \}` +...................................................................................... * For each :ref:`reference ` :math:`\reff_i` in the elements :math:`\reff^n`: diff --git a/document/core/exec/instructions.rst b/document/core/exec/instructions.rst index f86349b4e..ccb27bfd3 100644 --- a/document/core/exec/instructions.rst +++ b/document/core/exec/instructions.rst @@ -1682,7 +1682,7 @@ Table Instructions 4. Assert: due to :ref:`validation `, :math:`S.\SELEMS[a]` exists. -5. Replace :math:`S.\SELEMS[a]` with the :ref:`element instance ` :math:`\{\EIELEM~\epsilon\}`. +5. Replace :math:`S.\SELEMS[a].\EIELEM` with :math:`\epsilon`. .. math:: ~\\[-1ex] @@ -1691,7 +1691,7 @@ Table Instructions S; F; (\ELEMDROP~x) &\stepto& S'; F; \epsilon \end{array} \\ \qquad - (\iff S' = S \with \SELEMS[F.\AMODULE.\MIELEMS[x]] = \{ \EIELEM~\epsilon \}) \\ + (\iff S' = S \with \SELEMS[F.\AMODULE.\MIELEMS[x]].\EIELEM = \epsilon) \\ \end{array} From 2b00952f3dc2662622a04b113304fc3491178dc0 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Tue, 11 Jul 2023 06:17:49 -0700 Subject: [PATCH 17/25] [test] Add tests for out-of-range NaN payloads (#1670) --- test/core/float_literals.wast | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/test/core/float_literals.wast b/test/core/float_literals.wast index fefb91fbb..3b3ed76bb 100644 --- a/test/core/float_literals.wast +++ b/test/core/float_literals.wast @@ -352,6 +352,10 @@ (module quote "(global f32 (f32.const 0x1.0p_+1))") "unknown operator" ) +(assert_malformed + (module quote "(global f32 (f32.const nan:0x80_0000))") + "constant out of range" +) (assert_malformed (module quote "(global f64 (f64.const _100))") @@ -505,3 +509,7 @@ (module quote "(global f64 (f64.const 0x1.0p_+1))") "unknown operator" ) +(assert_malformed + (module quote "(global f64 (f64.const nan:0x10_0000_0000_0000))") + "constant out of range" +) From 539d521ffd313628cbf88049d20a6a67ea84fa09 Mon Sep 17 00:00:00 2001 From: Patrick Dubroy Date: Wed, 12 Jul 2023 20:03:10 +0200 Subject: [PATCH 18/25] [spec] Fix typo (#1671) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit depended → dependent --- document/core/binary/modules.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/document/core/binary/modules.rst b/document/core/binary/modules.rst index e9c72b61a..8e488582d 100644 --- a/document/core/binary/modules.rst +++ b/document/core/binary/modules.rst @@ -60,7 +60,7 @@ Each section consists of * a one-byte section *id*, * the |U32| *size* of the contents, in bytes, -* the actual *contents*, whose structure is depended on the section id. +* the actual *contents*, whose structure is dependent on the section id. Every section is optional; an omitted section is equivalent to the section being present with empty contents. From f3a57d973332090f70d32d8333253ff78afca517 Mon Sep 17 00:00:00 2001 From: Andreas Rossberg Date: Mon, 24 Jul 2023 07:32:12 +0200 Subject: [PATCH 19/25] [spec] Remark about the convention of using a pattern for attribute variable --- document/core/binary/conventions.rst | 1 + document/core/text/conventions.rst | 1 + 2 files changed, 2 insertions(+) diff --git a/document/core/binary/conventions.rst b/document/core/binary/conventions.rst index 83c80399f..7b606e1e4 100644 --- a/document/core/binary/conventions.rst +++ b/document/core/binary/conventions.rst @@ -54,6 +54,7 @@ In order to distinguish symbols of the binary syntax from symbols of the abstrac (This is a shorthand for :math:`B^n` where :math:`n \leq 1`.) * :math:`x{:}B` denotes the same language as the nonterminal :math:`B`, but also binds the variable :math:`x` to the attribute synthesized for :math:`B`. + A pattern may also be used instead of a variable, e.g., :math:`7{:}B`. * Productions are written :math:`\B{sym} ::= B_1 \Rightarrow A_1 ~|~ \dots ~|~ B_n \Rightarrow A_n`, where each :math:`A_i` is the attribute that is synthesized for :math:`\B{sym}` in the given case, usually from attribute variables bound in :math:`B_i`. diff --git a/document/core/text/conventions.rst b/document/core/text/conventions.rst index 0bd32e033..1efc88b03 100644 --- a/document/core/text/conventions.rst +++ b/document/core/text/conventions.rst @@ -49,6 +49,7 @@ In order to distinguish symbols of the textual syntax from symbols of the abstra (This is a shorthand for :math:`T^n` where :math:`n \leq 1`.) * :math:`x{:}T` denotes the same language as the nonterminal :math:`T`, but also binds the variable :math:`x` to the attribute synthesized for :math:`T`. + A pattern may also be used instead of a variable, e.g., :math:`(x,y){:}T`. * Productions are written :math:`\T{sym} ::= T_1 \Rightarrow A_1 ~|~ \dots ~|~ T_n \Rightarrow A_n`, where each :math:`A_i` is the attribute that is synthesized for :math:`\T{sym}` in the given case, usually from attribute variables bound in :math:`T_i`. From 3abc5872db2dfac841aea0e8b5de40ed94bcdb5c Mon Sep 17 00:00:00 2001 From: Andreas Rossberg Date: Mon, 24 Jul 2023 08:52:44 +0200 Subject: [PATCH 20/25] [interpreter] Bump version to 2.0.1 --- interpreter/main/main.ml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/interpreter/main/main.ml b/interpreter/main/main.ml index beeb98049..e626a27de 100644 --- a/interpreter/main/main.ml +++ b/interpreter/main/main.ml @@ -1,5 +1,5 @@ let name = "wasm" -let version = "2.0" +let version = "2.0.1" let configure () = Import.register (Utf8.decode "spectest") Spectest.lookup; From 797cb5e1f709690ac52fa9cf5243661bd92eccf2 Mon Sep 17 00:00:00 2001 From: Andreas Rossberg Date: Mon, 24 Jul 2023 09:34:31 +0200 Subject: [PATCH 21/25] [interpreter] Makefile support for opam releases --- interpreter/Makefile | 10 ++++++++++ interpreter/meta/opam/opam | 22 ++++++++++++++++++++++ 2 files changed, 32 insertions(+) create mode 100644 interpreter/meta/opam/opam diff --git a/interpreter/Makefile b/interpreter/Makefile index 014b98d55..9caf2a4ac 100644 --- a/interpreter/Makefile +++ b/interpreter/Makefile @@ -206,3 +206,13 @@ install: _build/$(LIB).cmx _build/$(LIB).cmo uninstall: ocamlfind remove $(LIB) + +opam-release/%: + git tag opam-$* + git push --tags + wget https://github.com/WebAssembly/spec/archive/opam-$*.zip + cp meta/opam/opam . + sed s/@VERSION/$*/g opam >opam.tmp + sed s/@MD5/`md5 -q opam-$*.zip`/g opam.tmp >opam + rm opam.tmp + echo Created file ./opam, submit to github opam-repository/packages/wasm/wasm.$*/opam diff --git a/interpreter/meta/opam/opam b/interpreter/meta/opam/opam new file mode 100644 index 000000000..139251f3f --- /dev/null +++ b/interpreter/meta/opam/opam @@ -0,0 +1,22 @@ +opam-version: "2.0" +maintainer: "Andreas Rossberg " +authors: "Andreas Rossberg " +homepage: "https://github.com/WebAssembly/spec" +bug-reports: "https://github.com/WebAssembly/spec/issues" +license: "Apache-2.0" +dev-repo: "git+https://github.com/WebAssembly/spec.git" +build: [ + [make "-C" "interpreter" "opt" "unopt"] +] +install: [make "-C" "interpreter" "install"] +depends: [ + "ocaml" {>= "4.12.0"} + "ocamlfind" {build} + "ocamlbuild" {build} +] +synopsis: + "Library to read and write WebAssembly (Wasm) files and manipulate their AST" +url { + src: "https://github.com/WebAssembly/spec/archive/opam-@VERSION.zip" + checksum: "md5=@MD5" +} From 8a0080afe5ca081c0e6a5c221254cbfd57b02fc4 Mon Sep 17 00:00:00 2001 From: Andreas Rossberg Date: Mon, 24 Jul 2023 09:46:23 +0200 Subject: [PATCH 22/25] [interpreter] Makefile tweaks --- interpreter/Makefile | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/interpreter/Makefile b/interpreter/Makefile index 9caf2a4ac..5a6cb64a8 100644 --- a/interpreter/Makefile +++ b/interpreter/Makefile @@ -208,11 +208,12 @@ uninstall: ocamlfind remove $(LIB) opam-release/%: - git tag opam-$* + #git tag opam-$* git push --tags + rm -f opam-$*.zip wget https://github.com/WebAssembly/spec/archive/opam-$*.zip cp meta/opam/opam . - sed s/@VERSION/$*/g opam >opam.tmp - sed s/@MD5/`md5 -q opam-$*.zip`/g opam.tmp >opam - rm opam.tmp - echo Created file ./opam, submit to github opam-repository/packages/wasm/wasm.$*/opam + sed -i "tmp" s/@VERSION/$*/g opam + sed -i "tmp" s/@MD5/`md5 -q opam-$*.zip`/g opam + rm opam-$*.zip + @echo Created file ./opam, submit to github opam-repository/packages/wasm/wasm.$*/opam From 0bd3aeb7061984f6496923b155e165f25aa8c20b Mon Sep 17 00:00:00 2001 From: Andreas Rossberg Date: Mon, 24 Jul 2023 09:49:12 +0200 Subject: [PATCH 23/25] [interpreter] Makefile tweaks --- interpreter/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/interpreter/Makefile b/interpreter/Makefile index 5a6cb64a8..aafdb2b8a 100644 --- a/interpreter/Makefile +++ b/interpreter/Makefile @@ -208,7 +208,7 @@ uninstall: ocamlfind remove $(LIB) opam-release/%: - #git tag opam-$* + git tag opam-$* git push --tags rm -f opam-$*.zip wget https://github.com/WebAssembly/spec/archive/opam-$*.zip From cfc93439b9b03d0a6decd38353ae03194324c795 Mon Sep 17 00:00:00 2001 From: Andreas Rossberg Date: Mon, 24 Jul 2023 11:59:40 +0200 Subject: [PATCH 24/25] [interpreter] Tune opam file to fix opam repo CI --- interpreter/Makefile | 6 +++--- interpreter/meta/opam/opam | 1 + 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/interpreter/Makefile b/interpreter/Makefile index aafdb2b8a..740554d3a 100644 --- a/interpreter/Makefile +++ b/interpreter/Makefile @@ -213,7 +213,7 @@ opam-release/%: rm -f opam-$*.zip wget https://github.com/WebAssembly/spec/archive/opam-$*.zip cp meta/opam/opam . - sed -i "tmp" s/@VERSION/$*/g opam - sed -i "tmp" s/@MD5/`md5 -q opam-$*.zip`/g opam - rm opam-$*.zip + sed -i ".tmp" s/@VERSION/$*/g opam + sed -i ".tmp" s/@MD5/`md5 -q opam-$*.zip`/g opam + rm opam.tmp opam-$*.zip @echo Created file ./opam, submit to github opam-repository/packages/wasm/wasm.$*/opam diff --git a/interpreter/meta/opam/opam b/interpreter/meta/opam/opam index 139251f3f..845fe675e 100644 --- a/interpreter/meta/opam/opam +++ b/interpreter/meta/opam/opam @@ -14,6 +14,7 @@ depends: [ "ocamlfind" {build} "ocamlbuild" {build} ] +conflicts: ["ocaml-option-bytecode-only"] # uses ocamlopt unconconditionally synopsis: "Library to read and write WebAssembly (Wasm) files and manipulate their AST" url { From 653938a88c6f40eb886d5980ca315136eb861d03 Mon Sep 17 00:00:00 2001 From: zapashcanon Date: Wed, 26 Jul 2023 14:14:44 +0200 Subject: [PATCH 25/25] [interpreter] Use dune instead of ocamlbuild (#1665) --- interpreter/.gitignore | 15 +- interpreter/Makefile | 212 +++++++-------------------- interpreter/README.md | 19 +-- interpreter/dune | 31 +++- interpreter/dune-project | 19 +++ interpreter/{meta => }/jslib/wast.ml | 1 + interpreter/meta/findlib/META | 4 - interpreter/meta/opam/opam | 23 --- interpreter/wasm.opam | 32 ++++ interpreter/winmake.bat | 75 ---------- 10 files changed, 137 insertions(+), 294 deletions(-) rename interpreter/{meta => }/jslib/wast.ml (99%) delete mode 100644 interpreter/meta/findlib/META delete mode 100644 interpreter/meta/opam/opam create mode 100644 interpreter/wasm.opam delete mode 100644 interpreter/winmake.bat diff --git a/interpreter/.gitignore b/interpreter/.gitignore index 0a02ff708..ced4eafb6 100644 --- a/interpreter/.gitignore +++ b/interpreter/.gitignore @@ -1,13 +1,6 @@ -*.cmo -*.cmx -*.native -*.byte -*.opt -*.unopt -*.js -*.zip -*.mlpack _build wasm -wasm.debug - +*.install +*.js +*.zip +opam diff --git a/interpreter/Makefile b/interpreter/Makefile index 740554d3a..d67882b29 100644 --- a/interpreter/Makefile +++ b/interpreter/Makefile @@ -1,4 +1,4 @@ -# This Makefile uses ocamlbuild but does not rely on ocamlfind or the Opam +# This Makefile uses dune but does not rely on ocamlfind or the Opam # package manager to build. However, Opam package management is available # optionally through the check/install/uninstall targets. # @@ -9,131 +9,45 @@ # Configuration -NAME = wasm -UNOPT = $(NAME).debug -OPT = $(NAME) -LIB = $(NAME) +NAME = wasm +OPT = $(NAME).exe ZIP = $(NAME).zip -JSLIB = wast -WINMAKE = winmake.bat - -DIRS = util syntax binary text valid runtime exec script host main tests -LIBS = -FLAGS = -lexflags -ml -cflags '-w +a-4-27-42-44-45-70 -warn-error +a-3' -OCBA = ocamlbuild $(FLAGS) $(DIRS:%=-I %) -OCB = $(OCBA) $(LIBS:%=-libs %) -JSO = js_of_ocaml -q --opt 3 -JS = # set to JS shell command to run JS tests, empty to skip +JSLIB = wast.js +BUILDDIR = _build/default -# Main targets +JS = # set to JS shell command to run JS tests, empty to skip -.PHONY: default opt unopt libopt libunopt jslib all land zip smallint dunebuild -default: opt -debug: unopt -opt: $(OPT) -unopt: $(UNOPT) -libopt: _build/$(LIB).cmx _build/$(LIB).cmxa -libunopt: _build/$(LIB).cmo _build/$(LIB).cma -jslib: $(JSLIB).js -all: unopt opt libunopt libopt test -land: $(WINMAKE) all -zip: $(ZIP) -smallint: smallint.native -ci: land jslib dunebuild +# Main targets -dunebuild: - dune build +.PHONY: default opt jslib all zip smallint +default: $(OPT) +jslib: $(JSLIB) +all: $(OPT) test +zip: $(ZIP) +smallint: smallint.exe +ci: all jslib # Building executable +.PHONY: $(NAME).exe +$(NAME).exe: + rm -f $(NAME) + dune build $@ + cp $(BUILDDIR)/$(OPT) $(NAME) -empty = -space = $(empty) $(empty) -comma = , - -.INTERMEDIATE: _tags -_tags: - echo >$@ "true: bin_annot" - echo >>$@ "true: debug" - echo >>$@ "<{$(subst $(space),$(comma),$(DIRS))}/*.cmx>: for-pack($(PACK))" - -$(UNOPT): main.byte - mv $< $@ - -$(OPT): main.native - mv $< $@ - -.PHONY: main.byte main.native -main.byte: _tags - $(OCB) -quiet $@ - -main.native: _tags - $(OCB) -quiet $@ - -.PHONY: smallint.byte smallint.native -smallint.byte: _tags - $(OCB) -quiet $@ -smallint.native: _tags - $(OCB) -quiet $@ - - -# Building library - -FILES = $(shell ls $(DIRS:%=%/*) | grep '[.]ml[^.]*$$') -PACK = $(shell echo `echo $(LIB) | sed 's/^\(.\).*$$/\\1/g' | tr [:lower:] [:upper:]``echo $(LIB) | sed 's/^.\(.*\)$$/\\1/g'`) - -.INTERMEDIATE: $(LIB).mlpack -$(LIB).mlpack: $(DIRS) - ls $(FILES) \ - | sed 's:\(.*/\)\{0,1\}\(.*\)\.[^\.]*:\2:' \ - | grep -v main \ - | sort | uniq \ - >$@ - -.INTERMEDIATE: $(LIB).mllib -$(LIB).mllib: - echo Wasm >$@ - -_build/$(LIB).cmo: $(FILES) $(LIB).mlpack _tags Makefile - $(OCB) -quiet $(LIB).cmo - -_build/$(LIB).cmx: $(FILES) $(LIB).mlpack _tags Makefile - $(OCB) -quiet $(LIB).cmx - -_build/$(LIB).cma: $(FILES) $(LIB).mllib _tags Makefile - $(OCBA) -quiet $(LIB).cma - -_build/$(LIB).cmxa: $(FILES) $(LIB).mllib _tags Makefile - $(OCBA) -quiet $(LIB).cmxa - +.PHONY: smallint.exe +smallint.exe: + dune build $@ # Building JavaScript library -JSLIB_DIR = meta/jslib -JSLIB_FLAGS = -I $(JSLIB_DIR) -use-ocamlfind -pkg js_of_ocaml -pkg js_of_ocaml-ppx - -.INTERMEDIATE: $(JSLIB).byte -$(JSLIB).byte: $(JSLIB_DIR)/$(JSLIB).ml - $(OCBA) $(JSLIB_FLAGS) $@ - -$(JSLIB).js: $(JSLIB).byte - $(JSO) $< - -# Building Windows build file - -$(WINMAKE): clean - echo rem Auto-generated from Makefile! >$@ - echo set NAME=$(NAME) >>$@ - echo if \'%1\' neq \'\' set NAME=%1 >>$@ - $(OCB) main.byte \ - | grep -v ocamldep \ - | grep -v mkdir \ - | sed s:`which ocaml`:ocaml:g \ - | sed s:main/main.d.byte:%NAME%.exe: \ - >>$@ +$(JSLIB): $(BUILDDIR)/$(JSLIB) + cp $< $@ +$(BUILDDIR)/$(JSLIB): + dune build $(JSLIB) # Executing test suite @@ -142,78 +56,60 @@ TESTDIR = ../test/core TESTFILES = $(shell cd $(TESTDIR); ls *.wast; ls [a-z]*/*.wast) TESTS = $(TESTFILES:%.wast=%) -.PHONY: test debugtest partest dune-test +.PHONY: test partest dune-test test: $(OPT) smallint - $(TESTDIR)/run.py --wasm `pwd`/$(OPT) $(if $(JS),--js '$(JS)',) - ./smallint.native -debugtest: $(UNOPT) smallint - $(TESTDIR)/run.py --wasm `pwd`/$(UNOPT) $(if $(JS),--js '$(JS)',) - ./smallint.native + $(TESTDIR)/run.py --wasm `pwd`/$(BUILDDIR)/$(OPT) $(if $(JS),--js '$(JS)',) + dune exec ./smallint.exe test/%: $(OPT) - $(TESTDIR)/run.py --wasm `pwd`/$(OPT) $(if $(JS),--js '$(JS)',) $(TESTDIR)/$*.wast -debugtest/%: $(UNOPT) - $(TESTDIR)/run.py --wasm `pwd`/$(UNOPT) $(if $(JS),--js '$(JS)',) $(TESTDIR)/$*.wast + $(TESTDIR)/run.py --wasm `pwd`/$(BUILDDIR)/$(OPT) $(if $(JS),--js '$(JS)',) $(TESTDIR)/$*.wast run/%: $(OPT) ./$(OPT) $(TESTDIR)/$*.wast -debug/%: $(UNOPT) - ./$(UNOPT) $(TESTDIR)/$*.wast -partest: $(TESTS:%=quiettest/%) +partest: $(TESTS:%=quiettest/%) @echo All tests passed. quiettest/%: $(OPT) @ ( \ - $(TESTDIR)/run.py 2>$(@F).out --wasm `pwd`/$(OPT) $(if $(JS),--js '$(JS)',) $(TESTDIR)/$*.wast && \ + $(TESTDIR)/run.py 2>$(@F).out --wasm `pwd`/$(BUILDDIR)/$(OPT) $(if $(JS),--js '$(JS)',) $(TESTDIR)/$*.wast && \ rm $(@F).out \ ) || \ cat $(@F).out || rm $(@F).out || exit 1 smallinttest: smallint - @./smallint.native + dune exec ./smallint.exe dunetest: dune test +install: + dune build -p $(NAME) @install + dune install + +opam-release/%: + git tag opam-$* + git push --tags + rm -f opam-$*.zip + wget https://github.com/WebAssembly/spec/archive/opam-$*.zip + cp wasm.opam opam + echo "url {" >> opam + echo " src: \"https://github.com/WebAssembly/spec/archive/opam-$*.zip\"" >> opam + echo " checksum: \"md5=`md5 -q opam-$*.zip`\"" >> opam + echo "}" >> opam + rm opam-$*.zip + @echo Created file ./opam, submit to github opam-repository/packages/wasm/wasm.$*/opam # Miscellaneous targets .PHONY: clean -$(ZIP): $(WINMAKE) - git archive --format=zip --prefix=$(NAME)/ -o $@ HEAD +$(ZIP): + git archive --format=zip --prefix=$(NAME)/ -o $@ HEAD clean: - rm -rf _build/jslib $(LIB).mlpack _tags $(JSLIB).js - $(OCB) -clean - - -# Opam support - -.PHONY: check install uninstall + dune clean -check: - # Check that we can find all relevant libraries - # when using ocamlfind - ocamlfind query $(LIBS) - -install: _build/$(LIB).cmx _build/$(LIB).cmo - ocamlfind install $(LIB) meta/findlib/META _build/$(LIB).o \ - $(wildcard _build/$(LIB).cm*) \ - $(wildcard $(DIRS:%=%/*.mli)) - -uninstall: - ocamlfind remove $(LIB) - -opam-release/%: - git tag opam-$* - git push --tags - rm -f opam-$*.zip - wget https://github.com/WebAssembly/spec/archive/opam-$*.zip - cp meta/opam/opam . - sed -i ".tmp" s/@VERSION/$*/g opam - sed -i ".tmp" s/@MD5/`md5 -q opam-$*.zip`/g opam - rm opam.tmp opam-$*.zip - @echo Created file ./opam, submit to github opam-repository/packages/wasm/wasm.$*/opam +distclean: clean + rm -f $(NAME) $(JSLIB) diff --git a/interpreter/README.md b/interpreter/README.md index fc2a1827a..1df7ff715 100644 --- a/interpreter/README.md +++ b/interpreter/README.md @@ -17,15 +17,14 @@ The text format defines modules in S-expression syntax. Moreover, it is generali You'll need OCaml 4.12 or higher. Instructions for installing a recent version of OCaml on multiple platforms are available [here](https://ocaml.org/docs/install.html). On most platforms, the recommended way is through [OPAM](https://ocaml.org/docs/install.html#OPAM). +You'll also need to install the dune build system. See the [installation instructions](https://github.com/ocaml/dune#installation-1). + Once you have OCaml, simply do ``` make ``` -You'll get an executable named `./wasm`. This is a byte code executable. If you want a (faster) native code executable, do -``` -make opt -``` +You'll get an executable named `./wasm`. To run the test suite, ``` make test @@ -34,12 +33,6 @@ To do everything: ``` make all ``` -Before committing changes, you should do -``` -make land -``` -That builds `all`, plus updates `winmake.bat`. - #### Building on Windows @@ -49,12 +42,6 @@ The instructions depend on how you [installed OCaml on Windows](https://ocaml.or 2. *Windows Subsystem for Linux* (WSL): You can build the interpreter using `make`, as described above. -3. *From source*: If you just want to build the interpreter and don't care about modifying it, you don't need to install the Cygwin core that comes with the installer. Just install OCaml itself and run -``` -winmake.bat -``` -in a Windows shell, which creates a program named `wasm`. Note that this will be a byte code executable only, i.e., somewhat slower. - In any way, in order to run the test suite you'll need to have Python installed. If you used Option 3, you can invoke the test runner `runtests.py` directly instead of doing it through `make`. diff --git a/interpreter/dune b/interpreter/dune index 48274aad9..c0e9c292f 100644 --- a/interpreter/dune +++ b/interpreter/dune @@ -1,16 +1,16 @@ (include_subdirs unqualified) (library - (name wasm) - ; The 'main' module shall not be part of the library, as it would start the + (public_name wasm) + ; The 'wasm' module shall not be part of the library, as it would start the ; Wasm REPL every time in all the dependencies. ; We exclude the 'wast' module as it is only used for the JS build. ; 'smallint' is a separate test module. - (modules :standard \ main smallint wast)) + (modules :standard \ main wasm smallint wast)) (executable - (name main) - (modules main) + (public_name wasm) + (modules wasm) (libraries wasm) (flags (-open Wasm))) @@ -22,6 +22,23 @@ (flags (-open Wasm))) +(executable + (name wast) + (modules wast) + (modes js) + (libraries js_of_ocaml wasm) + (preprocess (pps js_of_ocaml-ppx))) + +(rule + (targets wasm.ml) + (deps main/main.ml) + (action (copy main/main.ml wasm.ml))) + +(rule + (targets wast.js) + (deps wast.bc.js) + (action (copy wast.bc.js wast.js))) + (subdir text (rule @@ -42,10 +59,10 @@ (rule (alias runtest) (deps - ./main.exe + ./wasm.exe ./smallint.exe (source_tree ../test)) (action (progn - (run ../test/core/run.py --wasm ./main.exe) + (run ../test/core/run.py --wasm ./wasm.exe) (run ./smallint.exe)))) diff --git a/interpreter/dune-project b/interpreter/dune-project index c994249ac..0d15135d3 100644 --- a/interpreter/dune-project +++ b/interpreter/dune-project @@ -1 +1,20 @@ (lang dune 2.9) + +(name wasm) + +(generate_opam_files true) + +(license Apache-2.0) + +(source + (github WebAssembly/spec)) + +(authors "Andreas Rossberg = 4.12)))) diff --git a/interpreter/meta/jslib/wast.ml b/interpreter/jslib/wast.ml similarity index 99% rename from interpreter/meta/jslib/wast.ml rename to interpreter/jslib/wast.ml index 9af04f918..0ab4bd8fd 100644 --- a/interpreter/meta/jslib/wast.ml +++ b/interpreter/jslib/wast.ml @@ -1,6 +1,7 @@ (* Implements a wrapper library that allows the use of the reference * interpreter's encode/decode functionality in JavaScript. *) +open Wasm open Js_of_ocaml let _ = diff --git a/interpreter/meta/findlib/META b/interpreter/meta/findlib/META deleted file mode 100644 index 2c1d96dd0..000000000 --- a/interpreter/meta/findlib/META +++ /dev/null @@ -1,4 +0,0 @@ -description = "A library for writing/reading/running WebAssembly binaries" -requires = "bigarray,str" -archive(byte) = "wasm.cmo" -archive(native) = "wasm.cmx" diff --git a/interpreter/meta/opam/opam b/interpreter/meta/opam/opam deleted file mode 100644 index 845fe675e..000000000 --- a/interpreter/meta/opam/opam +++ /dev/null @@ -1,23 +0,0 @@ -opam-version: "2.0" -maintainer: "Andreas Rossberg " -authors: "Andreas Rossberg " -homepage: "https://github.com/WebAssembly/spec" -bug-reports: "https://github.com/WebAssembly/spec/issues" -license: "Apache-2.0" -dev-repo: "git+https://github.com/WebAssembly/spec.git" -build: [ - [make "-C" "interpreter" "opt" "unopt"] -] -install: [make "-C" "interpreter" "install"] -depends: [ - "ocaml" {>= "4.12.0"} - "ocamlfind" {build} - "ocamlbuild" {build} -] -conflicts: ["ocaml-option-bytecode-only"] # uses ocamlopt unconconditionally -synopsis: - "Library to read and write WebAssembly (Wasm) files and manipulate their AST" -url { - src: "https://github.com/WebAssembly/spec/archive/opam-@VERSION.zip" - checksum: "md5=@MD5" -} diff --git a/interpreter/wasm.opam b/interpreter/wasm.opam new file mode 100644 index 000000000..5d5984106 --- /dev/null +++ b/interpreter/wasm.opam @@ -0,0 +1,32 @@ +# This file is generated by dune, edit dune-project instead +opam-version: "2.0" +synopsis: + "Library to read and write WebAssembly (Wasm) files and manipulate their AST" +maintainer: ["Andreas Rossberg = "2.9"} + "ocaml" {>= "4.12"} + "odoc" {with-doc} +] +build: [ + ["dune" "subst"] {dev} + [ + "dune" + "build" + "-p" + name + "-j" + jobs + "--promote-install-files=false" + "@install" + "@runtest" {with-test} + "@doc" {with-doc} + ] + ["dune" "install" "-p" name "--create-install-files" name] +] +dev-repo: "git+https://github.com/WebAssembly/spec.git" diff --git a/interpreter/winmake.bat b/interpreter/winmake.bat deleted file mode 100644 index 6ff7e8caa..000000000 --- a/interpreter/winmake.bat +++ /dev/null @@ -1,75 +0,0 @@ -rem Auto-generated from Makefile! -set NAME=wasm -if '%1' neq '' set NAME=%1 -ocamlc.opt -c -w +a-3-4-27-42-44-45 -warn-error +a -I exec -I main -I syntax -I text -I binary -I script -I runtime -I util -I host -I valid -o exec/numeric_error.cmo exec/numeric_error.ml -ocamlc.opt -c -w +a-3-4-27-42-44-45 -warn-error +a -I exec -I main -I syntax -I text -I binary -I script -I runtime -I util -I host -I valid -o exec/int.cmo exec/int.ml -ocamlc.opt -c -w +a-3-4-27-42-44-45 -warn-error +a -I util -I main -I syntax -I text -I binary -I exec -I script -I runtime -I host -I valid -o util/lib.cmi util/lib.mli -ocamlc.opt -c -w +a-3-4-27-42-44-45 -warn-error +a -I exec -I main -I syntax -I text -I binary -I script -I runtime -I util -I host -I valid -o exec/i32.cmo exec/i32.ml -ocamlc.opt -c -w +a-3-4-27-42-44-45 -warn-error +a -I exec -I main -I syntax -I text -I binary -I script -I runtime -I util -I host -I valid -o exec/float.cmo exec/float.ml -ocamlc.opt -c -w +a-3-4-27-42-44-45 -warn-error +a -I syntax -I main -I text -I binary -I exec -I script -I runtime -I util -I host -I valid -o syntax/types.cmo syntax/types.ml -ocamlc.opt -c -w +a-3-4-27-42-44-45 -warn-error +a -I exec -I main -I syntax -I text -I binary -I script -I runtime -I util -I host -I valid -o exec/f32.cmo exec/f32.ml -ocamlc.opt -c -w +a-3-4-27-42-44-45 -warn-error +a -I exec -I main -I syntax -I text -I binary -I script -I runtime -I util -I host -I valid -o exec/f64.cmo exec/f64.ml -ocamlc.opt -c -w +a-3-4-27-42-44-45 -warn-error +a -I exec -I main -I syntax -I text -I binary -I script -I runtime -I util -I host -I valid -o exec/i64.cmo exec/i64.ml -ocamlc.opt -c -w +a-3-4-27-42-44-45 -warn-error +a -I syntax -I main -I text -I binary -I exec -I script -I runtime -I util -I host -I valid -o syntax/values.cmo syntax/values.ml -ocamlc.opt -c -w +a-3-4-27-42-44-45 -warn-error +a -I runtime -I main -I syntax -I text -I binary -I exec -I script -I util -I host -I valid -o runtime/memory.cmi runtime/memory.mli -ocamlc.opt -c -w +a-3-4-27-42-44-45 -warn-error +a -I util -I main -I syntax -I text -I binary -I exec -I script -I runtime -I host -I valid -o util/source.cmi util/source.mli -ocamlc.opt -c -w +a-3-4-27-42-44-45 -warn-error +a -I syntax -I main -I text -I binary -I exec -I script -I runtime -I util -I host -I valid -o syntax/ast.cmo syntax/ast.ml -ocamlc.opt -c -w +a-3-4-27-42-44-45 -warn-error +a -I runtime -I main -I syntax -I text -I binary -I exec -I script -I util -I host -I valid -o runtime/func.cmi runtime/func.mli -ocamlc.opt -c -w +a-3-4-27-42-44-45 -warn-error +a -I runtime -I main -I syntax -I text -I binary -I exec -I script -I util -I host -I valid -o runtime/global.cmi runtime/global.mli -ocamlc.opt -c -w +a-3-4-27-42-44-45 -warn-error +a -I runtime -I main -I syntax -I text -I binary -I exec -I script -I util -I host -I valid -o runtime/table.cmi runtime/table.mli -ocamlc.opt -c -w +a-3-4-27-42-44-45 -warn-error +a -I runtime -I main -I syntax -I text -I binary -I exec -I script -I util -I host -I valid -o runtime/instance.cmo runtime/instance.ml -ocamlc.opt -c -w +a-3-4-27-42-44-45 -warn-error +a -I exec -I main -I syntax -I text -I binary -I script -I runtime -I util -I host -I valid -o exec/eval.cmi exec/eval.mli -ocamlc.opt -c -w +a-3-4-27-42-44-45 -warn-error +a -I binary -I main -I syntax -I text -I exec -I script -I runtime -I util -I host -I valid -o binary/utf8.cmi binary/utf8.mli -ocamlc.opt -c -w +a-3-4-27-42-44-45 -warn-error +a -I host -I main -I syntax -I text -I binary -I exec -I script -I runtime -I util -I valid -o host/env.cmo host/env.ml -ocamlc.opt -c -w +a-3-4-27-42-44-45 -warn-error +a -I main -I syntax -I text -I binary -I exec -I script -I runtime -I util -I host -I valid -o main/flags.cmo main/flags.ml -ocamlc.opt -c -w +a-3-4-27-42-44-45 -warn-error +a -I script -I main -I syntax -I text -I binary -I exec -I runtime -I util -I host -I valid -o script/import.cmi script/import.mli -ocamlc.opt -c -w +a-3-4-27-42-44-45 -warn-error +a -I script -I main -I syntax -I text -I binary -I exec -I runtime -I util -I host -I valid -o script/run.cmi script/run.mli -ocamlc.opt -c -w +a-3-4-27-42-44-45 -warn-error +a -I host -I main -I syntax -I text -I binary -I exec -I script -I runtime -I util -I valid -o host/spectest.cmo host/spectest.ml -ocamlc.opt -c -w +a-3-4-27-42-44-45 -warn-error +a -I main -I syntax -I text -I binary -I exec -I script -I runtime -I util -I host -I valid -o main/main.cmo main/main.ml -ocamlc.opt -c -w +a-3-4-27-42-44-45 -warn-error +a -I util -I main -I syntax -I text -I binary -I exec -I script -I runtime -I host -I valid -o util/error.cmi util/error.mli -ocamlc.opt -c -w +a-3-4-27-42-44-45 -warn-error +a -I script -I main -I syntax -I text -I binary -I exec -I runtime -I util -I host -I valid -o script/script.cmo script/script.ml -ocamlc.opt -c -w +a-3-4-27-42-44-45 -warn-error +a -I binary -I main -I syntax -I text -I exec -I script -I runtime -I util -I host -I valid -o binary/decode.cmi binary/decode.mli -ocamlc.opt -c -w +a-3-4-27-42-44-45 -warn-error +a -I binary -I main -I syntax -I text -I exec -I script -I runtime -I util -I host -I valid -o binary/encode.cmi binary/encode.mli -ocamlc.opt -c -w +a-3-4-27-42-44-45 -warn-error +a -I script -I main -I syntax -I text -I binary -I exec -I runtime -I util -I host -I valid -o script/js.cmi script/js.mli -ocamlc.opt -c -w +a-3-4-27-42-44-45 -warn-error +a -I text -I main -I syntax -I binary -I exec -I script -I runtime -I util -I host -I valid -o text/parse.cmi text/parse.mli -ocamlc.opt -c -w +a-3-4-27-42-44-45 -warn-error +a -I text -I main -I syntax -I binary -I exec -I script -I runtime -I util -I host -I valid -o text/print.cmi text/print.mli -ocamlc.opt -c -w +a-3-4-27-42-44-45 -warn-error +a -I valid -I main -I syntax -I text -I binary -I exec -I script -I runtime -I util -I host -o valid/valid.cmi valid/valid.mli -ocamlc.opt -c -w +a-3-4-27-42-44-45 -warn-error +a -I script -I main -I syntax -I text -I binary -I exec -I runtime -I util -I host -I valid -o script/import.cmo script/import.ml -ocamlc.opt -c -w +a-3-4-27-42-44-45 -warn-error +a -I script -I main -I syntax -I text -I binary -I exec -I runtime -I util -I host -I valid -o script/run.cmo script/run.ml -ocamlc.opt -c -w +a-3-4-27-42-44-45 -warn-error +a -I binary -I main -I syntax -I text -I exec -I script -I runtime -I util -I host -I valid -o binary/utf8.cmo binary/utf8.ml -ocamlc.opt -c -w +a-3-4-27-42-44-45 -warn-error +a -I exec -I main -I syntax -I text -I binary -I script -I runtime -I util -I host -I valid -o exec/eval_numeric.cmi exec/eval_numeric.mli -ocamlc.opt -c -w +a-3-4-27-42-44-45 -warn-error +a -I exec -I main -I syntax -I text -I binary -I script -I runtime -I util -I host -I valid -o exec/i64_convert.cmi exec/i64_convert.mli -ocamlc.opt -c -w +a-3-4-27-42-44-45 -warn-error +a -I exec -I main -I syntax -I text -I binary -I script -I runtime -I util -I host -I valid -o exec/eval.cmo exec/eval.ml -ocamlc.opt -c -w +a-3-4-27-42-44-45 -warn-error +a -I runtime -I main -I syntax -I text -I binary -I exec -I script -I util -I host -I valid -o runtime/func.cmo runtime/func.ml -ocamlc.opt -c -w +a-3-4-27-42-44-45 -warn-error +a -I util -I main -I syntax -I text -I binary -I exec -I script -I runtime -I host -I valid -o util/source.cmo util/source.ml -ocamlc.opt -c -w +a-3-4-27-42-44-45 -warn-error +a -I exec -I main -I syntax -I text -I binary -I script -I runtime -I util -I host -I valid -o exec/f32_convert.cmi exec/f32_convert.mli -ocamlc.opt -c -w +a-3-4-27-42-44-45 -warn-error +a -I exec -I main -I syntax -I text -I binary -I script -I runtime -I util -I host -I valid -o exec/f64_convert.cmi exec/f64_convert.mli -ocamlc.opt -c -w +a-3-4-27-42-44-45 -warn-error +a -I exec -I main -I syntax -I text -I binary -I script -I runtime -I util -I host -I valid -o exec/i32_convert.cmi exec/i32_convert.mli -ocamlc.opt -c -w +a-3-4-27-42-44-45 -warn-error +a -I util -I main -I syntax -I text -I binary -I exec -I script -I runtime -I host -I valid -o util/error.cmo util/error.ml -ocamlc.opt -c -w +a-3-4-27-42-44-45 -warn-error +a -I exec -I main -I syntax -I text -I binary -I script -I runtime -I util -I host -I valid -o exec/eval_numeric.cmo exec/eval_numeric.ml -ocamlc.opt -c -w +a-3-4-27-42-44-45 -warn-error +a -I runtime -I main -I syntax -I text -I binary -I exec -I script -I util -I host -I valid -o runtime/global.cmo runtime/global.ml -ocamlc.opt -c -w +a-3-4-27-42-44-45 -warn-error +a -I exec -I main -I syntax -I text -I binary -I script -I runtime -I util -I host -I valid -o exec/i64_convert.cmo exec/i64_convert.ml -ocamlc.opt -c -w +a-3-4-27-42-44-45 -warn-error +a -I util -I main -I syntax -I text -I binary -I exec -I script -I runtime -I host -I valid -o util/lib.cmo util/lib.ml -ocamlc.opt -c -w +a-3-4-27-42-44-45 -warn-error +a -I runtime -I main -I syntax -I text -I binary -I exec -I script -I util -I host -I valid -o runtime/memory.cmo runtime/memory.ml -ocamlc.opt -c -w +a-3-4-27-42-44-45 -warn-error +a -I runtime -I main -I syntax -I text -I binary -I exec -I script -I util -I host -I valid -o runtime/table.cmo runtime/table.ml -ocamlc.opt -c -w +a-3-4-27-42-44-45 -warn-error +a -I exec -I main -I syntax -I text -I binary -I script -I runtime -I util -I host -I valid -o exec/f32_convert.cmo exec/f32_convert.ml -ocamlc.opt -c -w +a-3-4-27-42-44-45 -warn-error +a -I exec -I main -I syntax -I text -I binary -I script -I runtime -I util -I host -I valid -o exec/f64_convert.cmo exec/f64_convert.ml -ocamlc.opt -c -w +a-3-4-27-42-44-45 -warn-error +a -I exec -I main -I syntax -I text -I binary -I script -I runtime -I util -I host -I valid -o exec/i32_convert.cmo exec/i32_convert.ml -ocamlc.opt -c -w +a-3-4-27-42-44-45 -warn-error +a -I syntax -I main -I text -I binary -I exec -I script -I runtime -I util -I host -I valid -o syntax/operators.cmo syntax/operators.ml -ocamlyacc text/parser.mly -ocamlc.opt -c -w +a-3-4-27-42-44-45 -warn-error +a -I text -I main -I syntax -I binary -I exec -I script -I runtime -I util -I host -I valid -o text/parser.cmi text/parser.mli -ocamlc.opt -c -w +a-3-4-27-42-44-45 -warn-error +a -I text -I main -I syntax -I binary -I exec -I script -I runtime -I util -I host -I valid -o text/lexer.cmi text/lexer.mli -ocamlc.opt -c -w +a-3-4-27-42-44-45 -warn-error +a -I util -I main -I syntax -I text -I binary -I exec -I script -I runtime -I host -I valid -o util/sexpr.cmi util/sexpr.mli -ocamlc.opt -c -w +a-3-4-27-42-44-45 -warn-error +a -I text -I main -I syntax -I binary -I exec -I script -I runtime -I util -I host -I valid -o text/arrange.cmi text/arrange.mli -ocamlc.opt -c -w +a-3-4-27-42-44-45 -warn-error +a -I binary -I main -I syntax -I text -I exec -I script -I runtime -I util -I host -I valid -o binary/decode.cmo binary/decode.ml -ocamlc.opt -c -w +a-3-4-27-42-44-45 -warn-error +a -I binary -I main -I syntax -I text -I exec -I script -I runtime -I util -I host -I valid -o binary/encode.cmo binary/encode.ml -ocamlc.opt -c -w +a-3-4-27-42-44-45 -warn-error +a -I script -I main -I syntax -I text -I binary -I exec -I runtime -I util -I host -I valid -o script/js.cmo script/js.ml -ocamlc.opt -c -w +a-3-4-27-42-44-45 -warn-error +a -I text -I main -I syntax -I binary -I exec -I script -I runtime -I util -I host -I valid -o text/parse.cmo text/parse.ml -ocamlc.opt -c -w +a-3-4-27-42-44-45 -warn-error +a -I text -I main -I syntax -I binary -I exec -I script -I runtime -I util -I host -I valid -o text/print.cmo text/print.ml -ocamlc.opt -c -w +a-3-4-27-42-44-45 -warn-error +a -I valid -I main -I syntax -I text -I binary -I exec -I script -I runtime -I util -I host -o valid/valid.cmo valid/valid.ml -ocamllex.opt -q text/lexer.mll -ocamlc.opt -c -w +a-3-4-27-42-44-45 -warn-error +a -I text -I main -I syntax -I binary -I exec -I script -I runtime -I util -I host -I valid -o text/lexer.cmo text/lexer.ml -ocamlc.opt -c -w +a-3-4-27-42-44-45 -warn-error +a -I text -I main -I syntax -I binary -I exec -I script -I runtime -I util -I host -I valid -o text/parser.cmo text/parser.ml -ocamlc.opt -c -w +a-3-4-27-42-44-45 -warn-error +a -I text -I main -I syntax -I binary -I exec -I script -I runtime -I util -I host -I valid -o text/arrange.cmo text/arrange.ml -ocamlc.opt -c -w +a-3-4-27-42-44-45 -warn-error +a -I util -I main -I syntax -I text -I binary -I exec -I script -I runtime -I host -I valid -o util/sexpr.cmo util/sexpr.ml -ocamlc.opt bigarray.cma -I util -I binary -I exec -I syntax -I runtime -I host -I main -I script -I text -I valid util/lib.cmo binary/utf8.cmo exec/float.cmo exec/f32.cmo exec/f64.cmo exec/numeric_error.cmo exec/int.cmo exec/i32.cmo exec/i64.cmo exec/i32_convert.cmo exec/f32_convert.cmo exec/i64_convert.cmo exec/f64_convert.cmo syntax/types.cmo syntax/values.cmo runtime/memory.cmo util/source.cmo syntax/ast.cmo exec/eval_numeric.cmo runtime/func.cmo runtime/global.cmo runtime/table.cmo runtime/instance.cmo util/error.cmo exec/eval.cmo host/env.cmo host/spectest.cmo main/flags.cmo script/import.cmo binary/encode.cmo syntax/operators.cmo binary/decode.cmo script/script.cmo text/parser.cmo text/lexer.cmo text/parse.cmo script/js.cmo util/sexpr.cmo text/arrange.cmo text/print.cmo valid/valid.cmo script/run.cmo main/main.cmo -o main/main.byte