diff options
Diffstat (limited to 'test')
19 files changed, 203 insertions, 78 deletions
diff --git a/test/gen-spec-js.py b/test/gen-spec-js.py index c8502f31..11372abd 100755 --- a/test/gen-spec-js.py +++ b/test/gen-spec-js.py @@ -38,12 +38,14 @@ F32_NEG_INF = 0xff800000 F32_NEG_ZERO = 0x80000000 F32_SIGN_BIT = F32_NEG_ZERO F32_SIG_MASK = 0x7fffff +F32_QUIET_NAN = 0x7fc00000 F32_QUIET_NAN_TAG = 0x400000 F64_INF = 0x7ff0000000000000 F64_NEG_INF = 0xfff0000000000000 F64_NEG_ZERO = 0x8000000000000000 F64_SIGN_BIT = F64_NEG_ZERO F64_SIG_MASK = 0xfffffffffffff +F64_QUIET_NAN = 0x7ff8000000000000 F64_QUIET_NAN_TAG = 0x8000000000000 @@ -183,7 +185,8 @@ def IsValidJSCommand(command): expected = command['expected'] return (IsValidJSAction(action) and all(IsValidJSConstant(x) for x in expected)) - elif type_ in ('assert_return_nan', 'assert_trap', 'assert_exhaustion'): + elif type_ in ('assert_return_canonical_nan', 'assert_return_arithmetic_nan', + 'assert_trap', 'assert_exhaustion'): return IsValidJSAction(action) @@ -197,8 +200,9 @@ def CollectInvalidModuleCommands(commands): module_name = command.get('name') if module_name: module_map[module_name] = pair - elif command['type'] in ('assert_return', 'assert_return_nan', - 'assert_trap', 'assert_exhaustion'): + elif command['type'] in ( + 'assert_return', 'assert_return_canonical_nan', + 'assert_return_arithmetic_nan', 'assert_trap', 'assert_exhaustion'): if IsValidJSCommand(command): continue @@ -249,25 +253,13 @@ class ModuleExtender(object): self._Reinterpret(expected['type']) self._Constant(expected) self._Reinterpret(expected['type']) - self._Compare(expected['type']) + self._Eq(expected['type']) self.lines.extend(['i32.eqz', 'br_if 0']) self.lines.extend(['return', 'end', 'unreachable', ')']) - elif command_type == 'assert_return_nan': - type_ = command['expected'][0]['type'] - self.lines.append('(func (export "%s")' % new_field) - self.lines.append('(local %s)' % type_) - self.lines.append('block') - self._Action(command['action']) - self.lines.append('tee_local 0') - self._Reinterpret(type_) - self.lines.append('get_local 0') - self._Reinterpret(type_) - self._Compare(type_) - self.lines.extend( - ['i32.eqz', 'br_if 0', 'return', 'end', 'unreachable', ')']) - - # Change the command to assert_return, it won't return NaN anymore. - command['type'] = 'assert_return' + elif command_type == 'assert_return_canonical_nan': + self._AssertReturnNan(new_field, command, True) + elif command_type == 'assert_return_arithmetic_nan': + self._AssertReturnNan(new_field, command, False) elif command_type in ('assert_trap', 'assert_exhaustion'): self.lines.append('(func (export "%s")' % new_field) self._Action(command['action']) @@ -280,6 +272,22 @@ class ModuleExtender(object): command['action']['args'] = [] command['expected'] = [] + def _AssertReturnNan(self, new_field, command, canonical): + type_ = command['expected'][0]['type'] + self.lines.append('(func (export "%s")' % new_field) + self.lines.append('block') + self._Action(command['action']) + self._Reinterpret(type_) + self._NanBitmask(canonical, type_) + self._And(type_) + self._QuietNan(type_) + self._Eq(type_) + self.lines.extend( + ['i32.eqz', 'br_if 0', 'return', 'end', 'unreachable', ')']) + + # Change the command to assert_return, it won't return NaN anymore. + command['type'] = 'assert_return' + def _GetExports(self, wast): result = {} pattern = r'^\s*\(export \"(.*?)\"\s*\((\w+) (\d+)' @@ -306,7 +314,7 @@ class ModuleExtender(object): 'f64': ['i64.reinterpret/f64'] }[type_]) - def _Compare(self, type_): + def _Eq(self, type_): self.lines.append({ 'i32': 'i32.eq', 'i64': 'i64.eq', @@ -314,6 +322,36 @@ class ModuleExtender(object): 'f64': 'i64.eq' }[type_]) + def _And(self, type_): + self.lines.append({ + 'i32': 'i32.and', + 'i64': 'i64.and', + 'f32': 'i32.and', + 'f64': 'i64.and' + }[type_]) + + def _NanBitmask(self, canonical, type_): + # When checking for canonical NaNs, the value can differ only in the sign + # bit from +nan. For arithmetic NaNs, the sign bit and the rest of the tag + # can differ as well. + assert(type_ in ('f32', 'f64')) + if not canonical: + return self._QuietNan(type_) + + if type_ == 'f32': + line = 'i32.const 0x7fffffff' + else: + line = 'i64.const 0x7fffffffffffffff' + self.lines.append(line) + + def _QuietNan(self, type_): + assert(type_ in ('f32', 'f64')) + if type_ == 'f32': + line = 'i32.const 0x%x' % F32_QUIET_NAN + else: + line = 'i64.const 0x%x' % F64_QUIET_NAN + self.lines.append(line) + def _Constant(self, const): inst = None type_ = const['type'] @@ -359,7 +397,8 @@ class JSWriter(object): 'assert_unlinkable': self._WriteAssertModuleCommand, 'assert_uninstantiable': self._WriteAssertModuleCommand, 'assert_return': self._WriteAssertReturnCommand, - 'assert_return_nan': self._WriteAssertActionCommand, + 'assert_return_canonical_nan': self._WriteAssertActionCommand, + 'assert_return_arithmetic_nan': self._WriteAssertActionCommand, 'assert_trap': self._WriteAssertActionCommand, 'assert_exhaustion': self._WriteAssertActionCommand, } diff --git a/test/gen-spec-js/assert_return_nan.txt b/test/gen-spec-js/assert_return_nan.txt index 754d1345..b154c108 100644 --- a/test/gen-spec-js/assert_return_nan.txt +++ b/test/gen-spec-js/assert_return_nan.txt @@ -1,16 +1,35 @@ ;;; TOOL: run-gen-spec-js ;;; FLAGS: --prefix=%(test_dir)s/gen-spec-empty-prefix.js (module - (func (export "nan") (result f32) f32.const nan) - (func (export "passthru") (param f32) (result f32) get_local 0)) + (func (export "f32_nan") (result f32) f32.const nan) + (func (export "f32_nan_with_tag") (result f32) f32.const nan:0x1234) + (func (export "f32_passthru") (param f32) (result f32) get_local 0) + + (func (export "f64_nan") (result f64) f64.const nan) + (func (export "f64_nan_with_tag") (result f64) f64.const nan:0x1234) + (func (export "f64_passthru") (param f64) (result f64) get_local 0)) + +(assert_return_canonical_nan (invoke "f32_nan")) +(assert_return_arithmetic_nan (invoke "f32_nan_with_tag")) +(assert_return_canonical_nan (invoke "f64_nan")) +(assert_return_arithmetic_nan (invoke "f64_nan_with_tag")) -(assert_return_nan (invoke "nan")) ;; Rewritten to avoid passing nan as a parameter. -(assert_return_nan (invoke "passthru" (f32.const -nan))) +(assert_return_canonical_nan (invoke "f32_passthru" (f32.const -nan))) +(assert_return_arithmetic_nan (invoke "f32_passthru" (f32.const nan:0x1234))) +(assert_return_canonical_nan (invoke "f64_passthru" (f64.const -nan))) +(assert_return_arithmetic_nan (invoke "f64_passthru" (f64.const nan:0x1234))) + (;; STDOUT ;;; // A deliberately empty file for testing. -$$ = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x0d\x03\x60\x00\x01\x7d\x60\x01\x7d\x01\x7d\x60\x00\x00\x03\x04\x03\x00\x01\x02\x07\x1d\x03\x03\x6e\x61\x6e\x00\x00\x08\x70\x61\x73\x73\x74\x68\x72\x75\x00\x01\x08\x61\x73\x73\x65\x72\x74\x5f\x30\x00\x02\x0a\x29\x03\x07\x00\x43\x00\x00\xc0\x7f\x0b\x04\x00\x20\x00\x0b\x1a\x01\x01\x7d\x02\x40\x43\x00\x00\xc0\xff\x10\x01\x22\x00\xbc\x20\x00\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b"); -assert_return_nan(() => $$.exports["nan"]()); +$$ = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x16\x05\x60\x00\x01\x7d\x60\x01\x7d\x01\x7d\x60\x00\x01\x7c\x60\x01\x7c\x01\x7c\x60\x00\x00\x03\x0b\x0a\x00\x00\x01\x02\x02\x03\x04\x04\x04\x04\x07\x85\x01\x0a\x07\x66\x33\x32\x5f\x6e\x61\x6e\x00\x00\x10\x66\x33\x32\x5f\x6e\x61\x6e\x5f\x77\x69\x74\x68\x5f\x74\x61\x67\x00\x01\x0c\x66\x33\x32\x5f\x70\x61\x73\x73\x74\x68\x72\x75\x00\x02\x07\x66\x36\x34\x5f\x6e\x61\x6e\x00\x03\x10\x66\x36\x34\x5f\x6e\x61\x6e\x5f\x77\x69\x74\x68\x5f\x74\x61\x67\x00\x04\x0c\x66\x36\x34\x5f\x70\x61\x73\x73\x74\x68\x72\x75\x00\x05\x08\x61\x73\x73\x65\x72\x74\x5f\x30\x00\x06\x08\x61\x73\x73\x65\x72\x74\x5f\x31\x00\x07\x08\x61\x73\x73\x65\x72\x74\x5f\x32\x00\x08\x08\x61\x73\x73\x65\x72\x74\x5f\x33\x00\x09\x0a\xd3\x01\x0a\x07\x00\x43\x00\x00\xc0\x7f\x0b\x07\x00\x43\x34\x12\x80\x7f\x0b\x04\x00\x20\x00\x0b\x0b\x00\x44\x00\x00\x00\x00\x00\x00\xf8\x7f\x0b\x0b\x00\x44\x34\x12\x00\x00\x00\x00\xf0\x7f\x0b\x04\x00\x20\x00\x0b\x20\x00\x02\x40\x43\x00\x00\xc0\xff\x10\x02\xbc\x41\xff\xff\xff\xff\x07\x71\x41\x80\x80\x80\xfe\x07\x46\x45\x0d\x00\x0f\x0b\x00\x0b\x20\x00\x02\x40\x43\x34\x12\x80\x7f\x10\x02\xbc\x41\x80\x80\x80\xfe\x07\x71\x41\x80\x80\x80\xfe\x07\x46\x45\x0d\x00\x0f\x0b\x00\x0b\x2e\x00\x02\x40\x44\x00\x00\x00\x00\x00\x00\xf8\xff\x10\x05\xbd\x42\xff\xff\xff\xff\xff\xff\xff\xff\xff\x00\x83\x42\x80\x80\x80\x80\x80\x80\x80\xfc\xff\x00\x51\x45\x0d\x00\x0f\x0b\x00\x0b\x2e\x00\x02\x40\x44\x34\x12\x00\x00\x00\x00\xf0\x7f\x10\x05\xbd\x42\x80\x80\x80\x80\x80\x80\x80\xfc\xff\x00\x83\x42\x80\x80\x80\x80\x80\x80\x80\xfc\xff\x00\x51\x45\x0d\x00\x0f\x0b\x00\x0b"); +assert_return_canonical_nan(() => $$.exports["f32_nan"]()); +assert_return_arithmetic_nan(() => $$.exports["f32_nan_with_tag"]()); +assert_return_canonical_nan(() => $$.exports["f64_nan"]()); +assert_return_arithmetic_nan(() => $$.exports["f64_nan_with_tag"]()); assert_return(() => $$.exports["assert_0"]()); +assert_return(() => $$.exports["assert_1"]()); +assert_return(() => $$.exports["assert_2"]()); +assert_return(() => $$.exports["assert_3"]()); ;;; STDOUT ;;) diff --git a/test/gen-spec-prefix.js b/test/gen-spec-prefix.js index 36692dc0..ed68c84d 100644 --- a/test/gen-spec-prefix.js +++ b/test/gen-spec-prefix.js @@ -83,8 +83,19 @@ function assert_return(action, expected) { }; } -function assert_return_nan(action) { +function assert_return_canonical_nan(action) { let actual = action(); + // Note that JS can't reliably distinguish different NaN values, + // so there's no good way to test that it's a canonical NaN. + if (!Number.isNaN(actual)) { + throw new Error("Wasm return value NaN expected, got " + actual); + }; +} + +function assert_return_arithmetic_nan(action) { + let actual = action(); + // Note that JS can't reliably distinguish different NaN values, + // so there's no good way to test that it's a canonical NaN. if (!Number.isNaN(actual)) { throw new Error("Wasm return value NaN expected, got " + actual); }; diff --git a/test/parse/assert/assert-return-arithmetic-nan.txt b/test/parse/assert/assert-return-arithmetic-nan.txt new file mode 100644 index 00000000..0d135b1c --- /dev/null +++ b/test/parse/assert/assert-return-arithmetic-nan.txt @@ -0,0 +1,10 @@ +;;; FLAGS: --spec +(module + (func $foo (param f32) (result f32) + get_local 0 + f32.const 0 + f32.div) + (export "foo" (func $foo))) + +(assert_return_arithmetic_nan + (invoke "foo" (f32.const 0))) diff --git a/test/parse/assert/assertreturnnan.txt b/test/parse/assert/assert-return-canonical-nan.txt index c570d89d..d586833e 100644 --- a/test/parse/assert/assertreturnnan.txt +++ b/test/parse/assert/assert-return-canonical-nan.txt @@ -6,5 +6,5 @@ f32.div) (export "foo" (func $foo))) -(assert_return_nan +(assert_return_canonical_nan (invoke "foo" (f32.const 0))) diff --git a/test/parse/assert/bad-assert-return-arithmetic-nan-invalid-return-type.txt b/test/parse/assert/bad-assert-return-arithmetic-nan-invalid-return-type.txt new file mode 100644 index 00000000..417a8193 --- /dev/null +++ b/test/parse/assert/bad-assert-return-arithmetic-nan-invalid-return-type.txt @@ -0,0 +1,13 @@ +;;; ERROR: 1 +;;; FLAGS: --spec +(module + (func $foo (result i32) + i32.const 0) + (export "foo" (func $foo))) + +(assert_return_arithmetic_nan (invoke "foo")) +(;; STDERR ;;; +out/test/parse/assert/bad-assert-return-arithmetic-nan-invalid-return-type.txt:8:32: type mismatch at action. got i32, expected f32 or f64 +(assert_return_arithmetic_nan (invoke "foo")) + ^^^^^^ +;;; STDERR ;;) diff --git a/test/parse/assert/bad-assert-return-arithmetic-nan-too-few.txt b/test/parse/assert/bad-assert-return-arithmetic-nan-too-few.txt new file mode 100644 index 00000000..7cb624c7 --- /dev/null +++ b/test/parse/assert/bad-assert-return-arithmetic-nan-too-few.txt @@ -0,0 +1,12 @@ +;;; ERROR: 1 +;;; FLAGS: --spec +(module + (func $foo (param i32) (result f32) + f32.const 0) + (export "foo" (func $foo))) +(assert_return_arithmetic_nan (invoke "foo")) +(;; STDERR ;;; +out/test/parse/assert/bad-assert-return-arithmetic-nan-too-few.txt:7:32: too few parameters to function. got 0, expected 1 +(assert_return_arithmetic_nan (invoke "foo")) + ^^^^^^ +;;; STDERR ;;) diff --git a/test/parse/assert/bad-assert-return-arithmetic-nan-too-many.txt b/test/parse/assert/bad-assert-return-arithmetic-nan-too-many.txt new file mode 100644 index 00000000..971893b6 --- /dev/null +++ b/test/parse/assert/bad-assert-return-arithmetic-nan-too-many.txt @@ -0,0 +1,12 @@ +;;; ERROR: 1 +;;; FLAGS: --spec +(module + (func $foo (result f32) + f32.const 0) + (export "foo" (func $foo))) +(assert_return_arithmetic_nan (invoke "foo" (f32.const 0))) +(;; STDERR ;;; +out/test/parse/assert/bad-assert-return-arithmetic-nan-too-many.txt:7:32: too many parameters to function. got 1, expected 0 +(assert_return_arithmetic_nan (invoke "foo" (f32.const 0))) + ^^^^^^ +;;; STDERR ;;) diff --git a/test/parse/assert/bad-assert-return-arithmetic-nan-unknown-function.txt b/test/parse/assert/bad-assert-return-arithmetic-nan-unknown-function.txt new file mode 100644 index 00000000..e6c3956a --- /dev/null +++ b/test/parse/assert/bad-assert-return-arithmetic-nan-unknown-function.txt @@ -0,0 +1,9 @@ +;;; ERROR: 1 +;;; FLAGS: --spec +(module) +(assert_return_arithmetic_nan (invoke "foo")) +(;; STDERR ;;; +out/test/parse/assert/bad-assert-return-arithmetic-nan-unknown-function.txt:4:32: unknown function export "foo" +(assert_return_arithmetic_nan (invoke "foo")) + ^^^^^^ +;;; STDERR ;;) diff --git a/test/parse/assert/bad-assert-return-canonical-nan-invalid-return-type.txt b/test/parse/assert/bad-assert-return-canonical-nan-invalid-return-type.txt new file mode 100644 index 00000000..0daae22a --- /dev/null +++ b/test/parse/assert/bad-assert-return-canonical-nan-invalid-return-type.txt @@ -0,0 +1,13 @@ +;;; ERROR: 1 +;;; FLAGS: --spec +(module + (func $foo (result i32) + i32.const 0) + (export "foo" (func $foo))) + +(assert_return_canonical_nan (invoke "foo")) +(;; STDERR ;;; +out/test/parse/assert/bad-assert-return-canonical-nan-invalid-return-type.txt:8:31: type mismatch at action. got i32, expected f32 or f64 +(assert_return_canonical_nan (invoke "foo")) + ^^^^^^ +;;; STDERR ;;) diff --git a/test/parse/assert/bad-assert-return-canonical-nan-too-few.txt b/test/parse/assert/bad-assert-return-canonical-nan-too-few.txt new file mode 100644 index 00000000..995fab8a --- /dev/null +++ b/test/parse/assert/bad-assert-return-canonical-nan-too-few.txt @@ -0,0 +1,12 @@ +;;; ERROR: 1 +;;; FLAGS: --spec +(module + (func $foo (param i32) (result f32) + f32.const 0) + (export "foo" (func $foo))) +(assert_return_canonical_nan (invoke "foo")) +(;; STDERR ;;; +out/test/parse/assert/bad-assert-return-canonical-nan-too-few.txt:7:31: too few parameters to function. got 0, expected 1 +(assert_return_canonical_nan (invoke "foo")) + ^^^^^^ +;;; STDERR ;;) diff --git a/test/parse/assert/bad-assert-return-canonical-nan-too-many.txt b/test/parse/assert/bad-assert-return-canonical-nan-too-many.txt new file mode 100644 index 00000000..fd994e5b --- /dev/null +++ b/test/parse/assert/bad-assert-return-canonical-nan-too-many.txt @@ -0,0 +1,12 @@ +;;; ERROR: 1 +;;; FLAGS: --spec +(module + (func $foo (result f32) + f32.const 0) + (export "foo" (func $foo))) +(assert_return_canonical_nan (invoke "foo" (f32.const 0))) +(;; STDERR ;;; +out/test/parse/assert/bad-assert-return-canonical-nan-too-many.txt:7:31: too many parameters to function. got 1, expected 0 +(assert_return_canonical_nan (invoke "foo" (f32.const 0))) + ^^^^^^ +;;; STDERR ;;) diff --git a/test/parse/assert/bad-assert-return-canonical-nan-unknown-function.txt b/test/parse/assert/bad-assert-return-canonical-nan-unknown-function.txt new file mode 100644 index 00000000..5d48f729 --- /dev/null +++ b/test/parse/assert/bad-assert-return-canonical-nan-unknown-function.txt @@ -0,0 +1,9 @@ +;;; ERROR: 1 +;;; FLAGS: --spec +(module) +(assert_return_canonical_nan (invoke "foo")) +(;; STDERR ;;; +out/test/parse/assert/bad-assert-return-canonical-nan-unknown-function.txt:4:31: unknown function export "foo" +(assert_return_canonical_nan (invoke "foo")) + ^^^^^^ +;;; STDERR ;;) diff --git a/test/parse/assert/bad-assertreturnnan-invalid-return-type.txt b/test/parse/assert/bad-assertreturnnan-invalid-return-type.txt deleted file mode 100644 index 5922fab6..00000000 --- a/test/parse/assert/bad-assertreturnnan-invalid-return-type.txt +++ /dev/null @@ -1,13 +0,0 @@ -;;; ERROR: 1 -;;; FLAGS: --spec -(module - (func $foo (result i32) - i32.const 0) - (export "foo" (func $foo))) - -(assert_return_nan (invoke "foo")) -(;; STDERR ;;; -out/test/parse/assert/bad-assertreturnnan-invalid-return-type.txt:8:21: type mismatch at action. got i32, expected f32 or f64 -(assert_return_nan (invoke "foo")) - ^^^^^^ -;;; STDERR ;;) diff --git a/test/parse/assert/bad-assertreturnnan-too-few.txt b/test/parse/assert/bad-assertreturnnan-too-few.txt deleted file mode 100644 index 454b3ffc..00000000 --- a/test/parse/assert/bad-assertreturnnan-too-few.txt +++ /dev/null @@ -1,12 +0,0 @@ -;;; ERROR: 1 -;;; FLAGS: --spec -(module - (func $foo (param i32) (result f32) - f32.const 0) - (export "foo" (func $foo))) -(assert_return_nan (invoke "foo")) -(;; STDERR ;;; -out/test/parse/assert/bad-assertreturnnan-too-few.txt:7:21: too few parameters to function. got 0, expected 1 -(assert_return_nan (invoke "foo")) - ^^^^^^ -;;; STDERR ;;) diff --git a/test/parse/assert/bad-assertreturnnan-too-many.txt b/test/parse/assert/bad-assertreturnnan-too-many.txt deleted file mode 100644 index 38d765d2..00000000 --- a/test/parse/assert/bad-assertreturnnan-too-many.txt +++ /dev/null @@ -1,12 +0,0 @@ -;;; ERROR: 1 -;;; FLAGS: --spec -(module - (func $foo (result f32) - f32.const 0) - (export "foo" (func $foo))) -(assert_return_nan (invoke "foo" (f32.const 0))) -(;; STDERR ;;; -out/test/parse/assert/bad-assertreturnnan-too-many.txt:7:21: too many parameters to function. got 1, expected 0 -(assert_return_nan (invoke "foo" (f32.const 0))) - ^^^^^^ -;;; STDERR ;;) diff --git a/test/parse/assert/bad-assertreturnnan-unknown-function.txt b/test/parse/assert/bad-assertreturnnan-unknown-function.txt deleted file mode 100644 index 7964a65f..00000000 --- a/test/parse/assert/bad-assertreturnnan-unknown-function.txt +++ /dev/null @@ -1,9 +0,0 @@ -;;; ERROR: 1 -;;; FLAGS: --spec -(module) -(assert_return_nan (invoke "foo")) -(;; STDERR ;;; -out/test/parse/assert/bad-assertreturnnan-unknown-function.txt:4:21: unknown function export "foo" -(assert_return_nan (invoke "foo")) - ^^^^^^ -;;; STDERR ;;) diff --git a/test/spec/f32.txt b/test/spec/f32.txt index ab5859c0..a0a6b57c 100644 --- a/test/spec/f32.txt +++ b/test/spec/f32.txt @@ -2,5 +2,5 @@ ;;; TOOL: run-interp-spec ;;; STDIN_FILE: third_party/testsuite/f32.wast (;; STDOUT ;;; -2394/2394 tests passed. +2446/2446 tests passed. ;;; STDOUT ;;) diff --git a/test/spec/f64.txt b/test/spec/f64.txt index 6194fac3..c3a5d9a2 100644 --- a/test/spec/f64.txt +++ b/test/spec/f64.txt @@ -2,5 +2,5 @@ ;;; TOOL: run-interp-spec ;;; STDIN_FILE: third_party/testsuite/f64.wast (;; STDOUT ;;; -2394/2394 tests passed. +2462/2462 tests passed. ;;; STDOUT ;;) |