From 4f06f98771bc79889f0f162de8bfea237827bd9a Mon Sep 17 00:00:00 2001 From: Josh Wolfe Date: Sat, 30 Dec 2017 13:50:31 -0700 Subject: [PATCH] Infix operator ToNumeric coercion tests for BigInt operands --- .../expressions/addition/bigint-errors.js | 62 ++++ .../addition/bigint-toprimitive.js | 308 ++++++++++++++++ .../addition/bigint-wrapped-values.js | 40 ++ .../expressions/bitwise-and/bigint-errors.js | 62 ++++ .../bitwise-and/bigint-toprimitive.js | 308 ++++++++++++++++ .../bitwise-and/bigint-wrapped-values.js | 40 ++ .../expressions/bitwise-or/bigint-errors.js | 62 ++++ .../bitwise-or/bigint-toprimitive.js | 308 ++++++++++++++++ .../bitwise-or/bigint-wrapped-values.js | 40 ++ .../expressions/bitwise-xor/bigint-errors.js | 62 ++++ .../bitwise-xor/bigint-toprimitive.js | 308 ++++++++++++++++ .../bitwise-xor/bigint-wrapped-values.js | 40 ++ .../expressions/division/bigint-errors.js | 62 ++++ .../division/bigint-toprimitive.js | 308 ++++++++++++++++ .../division/bigint-wrapped-values.js | 40 ++ .../exponentiation/bigint-errors.js | 62 ++++ .../exponentiation/bigint-toprimitive.js | 308 ++++++++++++++++ .../exponentiation/bigint-wrapped-values.js | 40 ++ .../expressions/left-shift/bigint-errors.js | 62 ++++ .../left-shift/bigint-toprimitive.js | 308 ++++++++++++++++ .../left-shift/bigint-wrapped-values.js | 40 ++ .../expressions/modulus/bigint-errors.js | 62 ++++ .../expressions/modulus/bigint-toprimitive.js | 308 ++++++++++++++++ .../modulus/bigint-wrapped-values.js | 40 ++ .../multiplication/bigint-errors.js | 62 ++++ .../multiplication/bigint-toprimitive.js | 308 ++++++++++++++++ .../multiplication/bigint-wrapped-values.js | 40 ++ .../expressions/right-shift/bigint-errors.js | 62 ++++ .../right-shift/bigint-toprimitive.js | 308 ++++++++++++++++ .../right-shift/bigint-wrapped-values.js | 40 ++ .../expressions/subtraction/bigint-errors.js | 62 ++++ .../subtraction/bigint-toprimitive.js | 308 ++++++++++++++++ .../subtraction/bigint-wrapped-values.js | 40 ++ .../unsigned-right-shift/bigint-errors.js | 63 ++++ .../bigint-toprimitive.js | 349 ++++++++++++++++++ .../bigint-wrapped-values.js | 57 +++ 36 files changed, 4979 insertions(+) create mode 100644 test/language/expressions/addition/bigint-errors.js create mode 100644 test/language/expressions/addition/bigint-toprimitive.js create mode 100644 test/language/expressions/addition/bigint-wrapped-values.js create mode 100644 test/language/expressions/bitwise-and/bigint-errors.js create mode 100644 test/language/expressions/bitwise-and/bigint-toprimitive.js create mode 100644 test/language/expressions/bitwise-and/bigint-wrapped-values.js create mode 100644 test/language/expressions/bitwise-or/bigint-errors.js create mode 100644 test/language/expressions/bitwise-or/bigint-toprimitive.js create mode 100644 test/language/expressions/bitwise-or/bigint-wrapped-values.js create mode 100644 test/language/expressions/bitwise-xor/bigint-errors.js create mode 100644 test/language/expressions/bitwise-xor/bigint-toprimitive.js create mode 100644 test/language/expressions/bitwise-xor/bigint-wrapped-values.js create mode 100644 test/language/expressions/division/bigint-errors.js create mode 100644 test/language/expressions/division/bigint-toprimitive.js create mode 100644 test/language/expressions/division/bigint-wrapped-values.js create mode 100644 test/language/expressions/exponentiation/bigint-errors.js create mode 100644 test/language/expressions/exponentiation/bigint-toprimitive.js create mode 100644 test/language/expressions/exponentiation/bigint-wrapped-values.js create mode 100644 test/language/expressions/left-shift/bigint-errors.js create mode 100644 test/language/expressions/left-shift/bigint-toprimitive.js create mode 100644 test/language/expressions/left-shift/bigint-wrapped-values.js create mode 100644 test/language/expressions/modulus/bigint-errors.js create mode 100644 test/language/expressions/modulus/bigint-toprimitive.js create mode 100644 test/language/expressions/modulus/bigint-wrapped-values.js create mode 100644 test/language/expressions/multiplication/bigint-errors.js create mode 100644 test/language/expressions/multiplication/bigint-toprimitive.js create mode 100644 test/language/expressions/multiplication/bigint-wrapped-values.js create mode 100644 test/language/expressions/right-shift/bigint-errors.js create mode 100644 test/language/expressions/right-shift/bigint-toprimitive.js create mode 100644 test/language/expressions/right-shift/bigint-wrapped-values.js create mode 100644 test/language/expressions/subtraction/bigint-errors.js create mode 100644 test/language/expressions/subtraction/bigint-toprimitive.js create mode 100644 test/language/expressions/subtraction/bigint-wrapped-values.js create mode 100644 test/language/expressions/unsigned-right-shift/bigint-errors.js create mode 100644 test/language/expressions/unsigned-right-shift/bigint-toprimitive.js create mode 100644 test/language/expressions/unsigned-right-shift/bigint-wrapped-values.js diff --git a/test/language/expressions/addition/bigint-errors.js b/test/language/expressions/addition/bigint-errors.js new file mode 100644 index 0000000000..7edc78a7bb --- /dev/null +++ b/test/language/expressions/addition/bigint-errors.js @@ -0,0 +1,62 @@ +// Copyright (C) 2017 Josh Wolfe. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +description: addition operator ToNumeric with BigInt operands +esid: sec-addition-operator-plus-runtime-semantics-evaluation +features: [BigInt, Symbol, Symbol.toPrimitive, computed-property-names] +---*/ + +assert.throws(TypeError, function() { + Symbol("1") + 0n; +}, "ToBigInt: Symbol => TypeError"); +assert.throws(TypeError, function() { + 0n + Symbol("1"); +}, "ToBigInt: Symbol => TypeError"); +assert.throws(TypeError, function() { + Object(Symbol("1")) + 0n; +}, "ToBigInt: unbox object with internal slot => Symbol => TypeError"); +assert.throws(TypeError, function() { + 0n + Object(Symbol("1")); +}, "ToBigInt: unbox object with internal slot => Symbol => TypeError"); +assert.throws(TypeError, function() { + ({ + [Symbol.toPrimitive]: function() { + return Symbol("1"); + } + }) + 0n; +}, "ToBigInt: @@toPrimitive => Symbol => TypeError"); +assert.throws(TypeError, function() { + 0n + { + [Symbol.toPrimitive]: function() { + return Symbol("1"); + } + }; +}, "ToBigInt: @@toPrimitive => Symbol => TypeError"); +assert.throws(TypeError, function() { + ({ + valueOf: function() { + return Symbol("1"); + } + }) + 0n; +}, "ToBigInt: valueOf => Symbol => TypeError"); +assert.throws(TypeError, function() { + 0n + { + valueOf: function() { + return Symbol("1"); + } + }; +}, "ToBigInt: valueOf => Symbol => TypeError"); +assert.throws(TypeError, function() { + ({ + toString: function() { + return Symbol("1"); + } + }) + 0n; +}, "ToBigInt: toString => Symbol => TypeError"); +assert.throws(TypeError, function() { + 0n + { + toString: function() { + return Symbol("1"); + } + }; +}, "ToBigInt: toString => Symbol => TypeError"); diff --git a/test/language/expressions/addition/bigint-toprimitive.js b/test/language/expressions/addition/bigint-toprimitive.js new file mode 100644 index 0000000000..771b50843b --- /dev/null +++ b/test/language/expressions/addition/bigint-toprimitive.js @@ -0,0 +1,308 @@ +// Copyright (C) 2017 Josh Wolfe. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +description: addition operator ToNumeric with BigInt operands +esid: sec-addition-operator-plus-runtime-semantics-evaluation +features: [BigInt, Symbol.toPrimitive, computed-property-names] +---*/ + +function err() { + throw new Test262Error(); +} + +function MyError() {} + +assert.sameValue(({ + [Symbol.toPrimitive]: function() { + return 2n; + }, + valueOf: err, + toString: err +}) + 1n, 3n, "ToPrimitive: @@toPrimitive takes precedence"); +assert.sameValue(1n + { + [Symbol.toPrimitive]: function() { + return 2n; + }, + valueOf: err, + toString: err +}, 3n, "ToPrimitive: @@toPrimitive takes precedence"); +assert.sameValue(({ + valueOf: function() { + return 2n; + }, + toString: err +}) + 1n, 3n, "ToPrimitive: valueOf takes precedence over toString"); +assert.sameValue(1n + { + valueOf: function() { + return 2n; + }, + toString: err +}, 3n, "ToPrimitive: valueOf takes precedence over toString"); +assert.sameValue(({ + toString: function() { + return 2n; + } +}) + 1n, 3n, "ToPrimitive: toString with no valueOf"); +assert.sameValue(1n + { + toString: function() { + return 2n; + } +}, 3n, "ToPrimitive: toString with no valueOf"); +assert.sameValue(({ + [Symbol.toPrimitive]: undefined, + valueOf: function() { + return 2n; + } +}) + 1n, 3n, "ToPrimitive: skip @@toPrimitive when it's undefined"); +assert.sameValue(1n + { + [Symbol.toPrimitive]: undefined, + valueOf: function() { + return 2n; + } +}, 3n, "ToPrimitive: skip @@toPrimitive when it's undefined"); +assert.sameValue(({ + [Symbol.toPrimitive]: null, + valueOf: function() { + return 2n; + } +}) + 1n, 3n, "ToPrimitive: skip @@toPrimitive when it's null"); +assert.sameValue(1n + { + [Symbol.toPrimitive]: null, + valueOf: function() { + return 2n; + } +}, 3n, "ToPrimitive: skip @@toPrimitive when it's null"); +assert.sameValue(({ + valueOf: null, + toString: function() { + return 2n; + } +}) + 1n, 3n, "ToPrimitive: skip valueOf when it's not callable"); +assert.sameValue(1n + { + valueOf: null, + toString: function() { + return 2n; + } +}, 3n, "ToPrimitive: skip valueOf when it's not callable"); +assert.sameValue(({ + valueOf: 1, + toString: function() { + return 2n; + } +}) + 1n, 3n, "ToPrimitive: skip valueOf when it's not callable"); +assert.sameValue(1n + { + valueOf: 1, + toString: function() { + return 2n; + } +}, 3n, "ToPrimitive: skip valueOf when it's not callable"); +assert.sameValue(({ + valueOf: {}, + toString: function() { + return 2n; + } +}) + 1n, 3n, "ToPrimitive: skip valueOf when it's not callable"); +assert.sameValue(1n + { + valueOf: {}, + toString: function() { + return 2n; + } +}, 3n, "ToPrimitive: skip valueOf when it's not callable"); +assert.sameValue(({ + valueOf: function() { + return {}; + }, + toString: function() { + return 2n; + } +}) + 1n, 3n, "ToPrimitive: skip valueOf when it returns an object"); +assert.sameValue(1n + { + valueOf: function() { + return {}; + }, + toString: function() { + return 2n; + } +}, 3n, "ToPrimitive: skip valueOf when it returns an object"); +assert.sameValue(({ + valueOf: function() { + return Object(12345); + }, + toString: function() { + return 2n; + } +}) + 1n, 3n, "ToPrimitive: skip valueOf when it returns an object"); +assert.sameValue(1n + { + valueOf: function() { + return Object(12345); + }, + toString: function() { + return 2n; + } +}, 3n, "ToPrimitive: skip valueOf when it returns an object"); +assert.throws(TypeError, function() { + ({ + [Symbol.toPrimitive]: 1 + }) + 0n; +}, "ToPrimitive: throw when @@toPrimitive is not callable"); +assert.throws(TypeError, function() { + 0n + { + [Symbol.toPrimitive]: 1 + }; +}, "ToPrimitive: throw when @@toPrimitive is not callable"); +assert.throws(TypeError, function() { + ({ + [Symbol.toPrimitive]: {} + }) + 0n; +}, "ToPrimitive: throw when @@toPrimitive is not callable"); +assert.throws(TypeError, function() { + 0n + { + [Symbol.toPrimitive]: {} + }; +}, "ToPrimitive: throw when @@toPrimitive is not callable"); +assert.throws(TypeError, function() { + ({ + [Symbol.toPrimitive]: function() { + return Object(1); + } + }) + 0n; +}, "ToPrimitive: throw when @@toPrimitive returns an object"); +assert.throws(TypeError, function() { + 0n + { + [Symbol.toPrimitive]: function() { + return Object(1); + } + }; +}, "ToPrimitive: throw when @@toPrimitive returns an object"); +assert.throws(TypeError, function() { + ({ + [Symbol.toPrimitive]: function() { + return {}; + } + }) + 0n; +}, "ToPrimitive: throw when @@toPrimitive returns an object"); +assert.throws(TypeError, function() { + 0n + { + [Symbol.toPrimitive]: function() { + return {}; + } + }; +}, "ToPrimitive: throw when @@toPrimitive returns an object"); +assert.throws(MyError, function() { + ({ + [Symbol.toPrimitive]: function() { + throw new MyError(); + } + }) + 0n; +}, "ToPrimitive: propagate errors from @@toPrimitive"); +assert.throws(MyError, function() { + 0n + { + [Symbol.toPrimitive]: function() { + throw new MyError(); + } + }; +}, "ToPrimitive: propagate errors from @@toPrimitive"); +assert.throws(MyError, function() { + ({ + valueOf: function() { + throw new MyError(); + } + }) + 0n; +}, "ToPrimitive: propagate errors from valueOf"); +assert.throws(MyError, function() { + 0n + { + valueOf: function() { + throw new MyError(); + } + }; +}, "ToPrimitive: propagate errors from valueOf"); +assert.throws(MyError, function() { + ({ + toString: function() { + throw new MyError(); + } + }) + 0n; +}, "ToPrimitive: propagate errors from toString"); +assert.throws(MyError, function() { + 0n + { + toString: function() { + throw new MyError(); + } + }; +}, "ToPrimitive: propagate errors from toString"); +assert.throws(TypeError, function() { + ({ + valueOf: null, + toString: null + }) + 0n; +}, "ToPrimitive: throw when skipping both valueOf and toString"); +assert.throws(TypeError, function() { + 0n + { + valueOf: null, + toString: null + }; +}, "ToPrimitive: throw when skipping both valueOf and toString"); +assert.throws(TypeError, function() { + ({ + valueOf: 1, + toString: 1 + }) + 0n; +}, "ToPrimitive: throw when skipping both valueOf and toString"); +assert.throws(TypeError, function() { + 0n + { + valueOf: 1, + toString: 1 + }; +}, "ToPrimitive: throw when skipping both valueOf and toString"); +assert.throws(TypeError, function() { + ({ + valueOf: {}, + toString: {} + }) + 0n; +}, "ToPrimitive: throw when skipping both valueOf and toString"); +assert.throws(TypeError, function() { + 0n + { + valueOf: {}, + toString: {} + }; +}, "ToPrimitive: throw when skipping both valueOf and toString"); +assert.throws(TypeError, function() { + ({ + valueOf: function() { + return Object(1); + }, + toString: function() { + return Object(1); + } + }) + 0n; +}, "ToPrimitive: throw when skipping both valueOf and toString"); +assert.throws(TypeError, function() { + 0n + { + valueOf: function() { + return Object(1); + }, + toString: function() { + return Object(1); + } + }; +}, "ToPrimitive: throw when skipping both valueOf and toString"); +assert.throws(TypeError, function() { + ({ + valueOf: function() { + return {}; + }, + toString: function() { + return {}; + } + }) + 0n; +}, "ToPrimitive: throw when skipping both valueOf and toString"); +assert.throws(TypeError, function() { + 0n + { + valueOf: function() { + return {}; + }, + toString: function() { + return {}; + } + }; +}, "ToPrimitive: throw when skipping both valueOf and toString"); diff --git a/test/language/expressions/addition/bigint-wrapped-values.js b/test/language/expressions/addition/bigint-wrapped-values.js new file mode 100644 index 0000000000..a69e10b585 --- /dev/null +++ b/test/language/expressions/addition/bigint-wrapped-values.js @@ -0,0 +1,40 @@ +// Copyright (C) 2017 Josh Wolfe. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +description: addition operator ToNumeric with BigInt operands +esid: sec-addition-operator-plus-runtime-semantics-evaluation +features: [BigInt, Symbol.toPrimitive, computed-property-names] +---*/ + +assert.sameValue(Object(2n) + 1n, 3n, "ToPrimitive: unbox object with internal slot"); +assert.sameValue(1n + Object(2n), 3n, "ToPrimitive: unbox object with internal slot"); +assert.sameValue(({ + [Symbol.toPrimitive]: function() { + return 2n; + } +}) + 1n, 3n, "ToPrimitive: @@toPrimitive"); +assert.sameValue(1n + { + [Symbol.toPrimitive]: function() { + return 2n; + } +}, 3n, "ToPrimitive: @@toPrimitive"); +assert.sameValue(({ + valueOf: function() { + return 2n; + } +}) + 1n, 3n, "ToPrimitive: valueOf"); +assert.sameValue(1n + { + valueOf: function() { + return 2n; + } +}, 3n, "ToPrimitive: valueOf"); +assert.sameValue(({ + toString: function() { + return 2n; + } +}) + 1n, 3n, "ToPrimitive: toString"); +assert.sameValue(1n + { + toString: function() { + return 2n; + } +}, 3n, "ToPrimitive: toString"); diff --git a/test/language/expressions/bitwise-and/bigint-errors.js b/test/language/expressions/bitwise-and/bigint-errors.js new file mode 100644 index 0000000000..0f57b1431c --- /dev/null +++ b/test/language/expressions/bitwise-and/bigint-errors.js @@ -0,0 +1,62 @@ +// Copyright (C) 2017 Josh Wolfe. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +description: bitwise-and operator ToNumeric with BigInt operands +esid: sec-binary-bitwise-operators-runtime-semantics-evaluation +features: [BigInt, Symbol, Symbol.toPrimitive, computed-property-names] +---*/ + +assert.throws(TypeError, function() { + Symbol("1") & 0n; +}, "ToBigInt: Symbol => TypeError"); +assert.throws(TypeError, function() { + 0n & Symbol("1"); +}, "ToBigInt: Symbol => TypeError"); +assert.throws(TypeError, function() { + Object(Symbol("1")) & 0n; +}, "ToBigInt: unbox object with internal slot => Symbol => TypeError"); +assert.throws(TypeError, function() { + 0n & Object(Symbol("1")); +}, "ToBigInt: unbox object with internal slot => Symbol => TypeError"); +assert.throws(TypeError, function() { + ({ + [Symbol.toPrimitive]: function() { + return Symbol("1"); + } + }) & 0n; +}, "ToBigInt: @@toPrimitive => Symbol => TypeError"); +assert.throws(TypeError, function() { + 0n & { + [Symbol.toPrimitive]: function() { + return Symbol("1"); + } + }; +}, "ToBigInt: @@toPrimitive => Symbol => TypeError"); +assert.throws(TypeError, function() { + ({ + valueOf: function() { + return Symbol("1"); + } + }) & 0n; +}, "ToBigInt: valueOf => Symbol => TypeError"); +assert.throws(TypeError, function() { + 0n & { + valueOf: function() { + return Symbol("1"); + } + }; +}, "ToBigInt: valueOf => Symbol => TypeError"); +assert.throws(TypeError, function() { + ({ + toString: function() { + return Symbol("1"); + } + }) & 0n; +}, "ToBigInt: toString => Symbol => TypeError"); +assert.throws(TypeError, function() { + 0n & { + toString: function() { + return Symbol("1"); + } + }; +}, "ToBigInt: toString => Symbol => TypeError"); diff --git a/test/language/expressions/bitwise-and/bigint-toprimitive.js b/test/language/expressions/bitwise-and/bigint-toprimitive.js new file mode 100644 index 0000000000..88ed17b6c1 --- /dev/null +++ b/test/language/expressions/bitwise-and/bigint-toprimitive.js @@ -0,0 +1,308 @@ +// Copyright (C) 2017 Josh Wolfe. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +description: bitwise-and operator ToNumeric with BigInt operands +esid: sec-binary-bitwise-operators-runtime-semantics-evaluation +features: [BigInt, Symbol.toPrimitive, computed-property-names] +---*/ + +function err() { + throw new Test262Error(); +} + +function MyError() {} + +assert.sameValue(({ + [Symbol.toPrimitive]: function() { + return 2n; + }, + valueOf: err, + toString: err +}) & 3n, 2n, "ToPrimitive: @@toPrimitive takes precedence"); +assert.sameValue(3n & { + [Symbol.toPrimitive]: function() { + return 2n; + }, + valueOf: err, + toString: err +}, 2n, "ToPrimitive: @@toPrimitive takes precedence"); +assert.sameValue(({ + valueOf: function() { + return 2n; + }, + toString: err +}) & 3n, 2n, "ToPrimitive: valueOf takes precedence over toString"); +assert.sameValue(3n & { + valueOf: function() { + return 2n; + }, + toString: err +}, 2n, "ToPrimitive: valueOf takes precedence over toString"); +assert.sameValue(({ + toString: function() { + return 2n; + } +}) & 3n, 2n, "ToPrimitive: toString with no valueOf"); +assert.sameValue(3n & { + toString: function() { + return 2n; + } +}, 2n, "ToPrimitive: toString with no valueOf"); +assert.sameValue(({ + [Symbol.toPrimitive]: undefined, + valueOf: function() { + return 2n; + } +}) & 3n, 2n, "ToPrimitive: skip @@toPrimitive when it's undefined"); +assert.sameValue(3n & { + [Symbol.toPrimitive]: undefined, + valueOf: function() { + return 2n; + } +}, 2n, "ToPrimitive: skip @@toPrimitive when it's undefined"); +assert.sameValue(({ + [Symbol.toPrimitive]: null, + valueOf: function() { + return 2n; + } +}) & 3n, 2n, "ToPrimitive: skip @@toPrimitive when it's null"); +assert.sameValue(3n & { + [Symbol.toPrimitive]: null, + valueOf: function() { + return 2n; + } +}, 2n, "ToPrimitive: skip @@toPrimitive when it's null"); +assert.sameValue(({ + valueOf: null, + toString: function() { + return 2n; + } +}) & 3n, 2n, "ToPrimitive: skip valueOf when it's not callable"); +assert.sameValue(3n & { + valueOf: null, + toString: function() { + return 2n; + } +}, 2n, "ToPrimitive: skip valueOf when it's not callable"); +assert.sameValue(({ + valueOf: 1, + toString: function() { + return 2n; + } +}) & 3n, 2n, "ToPrimitive: skip valueOf when it's not callable"); +assert.sameValue(3n & { + valueOf: 1, + toString: function() { + return 2n; + } +}, 2n, "ToPrimitive: skip valueOf when it's not callable"); +assert.sameValue(({ + valueOf: {}, + toString: function() { + return 2n; + } +}) & 3n, 2n, "ToPrimitive: skip valueOf when it's not callable"); +assert.sameValue(3n & { + valueOf: {}, + toString: function() { + return 2n; + } +}, 2n, "ToPrimitive: skip valueOf when it's not callable"); +assert.sameValue(({ + valueOf: function() { + return {}; + }, + toString: function() { + return 2n; + } +}) & 3n, 2n, "ToPrimitive: skip valueOf when it returns an object"); +assert.sameValue(3n & { + valueOf: function() { + return {}; + }, + toString: function() { + return 2n; + } +}, 2n, "ToPrimitive: skip valueOf when it returns an object"); +assert.sameValue(({ + valueOf: function() { + return Object(12345); + }, + toString: function() { + return 2n; + } +}) & 3n, 2n, "ToPrimitive: skip valueOf when it returns an object"); +assert.sameValue(3n & { + valueOf: function() { + return Object(12345); + }, + toString: function() { + return 2n; + } +}, 2n, "ToPrimitive: skip valueOf when it returns an object"); +assert.throws(TypeError, function() { + ({ + [Symbol.toPrimitive]: 1 + }) & 0n; +}, "ToPrimitive: throw when @@toPrimitive is not callable"); +assert.throws(TypeError, function() { + 0n & { + [Symbol.toPrimitive]: 1 + }; +}, "ToPrimitive: throw when @@toPrimitive is not callable"); +assert.throws(TypeError, function() { + ({ + [Symbol.toPrimitive]: {} + }) & 0n; +}, "ToPrimitive: throw when @@toPrimitive is not callable"); +assert.throws(TypeError, function() { + 0n & { + [Symbol.toPrimitive]: {} + }; +}, "ToPrimitive: throw when @@toPrimitive is not callable"); +assert.throws(TypeError, function() { + ({ + [Symbol.toPrimitive]: function() { + return Object(1); + } + }) & 0n; +}, "ToPrimitive: throw when @@toPrimitive returns an object"); +assert.throws(TypeError, function() { + 0n & { + [Symbol.toPrimitive]: function() { + return Object(1); + } + }; +}, "ToPrimitive: throw when @@toPrimitive returns an object"); +assert.throws(TypeError, function() { + ({ + [Symbol.toPrimitive]: function() { + return {}; + } + }) & 0n; +}, "ToPrimitive: throw when @@toPrimitive returns an object"); +assert.throws(TypeError, function() { + 0n & { + [Symbol.toPrimitive]: function() { + return {}; + } + }; +}, "ToPrimitive: throw when @@toPrimitive returns an object"); +assert.throws(MyError, function() { + ({ + [Symbol.toPrimitive]: function() { + throw new MyError(); + } + }) & 0n; +}, "ToPrimitive: propagate errors from @@toPrimitive"); +assert.throws(MyError, function() { + 0n & { + [Symbol.toPrimitive]: function() { + throw new MyError(); + } + }; +}, "ToPrimitive: propagate errors from @@toPrimitive"); +assert.throws(MyError, function() { + ({ + valueOf: function() { + throw new MyError(); + } + }) & 0n; +}, "ToPrimitive: propagate errors from valueOf"); +assert.throws(MyError, function() { + 0n & { + valueOf: function() { + throw new MyError(); + } + }; +}, "ToPrimitive: propagate errors from valueOf"); +assert.throws(MyError, function() { + ({ + toString: function() { + throw new MyError(); + } + }) & 0n; +}, "ToPrimitive: propagate errors from toString"); +assert.throws(MyError, function() { + 0n & { + toString: function() { + throw new MyError(); + } + }; +}, "ToPrimitive: propagate errors from toString"); +assert.throws(TypeError, function() { + ({ + valueOf: null, + toString: null + }) & 0n; +}, "ToPrimitive: throw when skipping both valueOf and toString"); +assert.throws(TypeError, function() { + 0n & { + valueOf: null, + toString: null + }; +}, "ToPrimitive: throw when skipping both valueOf and toString"); +assert.throws(TypeError, function() { + ({ + valueOf: 1, + toString: 1 + }) & 0n; +}, "ToPrimitive: throw when skipping both valueOf and toString"); +assert.throws(TypeError, function() { + 0n & { + valueOf: 1, + toString: 1 + }; +}, "ToPrimitive: throw when skipping both valueOf and toString"); +assert.throws(TypeError, function() { + ({ + valueOf: {}, + toString: {} + }) & 0n; +}, "ToPrimitive: throw when skipping both valueOf and toString"); +assert.throws(TypeError, function() { + 0n & { + valueOf: {}, + toString: {} + }; +}, "ToPrimitive: throw when skipping both valueOf and toString"); +assert.throws(TypeError, function() { + ({ + valueOf: function() { + return Object(1); + }, + toString: function() { + return Object(1); + } + }) & 0n; +}, "ToPrimitive: throw when skipping both valueOf and toString"); +assert.throws(TypeError, function() { + 0n & { + valueOf: function() { + return Object(1); + }, + toString: function() { + return Object(1); + } + }; +}, "ToPrimitive: throw when skipping both valueOf and toString"); +assert.throws(TypeError, function() { + ({ + valueOf: function() { + return {}; + }, + toString: function() { + return {}; + } + }) & 0n; +}, "ToPrimitive: throw when skipping both valueOf and toString"); +assert.throws(TypeError, function() { + 0n & { + valueOf: function() { + return {}; + }, + toString: function() { + return {}; + } + }; +}, "ToPrimitive: throw when skipping both valueOf and toString"); diff --git a/test/language/expressions/bitwise-and/bigint-wrapped-values.js b/test/language/expressions/bitwise-and/bigint-wrapped-values.js new file mode 100644 index 0000000000..381ca6158f --- /dev/null +++ b/test/language/expressions/bitwise-and/bigint-wrapped-values.js @@ -0,0 +1,40 @@ +// Copyright (C) 2017 Josh Wolfe. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +description: bitwise-and operator ToNumeric with BigInt operands +esid: sec-binary-bitwise-operators-runtime-semantics-evaluation +features: [BigInt, Symbol.toPrimitive, computed-property-names] +---*/ + +assert.sameValue(Object(2n) & 3n, 2n, "ToPrimitive: unbox object with internal slot"); +assert.sameValue(3n & Object(2n), 2n, "ToPrimitive: unbox object with internal slot"); +assert.sameValue(({ + [Symbol.toPrimitive]: function() { + return 2n; + } +}) & 3n, 2n, "ToPrimitive: @@toPrimitive"); +assert.sameValue(3n & { + [Symbol.toPrimitive]: function() { + return 2n; + } +}, 2n, "ToPrimitive: @@toPrimitive"); +assert.sameValue(({ + valueOf: function() { + return 2n; + } +}) & 3n, 2n, "ToPrimitive: valueOf"); +assert.sameValue(3n & { + valueOf: function() { + return 2n; + } +}, 2n, "ToPrimitive: valueOf"); +assert.sameValue(({ + toString: function() { + return 2n; + } +}) & 3n, 2n, "ToPrimitive: toString"); +assert.sameValue(3n & { + toString: function() { + return 2n; + } +}, 2n, "ToPrimitive: toString"); diff --git a/test/language/expressions/bitwise-or/bigint-errors.js b/test/language/expressions/bitwise-or/bigint-errors.js new file mode 100644 index 0000000000..339de3b06e --- /dev/null +++ b/test/language/expressions/bitwise-or/bigint-errors.js @@ -0,0 +1,62 @@ +// Copyright (C) 2017 Josh Wolfe. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +description: bitwise-or operator ToNumeric with BigInt operands +esid: sec-binary-bitwise-operators-runtime-semantics-evaluation +features: [BigInt, Symbol, Symbol.toPrimitive, computed-property-names] +---*/ + +assert.throws(TypeError, function() { + Symbol("1") | 0n; +}, "ToBigInt: Symbol => TypeError"); +assert.throws(TypeError, function() { + 0n | Symbol("1"); +}, "ToBigInt: Symbol => TypeError"); +assert.throws(TypeError, function() { + Object(Symbol("1")) | 0n; +}, "ToBigInt: unbox object with internal slot => Symbol => TypeError"); +assert.throws(TypeError, function() { + 0n | Object(Symbol("1")); +}, "ToBigInt: unbox object with internal slot => Symbol => TypeError"); +assert.throws(TypeError, function() { + ({ + [Symbol.toPrimitive]: function() { + return Symbol("1"); + } + }) | 0n; +}, "ToBigInt: @@toPrimitive => Symbol => TypeError"); +assert.throws(TypeError, function() { + 0n | { + [Symbol.toPrimitive]: function() { + return Symbol("1"); + } + }; +}, "ToBigInt: @@toPrimitive => Symbol => TypeError"); +assert.throws(TypeError, function() { + ({ + valueOf: function() { + return Symbol("1"); + } + }) | 0n; +}, "ToBigInt: valueOf => Symbol => TypeError"); +assert.throws(TypeError, function() { + 0n | { + valueOf: function() { + return Symbol("1"); + } + }; +}, "ToBigInt: valueOf => Symbol => TypeError"); +assert.throws(TypeError, function() { + ({ + toString: function() { + return Symbol("1"); + } + }) | 0n; +}, "ToBigInt: toString => Symbol => TypeError"); +assert.throws(TypeError, function() { + 0n | { + toString: function() { + return Symbol("1"); + } + }; +}, "ToBigInt: toString => Symbol => TypeError"); diff --git a/test/language/expressions/bitwise-or/bigint-toprimitive.js b/test/language/expressions/bitwise-or/bigint-toprimitive.js new file mode 100644 index 0000000000..644395b8ca --- /dev/null +++ b/test/language/expressions/bitwise-or/bigint-toprimitive.js @@ -0,0 +1,308 @@ +// Copyright (C) 2017 Josh Wolfe. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +description: bitwise-or operator ToNumeric with BigInt operands +esid: sec-binary-bitwise-operators-runtime-semantics-evaluation +features: [BigInt, Symbol.toPrimitive, computed-property-names] +---*/ + +function err() { + throw new Test262Error(); +} + +function MyError() {} + +assert.sameValue(({ + [Symbol.toPrimitive]: function() { + return 2n; + }, + valueOf: err, + toString: err +}) | 1n, 3n, "ToPrimitive: @@toPrimitive takes precedence"); +assert.sameValue(1n | { + [Symbol.toPrimitive]: function() { + return 2n; + }, + valueOf: err, + toString: err +}, 3n, "ToPrimitive: @@toPrimitive takes precedence"); +assert.sameValue(({ + valueOf: function() { + return 2n; + }, + toString: err +}) | 1n, 3n, "ToPrimitive: valueOf takes precedence over toString"); +assert.sameValue(1n | { + valueOf: function() { + return 2n; + }, + toString: err +}, 3n, "ToPrimitive: valueOf takes precedence over toString"); +assert.sameValue(({ + toString: function() { + return 2n; + } +}) | 1n, 3n, "ToPrimitive: toString with no valueOf"); +assert.sameValue(1n | { + toString: function() { + return 2n; + } +}, 3n, "ToPrimitive: toString with no valueOf"); +assert.sameValue(({ + [Symbol.toPrimitive]: undefined, + valueOf: function() { + return 2n; + } +}) | 1n, 3n, "ToPrimitive: skip @@toPrimitive when it's undefined"); +assert.sameValue(1n | { + [Symbol.toPrimitive]: undefined, + valueOf: function() { + return 2n; + } +}, 3n, "ToPrimitive: skip @@toPrimitive when it's undefined"); +assert.sameValue(({ + [Symbol.toPrimitive]: null, + valueOf: function() { + return 2n; + } +}) | 1n, 3n, "ToPrimitive: skip @@toPrimitive when it's null"); +assert.sameValue(1n | { + [Symbol.toPrimitive]: null, + valueOf: function() { + return 2n; + } +}, 3n, "ToPrimitive: skip @@toPrimitive when it's null"); +assert.sameValue(({ + valueOf: null, + toString: function() { + return 2n; + } +}) | 1n, 3n, "ToPrimitive: skip valueOf when it's not callable"); +assert.sameValue(1n | { + valueOf: null, + toString: function() { + return 2n; + } +}, 3n, "ToPrimitive: skip valueOf when it's not callable"); +assert.sameValue(({ + valueOf: 1, + toString: function() { + return 2n; + } +}) | 1n, 3n, "ToPrimitive: skip valueOf when it's not callable"); +assert.sameValue(1n | { + valueOf: 1, + toString: function() { + return 2n; + } +}, 3n, "ToPrimitive: skip valueOf when it's not callable"); +assert.sameValue(({ + valueOf: {}, + toString: function() { + return 2n; + } +}) | 1n, 3n, "ToPrimitive: skip valueOf when it's not callable"); +assert.sameValue(1n | { + valueOf: {}, + toString: function() { + return 2n; + } +}, 3n, "ToPrimitive: skip valueOf when it's not callable"); +assert.sameValue(({ + valueOf: function() { + return {}; + }, + toString: function() { + return 2n; + } +}) | 1n, 3n, "ToPrimitive: skip valueOf when it returns an object"); +assert.sameValue(1n | { + valueOf: function() { + return {}; + }, + toString: function() { + return 2n; + } +}, 3n, "ToPrimitive: skip valueOf when it returns an object"); +assert.sameValue(({ + valueOf: function() { + return Object(12345); + }, + toString: function() { + return 2n; + } +}) | 1n, 3n, "ToPrimitive: skip valueOf when it returns an object"); +assert.sameValue(1n | { + valueOf: function() { + return Object(12345); + }, + toString: function() { + return 2n; + } +}, 3n, "ToPrimitive: skip valueOf when it returns an object"); +assert.throws(TypeError, function() { + ({ + [Symbol.toPrimitive]: 1 + }) | 0n; +}, "ToPrimitive: throw when @@toPrimitive is not callable"); +assert.throws(TypeError, function() { + 0n | { + [Symbol.toPrimitive]: 1 + }; +}, "ToPrimitive: throw when @@toPrimitive is not callable"); +assert.throws(TypeError, function() { + ({ + [Symbol.toPrimitive]: {} + }) | 0n; +}, "ToPrimitive: throw when @@toPrimitive is not callable"); +assert.throws(TypeError, function() { + 0n | { + [Symbol.toPrimitive]: {} + }; +}, "ToPrimitive: throw when @@toPrimitive is not callable"); +assert.throws(TypeError, function() { + ({ + [Symbol.toPrimitive]: function() { + return Object(1); + } + }) | 0n; +}, "ToPrimitive: throw when @@toPrimitive returns an object"); +assert.throws(TypeError, function() { + 0n | { + [Symbol.toPrimitive]: function() { + return Object(1); + } + }; +}, "ToPrimitive: throw when @@toPrimitive returns an object"); +assert.throws(TypeError, function() { + ({ + [Symbol.toPrimitive]: function() { + return {}; + } + }) | 0n; +}, "ToPrimitive: throw when @@toPrimitive returns an object"); +assert.throws(TypeError, function() { + 0n | { + [Symbol.toPrimitive]: function() { + return {}; + } + }; +}, "ToPrimitive: throw when @@toPrimitive returns an object"); +assert.throws(MyError, function() { + ({ + [Symbol.toPrimitive]: function() { + throw new MyError(); + } + }) | 0n; +}, "ToPrimitive: propagate errors from @@toPrimitive"); +assert.throws(MyError, function() { + 0n | { + [Symbol.toPrimitive]: function() { + throw new MyError(); + } + }; +}, "ToPrimitive: propagate errors from @@toPrimitive"); +assert.throws(MyError, function() { + ({ + valueOf: function() { + throw new MyError(); + } + }) | 0n; +}, "ToPrimitive: propagate errors from valueOf"); +assert.throws(MyError, function() { + 0n | { + valueOf: function() { + throw new MyError(); + } + }; +}, "ToPrimitive: propagate errors from valueOf"); +assert.throws(MyError, function() { + ({ + toString: function() { + throw new MyError(); + } + }) | 0n; +}, "ToPrimitive: propagate errors from toString"); +assert.throws(MyError, function() { + 0n | { + toString: function() { + throw new MyError(); + } + }; +}, "ToPrimitive: propagate errors from toString"); +assert.throws(TypeError, function() { + ({ + valueOf: null, + toString: null + }) | 0n; +}, "ToPrimitive: throw when skipping both valueOf and toString"); +assert.throws(TypeError, function() { + 0n | { + valueOf: null, + toString: null + }; +}, "ToPrimitive: throw when skipping both valueOf and toString"); +assert.throws(TypeError, function() { + ({ + valueOf: 1, + toString: 1 + }) | 0n; +}, "ToPrimitive: throw when skipping both valueOf and toString"); +assert.throws(TypeError, function() { + 0n | { + valueOf: 1, + toString: 1 + }; +}, "ToPrimitive: throw when skipping both valueOf and toString"); +assert.throws(TypeError, function() { + ({ + valueOf: {}, + toString: {} + }) | 0n; +}, "ToPrimitive: throw when skipping both valueOf and toString"); +assert.throws(TypeError, function() { + 0n | { + valueOf: {}, + toString: {} + }; +}, "ToPrimitive: throw when skipping both valueOf and toString"); +assert.throws(TypeError, function() { + ({ + valueOf: function() { + return Object(1); + }, + toString: function() { + return Object(1); + } + }) | 0n; +}, "ToPrimitive: throw when skipping both valueOf and toString"); +assert.throws(TypeError, function() { + 0n | { + valueOf: function() { + return Object(1); + }, + toString: function() { + return Object(1); + } + }; +}, "ToPrimitive: throw when skipping both valueOf and toString"); +assert.throws(TypeError, function() { + ({ + valueOf: function() { + return {}; + }, + toString: function() { + return {}; + } + }) | 0n; +}, "ToPrimitive: throw when skipping both valueOf and toString"); +assert.throws(TypeError, function() { + 0n | { + valueOf: function() { + return {}; + }, + toString: function() { + return {}; + } + }; +}, "ToPrimitive: throw when skipping both valueOf and toString"); diff --git a/test/language/expressions/bitwise-or/bigint-wrapped-values.js b/test/language/expressions/bitwise-or/bigint-wrapped-values.js new file mode 100644 index 0000000000..687e99f9d3 --- /dev/null +++ b/test/language/expressions/bitwise-or/bigint-wrapped-values.js @@ -0,0 +1,40 @@ +// Copyright (C) 2017 Josh Wolfe. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +description: bitwise-or operator ToNumeric with BigInt operands +esid: sec-binary-bitwise-operators-runtime-semantics-evaluation +features: [BigInt, Symbol.toPrimitive, computed-property-names] +---*/ + +assert.sameValue(Object(2n) | 1n, 3n, "ToPrimitive: unbox object with internal slot"); +assert.sameValue(1n | Object(2n), 3n, "ToPrimitive: unbox object with internal slot"); +assert.sameValue(({ + [Symbol.toPrimitive]: function() { + return 2n; + } +}) | 1n, 3n, "ToPrimitive: @@toPrimitive"); +assert.sameValue(1n | { + [Symbol.toPrimitive]: function() { + return 2n; + } +}, 3n, "ToPrimitive: @@toPrimitive"); +assert.sameValue(({ + valueOf: function() { + return 2n; + } +}) | 1n, 3n, "ToPrimitive: valueOf"); +assert.sameValue(1n | { + valueOf: function() { + return 2n; + } +}, 3n, "ToPrimitive: valueOf"); +assert.sameValue(({ + toString: function() { + return 2n; + } +}) | 1n, 3n, "ToPrimitive: toString"); +assert.sameValue(1n | { + toString: function() { + return 2n; + } +}, 3n, "ToPrimitive: toString"); diff --git a/test/language/expressions/bitwise-xor/bigint-errors.js b/test/language/expressions/bitwise-xor/bigint-errors.js new file mode 100644 index 0000000000..6b3e43c458 --- /dev/null +++ b/test/language/expressions/bitwise-xor/bigint-errors.js @@ -0,0 +1,62 @@ +// Copyright (C) 2017 Josh Wolfe. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +description: bitwise-xor operator ToNumeric with BigInt operands +esid: sec-binary-bitwise-operators-runtime-semantics-evaluation +features: [BigInt, Symbol, Symbol.toPrimitive, computed-property-names] +---*/ + +assert.throws(TypeError, function() { + Symbol("1") ^ 0n; +}, "ToBigInt: Symbol => TypeError"); +assert.throws(TypeError, function() { + 0n ^ Symbol("1"); +}, "ToBigInt: Symbol => TypeError"); +assert.throws(TypeError, function() { + Object(Symbol("1")) ^ 0n; +}, "ToBigInt: unbox object with internal slot => Symbol => TypeError"); +assert.throws(TypeError, function() { + 0n ^ Object(Symbol("1")); +}, "ToBigInt: unbox object with internal slot => Symbol => TypeError"); +assert.throws(TypeError, function() { + ({ + [Symbol.toPrimitive]: function() { + return Symbol("1"); + } + }) ^ 0n; +}, "ToBigInt: @@toPrimitive => Symbol => TypeError"); +assert.throws(TypeError, function() { + 0n ^ { + [Symbol.toPrimitive]: function() { + return Symbol("1"); + } + }; +}, "ToBigInt: @@toPrimitive => Symbol => TypeError"); +assert.throws(TypeError, function() { + ({ + valueOf: function() { + return Symbol("1"); + } + }) ^ 0n; +}, "ToBigInt: valueOf => Symbol => TypeError"); +assert.throws(TypeError, function() { + 0n ^ { + valueOf: function() { + return Symbol("1"); + } + }; +}, "ToBigInt: valueOf => Symbol => TypeError"); +assert.throws(TypeError, function() { + ({ + toString: function() { + return Symbol("1"); + } + }) ^ 0n; +}, "ToBigInt: toString => Symbol => TypeError"); +assert.throws(TypeError, function() { + 0n ^ { + toString: function() { + return Symbol("1"); + } + }; +}, "ToBigInt: toString => Symbol => TypeError"); diff --git a/test/language/expressions/bitwise-xor/bigint-toprimitive.js b/test/language/expressions/bitwise-xor/bigint-toprimitive.js new file mode 100644 index 0000000000..139c6990da --- /dev/null +++ b/test/language/expressions/bitwise-xor/bigint-toprimitive.js @@ -0,0 +1,308 @@ +// Copyright (C) 2017 Josh Wolfe. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +description: bitwise-xor operator ToNumeric with BigInt operands +esid: sec-binary-bitwise-operators-runtime-semantics-evaluation +features: [BigInt, Symbol.toPrimitive, computed-property-names] +---*/ + +function err() { + throw new Test262Error(); +} + +function MyError() {} + +assert.sameValue(({ + [Symbol.toPrimitive]: function() { + return 2n; + }, + valueOf: err, + toString: err +}) ^ 3n, 1n, "ToPrimitive: @@toPrimitive takes precedence"); +assert.sameValue(3n ^ { + [Symbol.toPrimitive]: function() { + return 2n; + }, + valueOf: err, + toString: err +}, 1n, "ToPrimitive: @@toPrimitive takes precedence"); +assert.sameValue(({ + valueOf: function() { + return 2n; + }, + toString: err +}) ^ 3n, 1n, "ToPrimitive: valueOf takes precedence over toString"); +assert.sameValue(3n ^ { + valueOf: function() { + return 2n; + }, + toString: err +}, 1n, "ToPrimitive: valueOf takes precedence over toString"); +assert.sameValue(({ + toString: function() { + return 2n; + } +}) ^ 3n, 1n, "ToPrimitive: toString with no valueOf"); +assert.sameValue(3n ^ { + toString: function() { + return 2n; + } +}, 1n, "ToPrimitive: toString with no valueOf"); +assert.sameValue(({ + [Symbol.toPrimitive]: undefined, + valueOf: function() { + return 2n; + } +}) ^ 3n, 1n, "ToPrimitive: skip @@toPrimitive when it's undefined"); +assert.sameValue(3n ^ { + [Symbol.toPrimitive]: undefined, + valueOf: function() { + return 2n; + } +}, 1n, "ToPrimitive: skip @@toPrimitive when it's undefined"); +assert.sameValue(({ + [Symbol.toPrimitive]: null, + valueOf: function() { + return 2n; + } +}) ^ 3n, 1n, "ToPrimitive: skip @@toPrimitive when it's null"); +assert.sameValue(3n ^ { + [Symbol.toPrimitive]: null, + valueOf: function() { + return 2n; + } +}, 1n, "ToPrimitive: skip @@toPrimitive when it's null"); +assert.sameValue(({ + valueOf: null, + toString: function() { + return 2n; + } +}) ^ 3n, 1n, "ToPrimitive: skip valueOf when it's not callable"); +assert.sameValue(3n ^ { + valueOf: null, + toString: function() { + return 2n; + } +}, 1n, "ToPrimitive: skip valueOf when it's not callable"); +assert.sameValue(({ + valueOf: 1, + toString: function() { + return 2n; + } +}) ^ 3n, 1n, "ToPrimitive: skip valueOf when it's not callable"); +assert.sameValue(3n ^ { + valueOf: 1, + toString: function() { + return 2n; + } +}, 1n, "ToPrimitive: skip valueOf when it's not callable"); +assert.sameValue(({ + valueOf: {}, + toString: function() { + return 2n; + } +}) ^ 3n, 1n, "ToPrimitive: skip valueOf when it's not callable"); +assert.sameValue(3n ^ { + valueOf: {}, + toString: function() { + return 2n; + } +}, 1n, "ToPrimitive: skip valueOf when it's not callable"); +assert.sameValue(({ + valueOf: function() { + return {}; + }, + toString: function() { + return 2n; + } +}) ^ 3n, 1n, "ToPrimitive: skip valueOf when it returns an object"); +assert.sameValue(3n ^ { + valueOf: function() { + return {}; + }, + toString: function() { + return 2n; + } +}, 1n, "ToPrimitive: skip valueOf when it returns an object"); +assert.sameValue(({ + valueOf: function() { + return Object(12345); + }, + toString: function() { + return 2n; + } +}) ^ 3n, 1n, "ToPrimitive: skip valueOf when it returns an object"); +assert.sameValue(3n ^ { + valueOf: function() { + return Object(12345); + }, + toString: function() { + return 2n; + } +}, 1n, "ToPrimitive: skip valueOf when it returns an object"); +assert.throws(TypeError, function() { + ({ + [Symbol.toPrimitive]: 1 + }) ^ 0n; +}, "ToPrimitive: throw when @@toPrimitive is not callable"); +assert.throws(TypeError, function() { + 0n ^ { + [Symbol.toPrimitive]: 1 + }; +}, "ToPrimitive: throw when @@toPrimitive is not callable"); +assert.throws(TypeError, function() { + ({ + [Symbol.toPrimitive]: {} + }) ^ 0n; +}, "ToPrimitive: throw when @@toPrimitive is not callable"); +assert.throws(TypeError, function() { + 0n ^ { + [Symbol.toPrimitive]: {} + }; +}, "ToPrimitive: throw when @@toPrimitive is not callable"); +assert.throws(TypeError, function() { + ({ + [Symbol.toPrimitive]: function() { + return Object(1); + } + }) ^ 0n; +}, "ToPrimitive: throw when @@toPrimitive returns an object"); +assert.throws(TypeError, function() { + 0n ^ { + [Symbol.toPrimitive]: function() { + return Object(1); + } + }; +}, "ToPrimitive: throw when @@toPrimitive returns an object"); +assert.throws(TypeError, function() { + ({ + [Symbol.toPrimitive]: function() { + return {}; + } + }) ^ 0n; +}, "ToPrimitive: throw when @@toPrimitive returns an object"); +assert.throws(TypeError, function() { + 0n ^ { + [Symbol.toPrimitive]: function() { + return {}; + } + }; +}, "ToPrimitive: throw when @@toPrimitive returns an object"); +assert.throws(MyError, function() { + ({ + [Symbol.toPrimitive]: function() { + throw new MyError(); + } + }) ^ 0n; +}, "ToPrimitive: propagate errors from @@toPrimitive"); +assert.throws(MyError, function() { + 0n ^ { + [Symbol.toPrimitive]: function() { + throw new MyError(); + } + }; +}, "ToPrimitive: propagate errors from @@toPrimitive"); +assert.throws(MyError, function() { + ({ + valueOf: function() { + throw new MyError(); + } + }) ^ 0n; +}, "ToPrimitive: propagate errors from valueOf"); +assert.throws(MyError, function() { + 0n ^ { + valueOf: function() { + throw new MyError(); + } + }; +}, "ToPrimitive: propagate errors from valueOf"); +assert.throws(MyError, function() { + ({ + toString: function() { + throw new MyError(); + } + }) ^ 0n; +}, "ToPrimitive: propagate errors from toString"); +assert.throws(MyError, function() { + 0n ^ { + toString: function() { + throw new MyError(); + } + }; +}, "ToPrimitive: propagate errors from toString"); +assert.throws(TypeError, function() { + ({ + valueOf: null, + toString: null + }) ^ 0n; +}, "ToPrimitive: throw when skipping both valueOf and toString"); +assert.throws(TypeError, function() { + 0n ^ { + valueOf: null, + toString: null + }; +}, "ToPrimitive: throw when skipping both valueOf and toString"); +assert.throws(TypeError, function() { + ({ + valueOf: 1, + toString: 1 + }) ^ 0n; +}, "ToPrimitive: throw when skipping both valueOf and toString"); +assert.throws(TypeError, function() { + 0n ^ { + valueOf: 1, + toString: 1 + }; +}, "ToPrimitive: throw when skipping both valueOf and toString"); +assert.throws(TypeError, function() { + ({ + valueOf: {}, + toString: {} + }) ^ 0n; +}, "ToPrimitive: throw when skipping both valueOf and toString"); +assert.throws(TypeError, function() { + 0n ^ { + valueOf: {}, + toString: {} + }; +}, "ToPrimitive: throw when skipping both valueOf and toString"); +assert.throws(TypeError, function() { + ({ + valueOf: function() { + return Object(1); + }, + toString: function() { + return Object(1); + } + }) ^ 0n; +}, "ToPrimitive: throw when skipping both valueOf and toString"); +assert.throws(TypeError, function() { + 0n ^ { + valueOf: function() { + return Object(1); + }, + toString: function() { + return Object(1); + } + }; +}, "ToPrimitive: throw when skipping both valueOf and toString"); +assert.throws(TypeError, function() { + ({ + valueOf: function() { + return {}; + }, + toString: function() { + return {}; + } + }) ^ 0n; +}, "ToPrimitive: throw when skipping both valueOf and toString"); +assert.throws(TypeError, function() { + 0n ^ { + valueOf: function() { + return {}; + }, + toString: function() { + return {}; + } + }; +}, "ToPrimitive: throw when skipping both valueOf and toString"); diff --git a/test/language/expressions/bitwise-xor/bigint-wrapped-values.js b/test/language/expressions/bitwise-xor/bigint-wrapped-values.js new file mode 100644 index 0000000000..4970575032 --- /dev/null +++ b/test/language/expressions/bitwise-xor/bigint-wrapped-values.js @@ -0,0 +1,40 @@ +// Copyright (C) 2017 Josh Wolfe. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +description: bitwise-xor operator ToNumeric with BigInt operands +esid: sec-binary-bitwise-operators-runtime-semantics-evaluation +features: [BigInt, Symbol.toPrimitive, computed-property-names] +---*/ + +assert.sameValue(Object(2n) ^ 3n, 1n, "ToPrimitive: unbox object with internal slot"); +assert.sameValue(3n ^ Object(2n), 1n, "ToPrimitive: unbox object with internal slot"); +assert.sameValue(({ + [Symbol.toPrimitive]: function() { + return 2n; + } +}) ^ 3n, 1n, "ToPrimitive: @@toPrimitive"); +assert.sameValue(3n ^ { + [Symbol.toPrimitive]: function() { + return 2n; + } +}, 1n, "ToPrimitive: @@toPrimitive"); +assert.sameValue(({ + valueOf: function() { + return 2n; + } +}) ^ 3n, 1n, "ToPrimitive: valueOf"); +assert.sameValue(3n ^ { + valueOf: function() { + return 2n; + } +}, 1n, "ToPrimitive: valueOf"); +assert.sameValue(({ + toString: function() { + return 2n; + } +}) ^ 3n, 1n, "ToPrimitive: toString"); +assert.sameValue(3n ^ { + toString: function() { + return 2n; + } +}, 1n, "ToPrimitive: toString"); diff --git a/test/language/expressions/division/bigint-errors.js b/test/language/expressions/division/bigint-errors.js new file mode 100644 index 0000000000..78981b44e8 --- /dev/null +++ b/test/language/expressions/division/bigint-errors.js @@ -0,0 +1,62 @@ +// Copyright (C) 2017 Josh Wolfe. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +description: division operator ToNumeric with BigInt operands +esid: sec-multiplicative-operators-runtime-semantics-evaluation +features: [BigInt, Symbol, Symbol.toPrimitive, computed-property-names] +---*/ + +assert.throws(TypeError, function() { + Symbol("1") / 1n; +}, "ToBigInt: Symbol => TypeError"); +assert.throws(TypeError, function() { + 0n / Symbol("1"); +}, "ToBigInt: Symbol => TypeError"); +assert.throws(TypeError, function() { + Object(Symbol("1")) / 1n; +}, "ToBigInt: unbox object with internal slot => Symbol => TypeError"); +assert.throws(TypeError, function() { + 0n / Object(Symbol("1")); +}, "ToBigInt: unbox object with internal slot => Symbol => TypeError"); +assert.throws(TypeError, function() { + ({ + [Symbol.toPrimitive]: function() { + return Symbol("1"); + } + }) / 1n; +}, "ToBigInt: @@toPrimitive => Symbol => TypeError"); +assert.throws(TypeError, function() { + 0n / { + [Symbol.toPrimitive]: function() { + return Symbol("1"); + } + }; +}, "ToBigInt: @@toPrimitive => Symbol => TypeError"); +assert.throws(TypeError, function() { + ({ + valueOf: function() { + return Symbol("1"); + } + }) / 1n; +}, "ToBigInt: valueOf => Symbol => TypeError"); +assert.throws(TypeError, function() { + 0n / { + valueOf: function() { + return Symbol("1"); + } + }; +}, "ToBigInt: valueOf => Symbol => TypeError"); +assert.throws(TypeError, function() { + ({ + toString: function() { + return Symbol("1"); + } + }) / 1n; +}, "ToBigInt: toString => Symbol => TypeError"); +assert.throws(TypeError, function() { + 0n / { + toString: function() { + return Symbol("1"); + } + }; +}, "ToBigInt: toString => Symbol => TypeError"); diff --git a/test/language/expressions/division/bigint-toprimitive.js b/test/language/expressions/division/bigint-toprimitive.js new file mode 100644 index 0000000000..d50ec872f8 --- /dev/null +++ b/test/language/expressions/division/bigint-toprimitive.js @@ -0,0 +1,308 @@ +// Copyright (C) 2017 Josh Wolfe. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +description: division operator ToNumeric with BigInt operands +esid: sec-multiplicative-operators-runtime-semantics-evaluation +features: [BigInt, Symbol.toPrimitive, computed-property-names] +---*/ + +function err() { + throw new Test262Error(); +} + +function MyError() {} + +assert.sameValue(({ + [Symbol.toPrimitive]: function() { + return 2n; + }, + valueOf: err, + toString: err +}) / 2n, 1n, "ToPrimitive: @@toPrimitive takes precedence"); +assert.sameValue(2n / { + [Symbol.toPrimitive]: function() { + return 2n; + }, + valueOf: err, + toString: err +}, 1n, "ToPrimitive: @@toPrimitive takes precedence"); +assert.sameValue(({ + valueOf: function() { + return 2n; + }, + toString: err +}) / 2n, 1n, "ToPrimitive: valueOf takes precedence over toString"); +assert.sameValue(2n / { + valueOf: function() { + return 2n; + }, + toString: err +}, 1n, "ToPrimitive: valueOf takes precedence over toString"); +assert.sameValue(({ + toString: function() { + return 2n; + } +}) / 2n, 1n, "ToPrimitive: toString with no valueOf"); +assert.sameValue(2n / { + toString: function() { + return 2n; + } +}, 1n, "ToPrimitive: toString with no valueOf"); +assert.sameValue(({ + [Symbol.toPrimitive]: undefined, + valueOf: function() { + return 2n; + } +}) / 2n, 1n, "ToPrimitive: skip @@toPrimitive when it's undefined"); +assert.sameValue(2n / { + [Symbol.toPrimitive]: undefined, + valueOf: function() { + return 2n; + } +}, 1n, "ToPrimitive: skip @@toPrimitive when it's undefined"); +assert.sameValue(({ + [Symbol.toPrimitive]: null, + valueOf: function() { + return 2n; + } +}) / 2n, 1n, "ToPrimitive: skip @@toPrimitive when it's null"); +assert.sameValue(2n / { + [Symbol.toPrimitive]: null, + valueOf: function() { + return 2n; + } +}, 1n, "ToPrimitive: skip @@toPrimitive when it's null"); +assert.sameValue(({ + valueOf: null, + toString: function() { + return 2n; + } +}) / 2n, 1n, "ToPrimitive: skip valueOf when it's not callable"); +assert.sameValue(2n / { + valueOf: null, + toString: function() { + return 2n; + } +}, 1n, "ToPrimitive: skip valueOf when it's not callable"); +assert.sameValue(({ + valueOf: 1, + toString: function() { + return 2n; + } +}) / 2n, 1n, "ToPrimitive: skip valueOf when it's not callable"); +assert.sameValue(2n / { + valueOf: 1, + toString: function() { + return 2n; + } +}, 1n, "ToPrimitive: skip valueOf when it's not callable"); +assert.sameValue(({ + valueOf: {}, + toString: function() { + return 2n; + } +}) / 2n, 1n, "ToPrimitive: skip valueOf when it's not callable"); +assert.sameValue(2n / { + valueOf: {}, + toString: function() { + return 2n; + } +}, 1n, "ToPrimitive: skip valueOf when it's not callable"); +assert.sameValue(({ + valueOf: function() { + return {}; + }, + toString: function() { + return 2n; + } +}) / 2n, 1n, "ToPrimitive: skip valueOf when it returns an object"); +assert.sameValue(2n / { + valueOf: function() { + return {}; + }, + toString: function() { + return 2n; + } +}, 1n, "ToPrimitive: skip valueOf when it returns an object"); +assert.sameValue(({ + valueOf: function() { + return Object(12345); + }, + toString: function() { + return 2n; + } +}) / 2n, 1n, "ToPrimitive: skip valueOf when it returns an object"); +assert.sameValue(2n / { + valueOf: function() { + return Object(12345); + }, + toString: function() { + return 2n; + } +}, 1n, "ToPrimitive: skip valueOf when it returns an object"); +assert.throws(TypeError, function() { + ({ + [Symbol.toPrimitive]: 1 + }) / 1n; +}, "ToPrimitive: throw when @@toPrimitive is not callable"); +assert.throws(TypeError, function() { + 0n / { + [Symbol.toPrimitive]: 1 + }; +}, "ToPrimitive: throw when @@toPrimitive is not callable"); +assert.throws(TypeError, function() { + ({ + [Symbol.toPrimitive]: {} + }) / 1n; +}, "ToPrimitive: throw when @@toPrimitive is not callable"); +assert.throws(TypeError, function() { + 0n / { + [Symbol.toPrimitive]: {} + }; +}, "ToPrimitive: throw when @@toPrimitive is not callable"); +assert.throws(TypeError, function() { + ({ + [Symbol.toPrimitive]: function() { + return Object(1); + } + }) / 1n; +}, "ToPrimitive: throw when @@toPrimitive returns an object"); +assert.throws(TypeError, function() { + 0n / { + [Symbol.toPrimitive]: function() { + return Object(1); + } + }; +}, "ToPrimitive: throw when @@toPrimitive returns an object"); +assert.throws(TypeError, function() { + ({ + [Symbol.toPrimitive]: function() { + return {}; + } + }) / 1n; +}, "ToPrimitive: throw when @@toPrimitive returns an object"); +assert.throws(TypeError, function() { + 0n / { + [Symbol.toPrimitive]: function() { + return {}; + } + }; +}, "ToPrimitive: throw when @@toPrimitive returns an object"); +assert.throws(MyError, function() { + ({ + [Symbol.toPrimitive]: function() { + throw new MyError(); + } + }) / 1n; +}, "ToPrimitive: propagate errors from @@toPrimitive"); +assert.throws(MyError, function() { + 0n / { + [Symbol.toPrimitive]: function() { + throw new MyError(); + } + }; +}, "ToPrimitive: propagate errors from @@toPrimitive"); +assert.throws(MyError, function() { + ({ + valueOf: function() { + throw new MyError(); + } + }) / 1n; +}, "ToPrimitive: propagate errors from valueOf"); +assert.throws(MyError, function() { + 0n / { + valueOf: function() { + throw new MyError(); + } + }; +}, "ToPrimitive: propagate errors from valueOf"); +assert.throws(MyError, function() { + ({ + toString: function() { + throw new MyError(); + } + }) / 1n; +}, "ToPrimitive: propagate errors from toString"); +assert.throws(MyError, function() { + 0n / { + toString: function() { + throw new MyError(); + } + }; +}, "ToPrimitive: propagate errors from toString"); +assert.throws(TypeError, function() { + ({ + valueOf: null, + toString: null + }) / 1n; +}, "ToPrimitive: throw when skipping both valueOf and toString"); +assert.throws(TypeError, function() { + 0n / { + valueOf: null, + toString: null + }; +}, "ToPrimitive: throw when skipping both valueOf and toString"); +assert.throws(TypeError, function() { + ({ + valueOf: 1, + toString: 1 + }) / 1n; +}, "ToPrimitive: throw when skipping both valueOf and toString"); +assert.throws(TypeError, function() { + 0n / { + valueOf: 1, + toString: 1 + }; +}, "ToPrimitive: throw when skipping both valueOf and toString"); +assert.throws(TypeError, function() { + ({ + valueOf: {}, + toString: {} + }) / 1n; +}, "ToPrimitive: throw when skipping both valueOf and toString"); +assert.throws(TypeError, function() { + 0n / { + valueOf: {}, + toString: {} + }; +}, "ToPrimitive: throw when skipping both valueOf and toString"); +assert.throws(TypeError, function() { + ({ + valueOf: function() { + return Object(1); + }, + toString: function() { + return Object(1); + } + }) / 1n; +}, "ToPrimitive: throw when skipping both valueOf and toString"); +assert.throws(TypeError, function() { + 0n / { + valueOf: function() { + return Object(1); + }, + toString: function() { + return Object(1); + } + }; +}, "ToPrimitive: throw when skipping both valueOf and toString"); +assert.throws(TypeError, function() { + ({ + valueOf: function() { + return {}; + }, + toString: function() { + return {}; + } + }) / 1n; +}, "ToPrimitive: throw when skipping both valueOf and toString"); +assert.throws(TypeError, function() { + 0n / { + valueOf: function() { + return {}; + }, + toString: function() { + return {}; + } + }; +}, "ToPrimitive: throw when skipping both valueOf and toString"); diff --git a/test/language/expressions/division/bigint-wrapped-values.js b/test/language/expressions/division/bigint-wrapped-values.js new file mode 100644 index 0000000000..d25f79b57e --- /dev/null +++ b/test/language/expressions/division/bigint-wrapped-values.js @@ -0,0 +1,40 @@ +// Copyright (C) 2017 Josh Wolfe. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +description: division operator ToNumeric with BigInt operands +esid: sec-multiplicative-operators-runtime-semantics-evaluation +features: [BigInt, Symbol.toPrimitive, computed-property-names] +---*/ + +assert.sameValue(Object(2n) / 2n, 1n, "ToPrimitive: unbox object with internal slot"); +assert.sameValue(2n / Object(2n), 1n, "ToPrimitive: unbox object with internal slot"); +assert.sameValue(({ + [Symbol.toPrimitive]: function() { + return 2n; + } +}) / 2n, 1n, "ToPrimitive: @@toPrimitive"); +assert.sameValue(2n / { + [Symbol.toPrimitive]: function() { + return 2n; + } +}, 1n, "ToPrimitive: @@toPrimitive"); +assert.sameValue(({ + valueOf: function() { + return 2n; + } +}) / 2n, 1n, "ToPrimitive: valueOf"); +assert.sameValue(2n / { + valueOf: function() { + return 2n; + } +}, 1n, "ToPrimitive: valueOf"); +assert.sameValue(({ + toString: function() { + return 2n; + } +}) / 2n, 1n, "ToPrimitive: toString"); +assert.sameValue(2n / { + toString: function() { + return 2n; + } +}, 1n, "ToPrimitive: toString"); diff --git a/test/language/expressions/exponentiation/bigint-errors.js b/test/language/expressions/exponentiation/bigint-errors.js new file mode 100644 index 0000000000..61b2a81922 --- /dev/null +++ b/test/language/expressions/exponentiation/bigint-errors.js @@ -0,0 +1,62 @@ +// Copyright (C) 2017 Josh Wolfe. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +description: exponentiation operator ToNumeric with BigInt operands +esid: sec-exp-operator-runtime-semantics-evaluation +features: [BigInt, Symbol, Symbol.toPrimitive, computed-property-names] +---*/ + +assert.throws(TypeError, function() { + Symbol("1") ** 0n; +}, "ToBigInt: Symbol => TypeError"); +assert.throws(TypeError, function() { + 0n ** Symbol("1"); +}, "ToBigInt: Symbol => TypeError"); +assert.throws(TypeError, function() { + Object(Symbol("1")) ** 0n; +}, "ToBigInt: unbox object with internal slot => Symbol => TypeError"); +assert.throws(TypeError, function() { + 0n ** Object(Symbol("1")); +}, "ToBigInt: unbox object with internal slot => Symbol => TypeError"); +assert.throws(TypeError, function() { + ({ + [Symbol.toPrimitive]: function() { + return Symbol("1"); + } + }) ** 0n; +}, "ToBigInt: @@toPrimitive => Symbol => TypeError"); +assert.throws(TypeError, function() { + 0n ** { + [Symbol.toPrimitive]: function() { + return Symbol("1"); + } + }; +}, "ToBigInt: @@toPrimitive => Symbol => TypeError"); +assert.throws(TypeError, function() { + ({ + valueOf: function() { + return Symbol("1"); + } + }) ** 0n; +}, "ToBigInt: valueOf => Symbol => TypeError"); +assert.throws(TypeError, function() { + 0n ** { + valueOf: function() { + return Symbol("1"); + } + }; +}, "ToBigInt: valueOf => Symbol => TypeError"); +assert.throws(TypeError, function() { + ({ + toString: function() { + return Symbol("1"); + } + }) ** 0n; +}, "ToBigInt: toString => Symbol => TypeError"); +assert.throws(TypeError, function() { + 0n ** { + toString: function() { + return Symbol("1"); + } + }; +}, "ToBigInt: toString => Symbol => TypeError"); diff --git a/test/language/expressions/exponentiation/bigint-toprimitive.js b/test/language/expressions/exponentiation/bigint-toprimitive.js new file mode 100644 index 0000000000..8e8277df36 --- /dev/null +++ b/test/language/expressions/exponentiation/bigint-toprimitive.js @@ -0,0 +1,308 @@ +// Copyright (C) 2017 Josh Wolfe. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +description: exponentiation operator ToNumeric with BigInt operands +esid: sec-exp-operator-runtime-semantics-evaluation +features: [BigInt, Symbol.toPrimitive, computed-property-names] +---*/ + +function err() { + throw new Test262Error(); +} + +function MyError() {} + +assert.sameValue(({ + [Symbol.toPrimitive]: function() { + return 2n; + }, + valueOf: err, + toString: err +}) ** 1n, 2n, "ToPrimitive: @@toPrimitive takes precedence"); +assert.sameValue(1n ** { + [Symbol.toPrimitive]: function() { + return 2n; + }, + valueOf: err, + toString: err +}, 1n, "ToPrimitive: @@toPrimitive takes precedence"); +assert.sameValue(({ + valueOf: function() { + return 2n; + }, + toString: err +}) ** 1n, 2n, "ToPrimitive: valueOf takes precedence over toString"); +assert.sameValue(1n ** { + valueOf: function() { + return 2n; + }, + toString: err +}, 1n, "ToPrimitive: valueOf takes precedence over toString"); +assert.sameValue(({ + toString: function() { + return 2n; + } +}) ** 1n, 2n, "ToPrimitive: toString with no valueOf"); +assert.sameValue(1n ** { + toString: function() { + return 2n; + } +}, 1n, "ToPrimitive: toString with no valueOf"); +assert.sameValue(({ + [Symbol.toPrimitive]: undefined, + valueOf: function() { + return 2n; + } +}) ** 1n, 2n, "ToPrimitive: skip @@toPrimitive when it's undefined"); +assert.sameValue(1n ** { + [Symbol.toPrimitive]: undefined, + valueOf: function() { + return 2n; + } +}, 1n, "ToPrimitive: skip @@toPrimitive when it's undefined"); +assert.sameValue(({ + [Symbol.toPrimitive]: null, + valueOf: function() { + return 2n; + } +}) ** 1n, 2n, "ToPrimitive: skip @@toPrimitive when it's null"); +assert.sameValue(1n ** { + [Symbol.toPrimitive]: null, + valueOf: function() { + return 2n; + } +}, 1n, "ToPrimitive: skip @@toPrimitive when it's null"); +assert.sameValue(({ + valueOf: null, + toString: function() { + return 2n; + } +}) ** 1n, 2n, "ToPrimitive: skip valueOf when it's not callable"); +assert.sameValue(1n ** { + valueOf: null, + toString: function() { + return 2n; + } +}, 1n, "ToPrimitive: skip valueOf when it's not callable"); +assert.sameValue(({ + valueOf: 1, + toString: function() { + return 2n; + } +}) ** 1n, 2n, "ToPrimitive: skip valueOf when it's not callable"); +assert.sameValue(1n ** { + valueOf: 1, + toString: function() { + return 2n; + } +}, 1n, "ToPrimitive: skip valueOf when it's not callable"); +assert.sameValue(({ + valueOf: {}, + toString: function() { + return 2n; + } +}) ** 1n, 2n, "ToPrimitive: skip valueOf when it's not callable"); +assert.sameValue(1n ** { + valueOf: {}, + toString: function() { + return 2n; + } +}, 1n, "ToPrimitive: skip valueOf when it's not callable"); +assert.sameValue(({ + valueOf: function() { + return {}; + }, + toString: function() { + return 2n; + } +}) ** 1n, 2n, "ToPrimitive: skip valueOf when it returns an object"); +assert.sameValue(1n ** { + valueOf: function() { + return {}; + }, + toString: function() { + return 2n; + } +}, 1n, "ToPrimitive: skip valueOf when it returns an object"); +assert.sameValue(({ + valueOf: function() { + return Object(12345); + }, + toString: function() { + return 2n; + } +}) ** 1n, 2n, "ToPrimitive: skip valueOf when it returns an object"); +assert.sameValue(1n ** { + valueOf: function() { + return Object(12345); + }, + toString: function() { + return 2n; + } +}, 1n, "ToPrimitive: skip valueOf when it returns an object"); +assert.throws(TypeError, function() { + ({ + [Symbol.toPrimitive]: 1 + }) ** 0n; +}, "ToPrimitive: throw when @@toPrimitive is not callable"); +assert.throws(TypeError, function() { + 0n ** { + [Symbol.toPrimitive]: 1 + }; +}, "ToPrimitive: throw when @@toPrimitive is not callable"); +assert.throws(TypeError, function() { + ({ + [Symbol.toPrimitive]: {} + }) ** 0n; +}, "ToPrimitive: throw when @@toPrimitive is not callable"); +assert.throws(TypeError, function() { + 0n ** { + [Symbol.toPrimitive]: {} + }; +}, "ToPrimitive: throw when @@toPrimitive is not callable"); +assert.throws(TypeError, function() { + ({ + [Symbol.toPrimitive]: function() { + return Object(1); + } + }) ** 0n; +}, "ToPrimitive: throw when @@toPrimitive returns an object"); +assert.throws(TypeError, function() { + 0n ** { + [Symbol.toPrimitive]: function() { + return Object(1); + } + }; +}, "ToPrimitive: throw when @@toPrimitive returns an object"); +assert.throws(TypeError, function() { + ({ + [Symbol.toPrimitive]: function() { + return {}; + } + }) ** 0n; +}, "ToPrimitive: throw when @@toPrimitive returns an object"); +assert.throws(TypeError, function() { + 0n ** { + [Symbol.toPrimitive]: function() { + return {}; + } + }; +}, "ToPrimitive: throw when @@toPrimitive returns an object"); +assert.throws(MyError, function() { + ({ + [Symbol.toPrimitive]: function() { + throw new MyError(); + } + }) ** 0n; +}, "ToPrimitive: propagate errors from @@toPrimitive"); +assert.throws(MyError, function() { + 0n ** { + [Symbol.toPrimitive]: function() { + throw new MyError(); + } + }; +}, "ToPrimitive: propagate errors from @@toPrimitive"); +assert.throws(MyError, function() { + ({ + valueOf: function() { + throw new MyError(); + } + }) ** 0n; +}, "ToPrimitive: propagate errors from valueOf"); +assert.throws(MyError, function() { + 0n ** { + valueOf: function() { + throw new MyError(); + } + }; +}, "ToPrimitive: propagate errors from valueOf"); +assert.throws(MyError, function() { + ({ + toString: function() { + throw new MyError(); + } + }) ** 0n; +}, "ToPrimitive: propagate errors from toString"); +assert.throws(MyError, function() { + 0n ** { + toString: function() { + throw new MyError(); + } + }; +}, "ToPrimitive: propagate errors from toString"); +assert.throws(TypeError, function() { + ({ + valueOf: null, + toString: null + }) ** 0n; +}, "ToPrimitive: throw when skipping both valueOf and toString"); +assert.throws(TypeError, function() { + 0n ** { + valueOf: null, + toString: null + }; +}, "ToPrimitive: throw when skipping both valueOf and toString"); +assert.throws(TypeError, function() { + ({ + valueOf: 1, + toString: 1 + }) ** 0n; +}, "ToPrimitive: throw when skipping both valueOf and toString"); +assert.throws(TypeError, function() { + 0n ** { + valueOf: 1, + toString: 1 + }; +}, "ToPrimitive: throw when skipping both valueOf and toString"); +assert.throws(TypeError, function() { + ({ + valueOf: {}, + toString: {} + }) ** 0n; +}, "ToPrimitive: throw when skipping both valueOf and toString"); +assert.throws(TypeError, function() { + 0n ** { + valueOf: {}, + toString: {} + }; +}, "ToPrimitive: throw when skipping both valueOf and toString"); +assert.throws(TypeError, function() { + ({ + valueOf: function() { + return Object(1); + }, + toString: function() { + return Object(1); + } + }) ** 0n; +}, "ToPrimitive: throw when skipping both valueOf and toString"); +assert.throws(TypeError, function() { + 0n ** { + valueOf: function() { + return Object(1); + }, + toString: function() { + return Object(1); + } + }; +}, "ToPrimitive: throw when skipping both valueOf and toString"); +assert.throws(TypeError, function() { + ({ + valueOf: function() { + return {}; + }, + toString: function() { + return {}; + } + }) ** 0n; +}, "ToPrimitive: throw when skipping both valueOf and toString"); +assert.throws(TypeError, function() { + 0n ** { + valueOf: function() { + return {}; + }, + toString: function() { + return {}; + } + }; +}, "ToPrimitive: throw when skipping both valueOf and toString"); diff --git a/test/language/expressions/exponentiation/bigint-wrapped-values.js b/test/language/expressions/exponentiation/bigint-wrapped-values.js new file mode 100644 index 0000000000..bc93102f4f --- /dev/null +++ b/test/language/expressions/exponentiation/bigint-wrapped-values.js @@ -0,0 +1,40 @@ +// Copyright (C) 2017 Josh Wolfe. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +description: exponentiation operator ToNumeric with BigInt operands +esid: sec-exp-operator-runtime-semantics-evaluation +features: [BigInt, Symbol.toPrimitive, computed-property-names] +---*/ + +assert.sameValue(Object(2n) ** 1n, 2n, "ToPrimitive: unbox object with internal slot"); +assert.sameValue(1n ** Object(2n), 1n, "ToPrimitive: unbox object with internal slot"); +assert.sameValue(({ + [Symbol.toPrimitive]: function() { + return 2n; + } +}) ** 1n, 2n, "ToPrimitive: @@toPrimitive"); +assert.sameValue(1n ** { + [Symbol.toPrimitive]: function() { + return 2n; + } +}, 1n, "ToPrimitive: @@toPrimitive"); +assert.sameValue(({ + valueOf: function() { + return 2n; + } +}) ** 1n, 2n, "ToPrimitive: valueOf"); +assert.sameValue(1n ** { + valueOf: function() { + return 2n; + } +}, 1n, "ToPrimitive: valueOf"); +assert.sameValue(({ + toString: function() { + return 2n; + } +}) ** 1n, 2n, "ToPrimitive: toString"); +assert.sameValue(1n ** { + toString: function() { + return 2n; + } +}, 1n, "ToPrimitive: toString"); diff --git a/test/language/expressions/left-shift/bigint-errors.js b/test/language/expressions/left-shift/bigint-errors.js new file mode 100644 index 0000000000..5e076e22f6 --- /dev/null +++ b/test/language/expressions/left-shift/bigint-errors.js @@ -0,0 +1,62 @@ +// Copyright (C) 2017 Josh Wolfe. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +description: left-shift operator ToNumeric with BigInt operands +esid: sec-left-shift-operator-runtime-semantics-evaluation +features: [BigInt, Symbol, Symbol.toPrimitive, computed-property-names] +---*/ + +assert.throws(TypeError, function() { + Symbol("1") << 0n; +}, "ToBigInt: Symbol => TypeError"); +assert.throws(TypeError, function() { + 0n << Symbol("1"); +}, "ToBigInt: Symbol => TypeError"); +assert.throws(TypeError, function() { + Object(Symbol("1")) << 0n; +}, "ToBigInt: unbox object with internal slot => Symbol => TypeError"); +assert.throws(TypeError, function() { + 0n << Object(Symbol("1")); +}, "ToBigInt: unbox object with internal slot => Symbol => TypeError"); +assert.throws(TypeError, function() { + ({ + [Symbol.toPrimitive]: function() { + return Symbol("1"); + } + }) << 0n; +}, "ToBigInt: @@toPrimitive => Symbol => TypeError"); +assert.throws(TypeError, function() { + 0n << { + [Symbol.toPrimitive]: function() { + return Symbol("1"); + } + }; +}, "ToBigInt: @@toPrimitive => Symbol => TypeError"); +assert.throws(TypeError, function() { + ({ + valueOf: function() { + return Symbol("1"); + } + }) << 0n; +}, "ToBigInt: valueOf => Symbol => TypeError"); +assert.throws(TypeError, function() { + 0n << { + valueOf: function() { + return Symbol("1"); + } + }; +}, "ToBigInt: valueOf => Symbol => TypeError"); +assert.throws(TypeError, function() { + ({ + toString: function() { + return Symbol("1"); + } + }) << 0n; +}, "ToBigInt: toString => Symbol => TypeError"); +assert.throws(TypeError, function() { + 0n << { + toString: function() { + return Symbol("1"); + } + }; +}, "ToBigInt: toString => Symbol => TypeError"); diff --git a/test/language/expressions/left-shift/bigint-toprimitive.js b/test/language/expressions/left-shift/bigint-toprimitive.js new file mode 100644 index 0000000000..752d0e8ad5 --- /dev/null +++ b/test/language/expressions/left-shift/bigint-toprimitive.js @@ -0,0 +1,308 @@ +// Copyright (C) 2017 Josh Wolfe. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +description: left-shift operator ToNumeric with BigInt operands +esid: sec-left-shift-operator-runtime-semantics-evaluation +features: [BigInt, Symbol.toPrimitive, computed-property-names] +---*/ + +function err() { + throw new Test262Error(); +} + +function MyError() {} + +assert.sameValue(({ + [Symbol.toPrimitive]: function() { + return 2n; + }, + valueOf: err, + toString: err +}) << 1n, 4n, "ToPrimitive: @@toPrimitive takes precedence"); +assert.sameValue(1n << { + [Symbol.toPrimitive]: function() { + return 2n; + }, + valueOf: err, + toString: err +}, 4n, "ToPrimitive: @@toPrimitive takes precedence"); +assert.sameValue(({ + valueOf: function() { + return 2n; + }, + toString: err +}) << 1n, 4n, "ToPrimitive: valueOf takes precedence over toString"); +assert.sameValue(1n << { + valueOf: function() { + return 2n; + }, + toString: err +}, 4n, "ToPrimitive: valueOf takes precedence over toString"); +assert.sameValue(({ + toString: function() { + return 2n; + } +}) << 1n, 4n, "ToPrimitive: toString with no valueOf"); +assert.sameValue(1n << { + toString: function() { + return 2n; + } +}, 4n, "ToPrimitive: toString with no valueOf"); +assert.sameValue(({ + [Symbol.toPrimitive]: undefined, + valueOf: function() { + return 2n; + } +}) << 1n, 4n, "ToPrimitive: skip @@toPrimitive when it's undefined"); +assert.sameValue(1n << { + [Symbol.toPrimitive]: undefined, + valueOf: function() { + return 2n; + } +}, 4n, "ToPrimitive: skip @@toPrimitive when it's undefined"); +assert.sameValue(({ + [Symbol.toPrimitive]: null, + valueOf: function() { + return 2n; + } +}) << 1n, 4n, "ToPrimitive: skip @@toPrimitive when it's null"); +assert.sameValue(1n << { + [Symbol.toPrimitive]: null, + valueOf: function() { + return 2n; + } +}, 4n, "ToPrimitive: skip @@toPrimitive when it's null"); +assert.sameValue(({ + valueOf: null, + toString: function() { + return 2n; + } +}) << 1n, 4n, "ToPrimitive: skip valueOf when it's not callable"); +assert.sameValue(1n << { + valueOf: null, + toString: function() { + return 2n; + } +}, 4n, "ToPrimitive: skip valueOf when it's not callable"); +assert.sameValue(({ + valueOf: 1, + toString: function() { + return 2n; + } +}) << 1n, 4n, "ToPrimitive: skip valueOf when it's not callable"); +assert.sameValue(1n << { + valueOf: 1, + toString: function() { + return 2n; + } +}, 4n, "ToPrimitive: skip valueOf when it's not callable"); +assert.sameValue(({ + valueOf: {}, + toString: function() { + return 2n; + } +}) << 1n, 4n, "ToPrimitive: skip valueOf when it's not callable"); +assert.sameValue(1n << { + valueOf: {}, + toString: function() { + return 2n; + } +}, 4n, "ToPrimitive: skip valueOf when it's not callable"); +assert.sameValue(({ + valueOf: function() { + return {}; + }, + toString: function() { + return 2n; + } +}) << 1n, 4n, "ToPrimitive: skip valueOf when it returns an object"); +assert.sameValue(1n << { + valueOf: function() { + return {}; + }, + toString: function() { + return 2n; + } +}, 4n, "ToPrimitive: skip valueOf when it returns an object"); +assert.sameValue(({ + valueOf: function() { + return Object(12345); + }, + toString: function() { + return 2n; + } +}) << 1n, 4n, "ToPrimitive: skip valueOf when it returns an object"); +assert.sameValue(1n << { + valueOf: function() { + return Object(12345); + }, + toString: function() { + return 2n; + } +}, 4n, "ToPrimitive: skip valueOf when it returns an object"); +assert.throws(TypeError, function() { + ({ + [Symbol.toPrimitive]: 1 + }) << 0n; +}, "ToPrimitive: throw when @@toPrimitive is not callable"); +assert.throws(TypeError, function() { + 0n << { + [Symbol.toPrimitive]: 1 + }; +}, "ToPrimitive: throw when @@toPrimitive is not callable"); +assert.throws(TypeError, function() { + ({ + [Symbol.toPrimitive]: {} + }) << 0n; +}, "ToPrimitive: throw when @@toPrimitive is not callable"); +assert.throws(TypeError, function() { + 0n << { + [Symbol.toPrimitive]: {} + }; +}, "ToPrimitive: throw when @@toPrimitive is not callable"); +assert.throws(TypeError, function() { + ({ + [Symbol.toPrimitive]: function() { + return Object(1); + } + }) << 0n; +}, "ToPrimitive: throw when @@toPrimitive returns an object"); +assert.throws(TypeError, function() { + 0n << { + [Symbol.toPrimitive]: function() { + return Object(1); + } + }; +}, "ToPrimitive: throw when @@toPrimitive returns an object"); +assert.throws(TypeError, function() { + ({ + [Symbol.toPrimitive]: function() { + return {}; + } + }) << 0n; +}, "ToPrimitive: throw when @@toPrimitive returns an object"); +assert.throws(TypeError, function() { + 0n << { + [Symbol.toPrimitive]: function() { + return {}; + } + }; +}, "ToPrimitive: throw when @@toPrimitive returns an object"); +assert.throws(MyError, function() { + ({ + [Symbol.toPrimitive]: function() { + throw new MyError(); + } + }) << 0n; +}, "ToPrimitive: propagate errors from @@toPrimitive"); +assert.throws(MyError, function() { + 0n << { + [Symbol.toPrimitive]: function() { + throw new MyError(); + } + }; +}, "ToPrimitive: propagate errors from @@toPrimitive"); +assert.throws(MyError, function() { + ({ + valueOf: function() { + throw new MyError(); + } + }) << 0n; +}, "ToPrimitive: propagate errors from valueOf"); +assert.throws(MyError, function() { + 0n << { + valueOf: function() { + throw new MyError(); + } + }; +}, "ToPrimitive: propagate errors from valueOf"); +assert.throws(MyError, function() { + ({ + toString: function() { + throw new MyError(); + } + }) << 0n; +}, "ToPrimitive: propagate errors from toString"); +assert.throws(MyError, function() { + 0n << { + toString: function() { + throw new MyError(); + } + }; +}, "ToPrimitive: propagate errors from toString"); +assert.throws(TypeError, function() { + ({ + valueOf: null, + toString: null + }) << 0n; +}, "ToPrimitive: throw when skipping both valueOf and toString"); +assert.throws(TypeError, function() { + 0n << { + valueOf: null, + toString: null + }; +}, "ToPrimitive: throw when skipping both valueOf and toString"); +assert.throws(TypeError, function() { + ({ + valueOf: 1, + toString: 1 + }) << 0n; +}, "ToPrimitive: throw when skipping both valueOf and toString"); +assert.throws(TypeError, function() { + 0n << { + valueOf: 1, + toString: 1 + }; +}, "ToPrimitive: throw when skipping both valueOf and toString"); +assert.throws(TypeError, function() { + ({ + valueOf: {}, + toString: {} + }) << 0n; +}, "ToPrimitive: throw when skipping both valueOf and toString"); +assert.throws(TypeError, function() { + 0n << { + valueOf: {}, + toString: {} + }; +}, "ToPrimitive: throw when skipping both valueOf and toString"); +assert.throws(TypeError, function() { + ({ + valueOf: function() { + return Object(1); + }, + toString: function() { + return Object(1); + } + }) << 0n; +}, "ToPrimitive: throw when skipping both valueOf and toString"); +assert.throws(TypeError, function() { + 0n << { + valueOf: function() { + return Object(1); + }, + toString: function() { + return Object(1); + } + }; +}, "ToPrimitive: throw when skipping both valueOf and toString"); +assert.throws(TypeError, function() { + ({ + valueOf: function() { + return {}; + }, + toString: function() { + return {}; + } + }) << 0n; +}, "ToPrimitive: throw when skipping both valueOf and toString"); +assert.throws(TypeError, function() { + 0n << { + valueOf: function() { + return {}; + }, + toString: function() { + return {}; + } + }; +}, "ToPrimitive: throw when skipping both valueOf and toString"); diff --git a/test/language/expressions/left-shift/bigint-wrapped-values.js b/test/language/expressions/left-shift/bigint-wrapped-values.js new file mode 100644 index 0000000000..79422b11b9 --- /dev/null +++ b/test/language/expressions/left-shift/bigint-wrapped-values.js @@ -0,0 +1,40 @@ +// Copyright (C) 2017 Josh Wolfe. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +description: left-shift operator ToNumeric with BigInt operands +esid: sec-left-shift-operator-runtime-semantics-evaluation +features: [BigInt, Symbol.toPrimitive, computed-property-names] +---*/ + +assert.sameValue(Object(2n) << 1n, 4n, "ToPrimitive: unbox object with internal slot"); +assert.sameValue(1n << Object(2n), 4n, "ToPrimitive: unbox object with internal slot"); +assert.sameValue(({ + [Symbol.toPrimitive]: function() { + return 2n; + } +}) << 1n, 4n, "ToPrimitive: @@toPrimitive"); +assert.sameValue(1n << { + [Symbol.toPrimitive]: function() { + return 2n; + } +}, 4n, "ToPrimitive: @@toPrimitive"); +assert.sameValue(({ + valueOf: function() { + return 2n; + } +}) << 1n, 4n, "ToPrimitive: valueOf"); +assert.sameValue(1n << { + valueOf: function() { + return 2n; + } +}, 4n, "ToPrimitive: valueOf"); +assert.sameValue(({ + toString: function() { + return 2n; + } +}) << 1n, 4n, "ToPrimitive: toString"); +assert.sameValue(1n << { + toString: function() { + return 2n; + } +}, 4n, "ToPrimitive: toString"); diff --git a/test/language/expressions/modulus/bigint-errors.js b/test/language/expressions/modulus/bigint-errors.js new file mode 100644 index 0000000000..ec59400418 --- /dev/null +++ b/test/language/expressions/modulus/bigint-errors.js @@ -0,0 +1,62 @@ +// Copyright (C) 2017 Josh Wolfe. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +description: modulus operator ToNumeric with BigInt operands +esid: sec-multiplicative-operators-runtime-semantics-evaluation +features: [BigInt, Symbol, Symbol.toPrimitive, computed-property-names] +---*/ + +assert.throws(TypeError, function() { + Symbol("1") % 1n; +}, "ToBigInt: Symbol => TypeError"); +assert.throws(TypeError, function() { + 0n % Symbol("1"); +}, "ToBigInt: Symbol => TypeError"); +assert.throws(TypeError, function() { + Object(Symbol("1")) % 1n; +}, "ToBigInt: unbox object with internal slot => Symbol => TypeError"); +assert.throws(TypeError, function() { + 0n % Object(Symbol("1")); +}, "ToBigInt: unbox object with internal slot => Symbol => TypeError"); +assert.throws(TypeError, function() { + ({ + [Symbol.toPrimitive]: function() { + return Symbol("1"); + } + }) % 1n; +}, "ToBigInt: @@toPrimitive => Symbol => TypeError"); +assert.throws(TypeError, function() { + 0n % { + [Symbol.toPrimitive]: function() { + return Symbol("1"); + } + }; +}, "ToBigInt: @@toPrimitive => Symbol => TypeError"); +assert.throws(TypeError, function() { + ({ + valueOf: function() { + return Symbol("1"); + } + }) % 1n; +}, "ToBigInt: valueOf => Symbol => TypeError"); +assert.throws(TypeError, function() { + 0n % { + valueOf: function() { + return Symbol("1"); + } + }; +}, "ToBigInt: valueOf => Symbol => TypeError"); +assert.throws(TypeError, function() { + ({ + toString: function() { + return Symbol("1"); + } + }) % 1n; +}, "ToBigInt: toString => Symbol => TypeError"); +assert.throws(TypeError, function() { + 0n % { + toString: function() { + return Symbol("1"); + } + }; +}, "ToBigInt: toString => Symbol => TypeError"); diff --git a/test/language/expressions/modulus/bigint-toprimitive.js b/test/language/expressions/modulus/bigint-toprimitive.js new file mode 100644 index 0000000000..00c7cd6110 --- /dev/null +++ b/test/language/expressions/modulus/bigint-toprimitive.js @@ -0,0 +1,308 @@ +// Copyright (C) 2017 Josh Wolfe. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +description: modulus operator ToNumeric with BigInt operands +esid: sec-multiplicative-operators-runtime-semantics-evaluation +features: [BigInt, Symbol.toPrimitive, computed-property-names] +---*/ + +function err() { + throw new Test262Error(); +} + +function MyError() {} + +assert.sameValue(({ + [Symbol.toPrimitive]: function() { + return 2n; + }, + valueOf: err, + toString: err +}) % 2n, 0n, "ToPrimitive: @@toPrimitive takes precedence"); +assert.sameValue(2n % { + [Symbol.toPrimitive]: function() { + return 2n; + }, + valueOf: err, + toString: err +}, 0n, "ToPrimitive: @@toPrimitive takes precedence"); +assert.sameValue(({ + valueOf: function() { + return 2n; + }, + toString: err +}) % 2n, 0n, "ToPrimitive: valueOf takes precedence over toString"); +assert.sameValue(2n % { + valueOf: function() { + return 2n; + }, + toString: err +}, 0n, "ToPrimitive: valueOf takes precedence over toString"); +assert.sameValue(({ + toString: function() { + return 2n; + } +}) % 2n, 0n, "ToPrimitive: toString with no valueOf"); +assert.sameValue(2n % { + toString: function() { + return 2n; + } +}, 0n, "ToPrimitive: toString with no valueOf"); +assert.sameValue(({ + [Symbol.toPrimitive]: undefined, + valueOf: function() { + return 2n; + } +}) % 2n, 0n, "ToPrimitive: skip @@toPrimitive when it's undefined"); +assert.sameValue(2n % { + [Symbol.toPrimitive]: undefined, + valueOf: function() { + return 2n; + } +}, 0n, "ToPrimitive: skip @@toPrimitive when it's undefined"); +assert.sameValue(({ + [Symbol.toPrimitive]: null, + valueOf: function() { + return 2n; + } +}) % 2n, 0n, "ToPrimitive: skip @@toPrimitive when it's null"); +assert.sameValue(2n % { + [Symbol.toPrimitive]: null, + valueOf: function() { + return 2n; + } +}, 0n, "ToPrimitive: skip @@toPrimitive when it's null"); +assert.sameValue(({ + valueOf: null, + toString: function() { + return 2n; + } +}) % 2n, 0n, "ToPrimitive: skip valueOf when it's not callable"); +assert.sameValue(2n % { + valueOf: null, + toString: function() { + return 2n; + } +}, 0n, "ToPrimitive: skip valueOf when it's not callable"); +assert.sameValue(({ + valueOf: 1, + toString: function() { + return 2n; + } +}) % 2n, 0n, "ToPrimitive: skip valueOf when it's not callable"); +assert.sameValue(2n % { + valueOf: 1, + toString: function() { + return 2n; + } +}, 0n, "ToPrimitive: skip valueOf when it's not callable"); +assert.sameValue(({ + valueOf: {}, + toString: function() { + return 2n; + } +}) % 2n, 0n, "ToPrimitive: skip valueOf when it's not callable"); +assert.sameValue(2n % { + valueOf: {}, + toString: function() { + return 2n; + } +}, 0n, "ToPrimitive: skip valueOf when it's not callable"); +assert.sameValue(({ + valueOf: function() { + return {}; + }, + toString: function() { + return 2n; + } +}) % 2n, 0n, "ToPrimitive: skip valueOf when it returns an object"); +assert.sameValue(2n % { + valueOf: function() { + return {}; + }, + toString: function() { + return 2n; + } +}, 0n, "ToPrimitive: skip valueOf when it returns an object"); +assert.sameValue(({ + valueOf: function() { + return Object(12345); + }, + toString: function() { + return 2n; + } +}) % 2n, 0n, "ToPrimitive: skip valueOf when it returns an object"); +assert.sameValue(2n % { + valueOf: function() { + return Object(12345); + }, + toString: function() { + return 2n; + } +}, 0n, "ToPrimitive: skip valueOf when it returns an object"); +assert.throws(TypeError, function() { + ({ + [Symbol.toPrimitive]: 1 + }) % 1n; +}, "ToPrimitive: throw when @@toPrimitive is not callable"); +assert.throws(TypeError, function() { + 0n % { + [Symbol.toPrimitive]: 1 + }; +}, "ToPrimitive: throw when @@toPrimitive is not callable"); +assert.throws(TypeError, function() { + ({ + [Symbol.toPrimitive]: {} + }) % 1n; +}, "ToPrimitive: throw when @@toPrimitive is not callable"); +assert.throws(TypeError, function() { + 0n % { + [Symbol.toPrimitive]: {} + }; +}, "ToPrimitive: throw when @@toPrimitive is not callable"); +assert.throws(TypeError, function() { + ({ + [Symbol.toPrimitive]: function() { + return Object(1); + } + }) % 1n; +}, "ToPrimitive: throw when @@toPrimitive returns an object"); +assert.throws(TypeError, function() { + 0n % { + [Symbol.toPrimitive]: function() { + return Object(1); + } + }; +}, "ToPrimitive: throw when @@toPrimitive returns an object"); +assert.throws(TypeError, function() { + ({ + [Symbol.toPrimitive]: function() { + return {}; + } + }) % 1n; +}, "ToPrimitive: throw when @@toPrimitive returns an object"); +assert.throws(TypeError, function() { + 0n % { + [Symbol.toPrimitive]: function() { + return {}; + } + }; +}, "ToPrimitive: throw when @@toPrimitive returns an object"); +assert.throws(MyError, function() { + ({ + [Symbol.toPrimitive]: function() { + throw new MyError(); + } + }) % 1n; +}, "ToPrimitive: propagate errors from @@toPrimitive"); +assert.throws(MyError, function() { + 0n % { + [Symbol.toPrimitive]: function() { + throw new MyError(); + } + }; +}, "ToPrimitive: propagate errors from @@toPrimitive"); +assert.throws(MyError, function() { + ({ + valueOf: function() { + throw new MyError(); + } + }) % 1n; +}, "ToPrimitive: propagate errors from valueOf"); +assert.throws(MyError, function() { + 0n % { + valueOf: function() { + throw new MyError(); + } + }; +}, "ToPrimitive: propagate errors from valueOf"); +assert.throws(MyError, function() { + ({ + toString: function() { + throw new MyError(); + } + }) % 1n; +}, "ToPrimitive: propagate errors from toString"); +assert.throws(MyError, function() { + 0n % { + toString: function() { + throw new MyError(); + } + }; +}, "ToPrimitive: propagate errors from toString"); +assert.throws(TypeError, function() { + ({ + valueOf: null, + toString: null + }) % 1n; +}, "ToPrimitive: throw when skipping both valueOf and toString"); +assert.throws(TypeError, function() { + 0n % { + valueOf: null, + toString: null + }; +}, "ToPrimitive: throw when skipping both valueOf and toString"); +assert.throws(TypeError, function() { + ({ + valueOf: 1, + toString: 1 + }) % 1n; +}, "ToPrimitive: throw when skipping both valueOf and toString"); +assert.throws(TypeError, function() { + 0n % { + valueOf: 1, + toString: 1 + }; +}, "ToPrimitive: throw when skipping both valueOf and toString"); +assert.throws(TypeError, function() { + ({ + valueOf: {}, + toString: {} + }) % 1n; +}, "ToPrimitive: throw when skipping both valueOf and toString"); +assert.throws(TypeError, function() { + 0n % { + valueOf: {}, + toString: {} + }; +}, "ToPrimitive: throw when skipping both valueOf and toString"); +assert.throws(TypeError, function() { + ({ + valueOf: function() { + return Object(1); + }, + toString: function() { + return Object(1); + } + }) % 1n; +}, "ToPrimitive: throw when skipping both valueOf and toString"); +assert.throws(TypeError, function() { + 0n % { + valueOf: function() { + return Object(1); + }, + toString: function() { + return Object(1); + } + }; +}, "ToPrimitive: throw when skipping both valueOf and toString"); +assert.throws(TypeError, function() { + ({ + valueOf: function() { + return {}; + }, + toString: function() { + return {}; + } + }) % 1n; +}, "ToPrimitive: throw when skipping both valueOf and toString"); +assert.throws(TypeError, function() { + 0n % { + valueOf: function() { + return {}; + }, + toString: function() { + return {}; + } + }; +}, "ToPrimitive: throw when skipping both valueOf and toString"); diff --git a/test/language/expressions/modulus/bigint-wrapped-values.js b/test/language/expressions/modulus/bigint-wrapped-values.js new file mode 100644 index 0000000000..474e7f43c7 --- /dev/null +++ b/test/language/expressions/modulus/bigint-wrapped-values.js @@ -0,0 +1,40 @@ +// Copyright (C) 2017 Josh Wolfe. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +description: modulus operator ToNumeric with BigInt operands +esid: sec-multiplicative-operators-runtime-semantics-evaluation +features: [BigInt, Symbol.toPrimitive, computed-property-names] +---*/ + +assert.sameValue(Object(2n) % 2n, 0n, "ToPrimitive: unbox object with internal slot"); +assert.sameValue(2n % Object(2n), 0n, "ToPrimitive: unbox object with internal slot"); +assert.sameValue(({ + [Symbol.toPrimitive]: function() { + return 2n; + } +}) % 2n, 0n, "ToPrimitive: @@toPrimitive"); +assert.sameValue(2n % { + [Symbol.toPrimitive]: function() { + return 2n; + } +}, 0n, "ToPrimitive: @@toPrimitive"); +assert.sameValue(({ + valueOf: function() { + return 2n; + } +}) % 2n, 0n, "ToPrimitive: valueOf"); +assert.sameValue(2n % { + valueOf: function() { + return 2n; + } +}, 0n, "ToPrimitive: valueOf"); +assert.sameValue(({ + toString: function() { + return 2n; + } +}) % 2n, 0n, "ToPrimitive: toString"); +assert.sameValue(2n % { + toString: function() { + return 2n; + } +}, 0n, "ToPrimitive: toString"); diff --git a/test/language/expressions/multiplication/bigint-errors.js b/test/language/expressions/multiplication/bigint-errors.js new file mode 100644 index 0000000000..a2cc666b4d --- /dev/null +++ b/test/language/expressions/multiplication/bigint-errors.js @@ -0,0 +1,62 @@ +// Copyright (C) 2017 Josh Wolfe. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +description: multiplication operator ToNumeric with BigInt operands +esid: sec-multiplicative-operators-runtime-semantics-evaluation +features: [BigInt, Symbol, Symbol.toPrimitive, computed-property-names] +---*/ + +assert.throws(TypeError, function() { + Symbol("1") * 0n; +}, "ToBigInt: Symbol => TypeError"); +assert.throws(TypeError, function() { + 0n * Symbol("1"); +}, "ToBigInt: Symbol => TypeError"); +assert.throws(TypeError, function() { + Object(Symbol("1")) * 0n; +}, "ToBigInt: unbox object with internal slot => Symbol => TypeError"); +assert.throws(TypeError, function() { + 0n * Object(Symbol("1")); +}, "ToBigInt: unbox object with internal slot => Symbol => TypeError"); +assert.throws(TypeError, function() { + ({ + [Symbol.toPrimitive]: function() { + return Symbol("1"); + } + }) * 0n; +}, "ToBigInt: @@toPrimitive => Symbol => TypeError"); +assert.throws(TypeError, function() { + 0n * { + [Symbol.toPrimitive]: function() { + return Symbol("1"); + } + }; +}, "ToBigInt: @@toPrimitive => Symbol => TypeError"); +assert.throws(TypeError, function() { + ({ + valueOf: function() { + return Symbol("1"); + } + }) * 0n; +}, "ToBigInt: valueOf => Symbol => TypeError"); +assert.throws(TypeError, function() { + 0n * { + valueOf: function() { + return Symbol("1"); + } + }; +}, "ToBigInt: valueOf => Symbol => TypeError"); +assert.throws(TypeError, function() { + ({ + toString: function() { + return Symbol("1"); + } + }) * 0n; +}, "ToBigInt: toString => Symbol => TypeError"); +assert.throws(TypeError, function() { + 0n * { + toString: function() { + return Symbol("1"); + } + }; +}, "ToBigInt: toString => Symbol => TypeError"); diff --git a/test/language/expressions/multiplication/bigint-toprimitive.js b/test/language/expressions/multiplication/bigint-toprimitive.js new file mode 100644 index 0000000000..adb1a64745 --- /dev/null +++ b/test/language/expressions/multiplication/bigint-toprimitive.js @@ -0,0 +1,308 @@ +// Copyright (C) 2017 Josh Wolfe. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +description: multiplication operator ToNumeric with BigInt operands +esid: sec-multiplicative-operators-runtime-semantics-evaluation +features: [BigInt, Symbol.toPrimitive, computed-property-names] +---*/ + +function err() { + throw new Test262Error(); +} + +function MyError() {} + +assert.sameValue(({ + [Symbol.toPrimitive]: function() { + return 2n; + }, + valueOf: err, + toString: err +}) * 2n, 4n, "ToPrimitive: @@toPrimitive takes precedence"); +assert.sameValue(2n * { + [Symbol.toPrimitive]: function() { + return 2n; + }, + valueOf: err, + toString: err +}, 4n, "ToPrimitive: @@toPrimitive takes precedence"); +assert.sameValue(({ + valueOf: function() { + return 2n; + }, + toString: err +}) * 2n, 4n, "ToPrimitive: valueOf takes precedence over toString"); +assert.sameValue(2n * { + valueOf: function() { + return 2n; + }, + toString: err +}, 4n, "ToPrimitive: valueOf takes precedence over toString"); +assert.sameValue(({ + toString: function() { + return 2n; + } +}) * 2n, 4n, "ToPrimitive: toString with no valueOf"); +assert.sameValue(2n * { + toString: function() { + return 2n; + } +}, 4n, "ToPrimitive: toString with no valueOf"); +assert.sameValue(({ + [Symbol.toPrimitive]: undefined, + valueOf: function() { + return 2n; + } +}) * 2n, 4n, "ToPrimitive: skip @@toPrimitive when it's undefined"); +assert.sameValue(2n * { + [Symbol.toPrimitive]: undefined, + valueOf: function() { + return 2n; + } +}, 4n, "ToPrimitive: skip @@toPrimitive when it's undefined"); +assert.sameValue(({ + [Symbol.toPrimitive]: null, + valueOf: function() { + return 2n; + } +}) * 2n, 4n, "ToPrimitive: skip @@toPrimitive when it's null"); +assert.sameValue(2n * { + [Symbol.toPrimitive]: null, + valueOf: function() { + return 2n; + } +}, 4n, "ToPrimitive: skip @@toPrimitive when it's null"); +assert.sameValue(({ + valueOf: null, + toString: function() { + return 2n; + } +}) * 2n, 4n, "ToPrimitive: skip valueOf when it's not callable"); +assert.sameValue(2n * { + valueOf: null, + toString: function() { + return 2n; + } +}, 4n, "ToPrimitive: skip valueOf when it's not callable"); +assert.sameValue(({ + valueOf: 1, + toString: function() { + return 2n; + } +}) * 2n, 4n, "ToPrimitive: skip valueOf when it's not callable"); +assert.sameValue(2n * { + valueOf: 1, + toString: function() { + return 2n; + } +}, 4n, "ToPrimitive: skip valueOf when it's not callable"); +assert.sameValue(({ + valueOf: {}, + toString: function() { + return 2n; + } +}) * 2n, 4n, "ToPrimitive: skip valueOf when it's not callable"); +assert.sameValue(2n * { + valueOf: {}, + toString: function() { + return 2n; + } +}, 4n, "ToPrimitive: skip valueOf when it's not callable"); +assert.sameValue(({ + valueOf: function() { + return {}; + }, + toString: function() { + return 2n; + } +}) * 2n, 4n, "ToPrimitive: skip valueOf when it returns an object"); +assert.sameValue(2n * { + valueOf: function() { + return {}; + }, + toString: function() { + return 2n; + } +}, 4n, "ToPrimitive: skip valueOf when it returns an object"); +assert.sameValue(({ + valueOf: function() { + return Object(12345); + }, + toString: function() { + return 2n; + } +}) * 2n, 4n, "ToPrimitive: skip valueOf when it returns an object"); +assert.sameValue(2n * { + valueOf: function() { + return Object(12345); + }, + toString: function() { + return 2n; + } +}, 4n, "ToPrimitive: skip valueOf when it returns an object"); +assert.throws(TypeError, function() { + ({ + [Symbol.toPrimitive]: 1 + }) * 0n; +}, "ToPrimitive: throw when @@toPrimitive is not callable"); +assert.throws(TypeError, function() { + 0n * { + [Symbol.toPrimitive]: 1 + }; +}, "ToPrimitive: throw when @@toPrimitive is not callable"); +assert.throws(TypeError, function() { + ({ + [Symbol.toPrimitive]: {} + }) * 0n; +}, "ToPrimitive: throw when @@toPrimitive is not callable"); +assert.throws(TypeError, function() { + 0n * { + [Symbol.toPrimitive]: {} + }; +}, "ToPrimitive: throw when @@toPrimitive is not callable"); +assert.throws(TypeError, function() { + ({ + [Symbol.toPrimitive]: function() { + return Object(1); + } + }) * 0n; +}, "ToPrimitive: throw when @@toPrimitive returns an object"); +assert.throws(TypeError, function() { + 0n * { + [Symbol.toPrimitive]: function() { + return Object(1); + } + }; +}, "ToPrimitive: throw when @@toPrimitive returns an object"); +assert.throws(TypeError, function() { + ({ + [Symbol.toPrimitive]: function() { + return {}; + } + }) * 0n; +}, "ToPrimitive: throw when @@toPrimitive returns an object"); +assert.throws(TypeError, function() { + 0n * { + [Symbol.toPrimitive]: function() { + return {}; + } + }; +}, "ToPrimitive: throw when @@toPrimitive returns an object"); +assert.throws(MyError, function() { + ({ + [Symbol.toPrimitive]: function() { + throw new MyError(); + } + }) * 0n; +}, "ToPrimitive: propagate errors from @@toPrimitive"); +assert.throws(MyError, function() { + 0n * { + [Symbol.toPrimitive]: function() { + throw new MyError(); + } + }; +}, "ToPrimitive: propagate errors from @@toPrimitive"); +assert.throws(MyError, function() { + ({ + valueOf: function() { + throw new MyError(); + } + }) * 0n; +}, "ToPrimitive: propagate errors from valueOf"); +assert.throws(MyError, function() { + 0n * { + valueOf: function() { + throw new MyError(); + } + }; +}, "ToPrimitive: propagate errors from valueOf"); +assert.throws(MyError, function() { + ({ + toString: function() { + throw new MyError(); + } + }) * 0n; +}, "ToPrimitive: propagate errors from toString"); +assert.throws(MyError, function() { + 0n * { + toString: function() { + throw new MyError(); + } + }; +}, "ToPrimitive: propagate errors from toString"); +assert.throws(TypeError, function() { + ({ + valueOf: null, + toString: null + }) * 0n; +}, "ToPrimitive: throw when skipping both valueOf and toString"); +assert.throws(TypeError, function() { + 0n * { + valueOf: null, + toString: null + }; +}, "ToPrimitive: throw when skipping both valueOf and toString"); +assert.throws(TypeError, function() { + ({ + valueOf: 1, + toString: 1 + }) * 0n; +}, "ToPrimitive: throw when skipping both valueOf and toString"); +assert.throws(TypeError, function() { + 0n * { + valueOf: 1, + toString: 1 + }; +}, "ToPrimitive: throw when skipping both valueOf and toString"); +assert.throws(TypeError, function() { + ({ + valueOf: {}, + toString: {} + }) * 0n; +}, "ToPrimitive: throw when skipping both valueOf and toString"); +assert.throws(TypeError, function() { + 0n * { + valueOf: {}, + toString: {} + }; +}, "ToPrimitive: throw when skipping both valueOf and toString"); +assert.throws(TypeError, function() { + ({ + valueOf: function() { + return Object(1); + }, + toString: function() { + return Object(1); + } + }) * 0n; +}, "ToPrimitive: throw when skipping both valueOf and toString"); +assert.throws(TypeError, function() { + 0n * { + valueOf: function() { + return Object(1); + }, + toString: function() { + return Object(1); + } + }; +}, "ToPrimitive: throw when skipping both valueOf and toString"); +assert.throws(TypeError, function() { + ({ + valueOf: function() { + return {}; + }, + toString: function() { + return {}; + } + }) * 0n; +}, "ToPrimitive: throw when skipping both valueOf and toString"); +assert.throws(TypeError, function() { + 0n * { + valueOf: function() { + return {}; + }, + toString: function() { + return {}; + } + }; +}, "ToPrimitive: throw when skipping both valueOf and toString"); diff --git a/test/language/expressions/multiplication/bigint-wrapped-values.js b/test/language/expressions/multiplication/bigint-wrapped-values.js new file mode 100644 index 0000000000..2421ee83a7 --- /dev/null +++ b/test/language/expressions/multiplication/bigint-wrapped-values.js @@ -0,0 +1,40 @@ +// Copyright (C) 2017 Josh Wolfe. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +description: multiplication operator ToNumeric with BigInt operands +esid: sec-multiplicative-operators-runtime-semantics-evaluation +features: [BigInt, Symbol.toPrimitive, computed-property-names] +---*/ + +assert.sameValue(Object(2n) * 2n, 4n, "ToPrimitive: unbox object with internal slot"); +assert.sameValue(2n * Object(2n), 4n, "ToPrimitive: unbox object with internal slot"); +assert.sameValue(({ + [Symbol.toPrimitive]: function() { + return 2n; + } +}) * 2n, 4n, "ToPrimitive: @@toPrimitive"); +assert.sameValue(2n * { + [Symbol.toPrimitive]: function() { + return 2n; + } +}, 4n, "ToPrimitive: @@toPrimitive"); +assert.sameValue(({ + valueOf: function() { + return 2n; + } +}) * 2n, 4n, "ToPrimitive: valueOf"); +assert.sameValue(2n * { + valueOf: function() { + return 2n; + } +}, 4n, "ToPrimitive: valueOf"); +assert.sameValue(({ + toString: function() { + return 2n; + } +}) * 2n, 4n, "ToPrimitive: toString"); +assert.sameValue(2n * { + toString: function() { + return 2n; + } +}, 4n, "ToPrimitive: toString"); diff --git a/test/language/expressions/right-shift/bigint-errors.js b/test/language/expressions/right-shift/bigint-errors.js new file mode 100644 index 0000000000..c7c7371cd9 --- /dev/null +++ b/test/language/expressions/right-shift/bigint-errors.js @@ -0,0 +1,62 @@ +// Copyright (C) 2017 Josh Wolfe. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +description: right-shift operator ToNumeric with BigInt operands +esid: sec-signed-right-shift-operator-runtime-semantics-evaluation +features: [BigInt, Symbol, Symbol.toPrimitive, computed-property-names] +---*/ + +assert.throws(TypeError, function() { + Symbol("1") >> 0n; +}, "ToBigInt: Symbol => TypeError"); +assert.throws(TypeError, function() { + 0n >> Symbol("1"); +}, "ToBigInt: Symbol => TypeError"); +assert.throws(TypeError, function() { + Object(Symbol("1")) >> 0n; +}, "ToBigInt: unbox object with internal slot => Symbol => TypeError"); +assert.throws(TypeError, function() { + 0n >> Object(Symbol("1")); +}, "ToBigInt: unbox object with internal slot => Symbol => TypeError"); +assert.throws(TypeError, function() { + ({ + [Symbol.toPrimitive]: function() { + return Symbol("1"); + } + }) >> 0n; +}, "ToBigInt: @@toPrimitive => Symbol => TypeError"); +assert.throws(TypeError, function() { + 0n >> { + [Symbol.toPrimitive]: function() { + return Symbol("1"); + } + }; +}, "ToBigInt: @@toPrimitive => Symbol => TypeError"); +assert.throws(TypeError, function() { + ({ + valueOf: function() { + return Symbol("1"); + } + }) >> 0n; +}, "ToBigInt: valueOf => Symbol => TypeError"); +assert.throws(TypeError, function() { + 0n >> { + valueOf: function() { + return Symbol("1"); + } + }; +}, "ToBigInt: valueOf => Symbol => TypeError"); +assert.throws(TypeError, function() { + ({ + toString: function() { + return Symbol("1"); + } + }) >> 0n; +}, "ToBigInt: toString => Symbol => TypeError"); +assert.throws(TypeError, function() { + 0n >> { + toString: function() { + return Symbol("1"); + } + }; +}, "ToBigInt: toString => Symbol => TypeError"); diff --git a/test/language/expressions/right-shift/bigint-toprimitive.js b/test/language/expressions/right-shift/bigint-toprimitive.js new file mode 100644 index 0000000000..3d40f35b2d --- /dev/null +++ b/test/language/expressions/right-shift/bigint-toprimitive.js @@ -0,0 +1,308 @@ +// Copyright (C) 2017 Josh Wolfe. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +description: right-shift operator ToNumeric with BigInt operands +esid: sec-signed-right-shift-operator-runtime-semantics-evaluation +features: [BigInt, Symbol.toPrimitive, computed-property-names] +---*/ + +function err() { + throw new Test262Error(); +} + +function MyError() {} + +assert.sameValue(({ + [Symbol.toPrimitive]: function() { + return 2n; + }, + valueOf: err, + toString: err +}) >> 1n, 1n, "ToPrimitive: @@toPrimitive takes precedence"); +assert.sameValue(4n >> { + [Symbol.toPrimitive]: function() { + return 2n; + }, + valueOf: err, + toString: err +}, 1n, "ToPrimitive: @@toPrimitive takes precedence"); +assert.sameValue(({ + valueOf: function() { + return 2n; + }, + toString: err +}) >> 1n, 1n, "ToPrimitive: valueOf takes precedence over toString"); +assert.sameValue(4n >> { + valueOf: function() { + return 2n; + }, + toString: err +}, 1n, "ToPrimitive: valueOf takes precedence over toString"); +assert.sameValue(({ + toString: function() { + return 2n; + } +}) >> 1n, 1n, "ToPrimitive: toString with no valueOf"); +assert.sameValue(4n >> { + toString: function() { + return 2n; + } +}, 1n, "ToPrimitive: toString with no valueOf"); +assert.sameValue(({ + [Symbol.toPrimitive]: undefined, + valueOf: function() { + return 2n; + } +}) >> 1n, 1n, "ToPrimitive: skip @@toPrimitive when it's undefined"); +assert.sameValue(4n >> { + [Symbol.toPrimitive]: undefined, + valueOf: function() { + return 2n; + } +}, 1n, "ToPrimitive: skip @@toPrimitive when it's undefined"); +assert.sameValue(({ + [Symbol.toPrimitive]: null, + valueOf: function() { + return 2n; + } +}) >> 1n, 1n, "ToPrimitive: skip @@toPrimitive when it's null"); +assert.sameValue(4n >> { + [Symbol.toPrimitive]: null, + valueOf: function() { + return 2n; + } +}, 1n, "ToPrimitive: skip @@toPrimitive when it's null"); +assert.sameValue(({ + valueOf: null, + toString: function() { + return 2n; + } +}) >> 1n, 1n, "ToPrimitive: skip valueOf when it's not callable"); +assert.sameValue(4n >> { + valueOf: null, + toString: function() { + return 2n; + } +}, 1n, "ToPrimitive: skip valueOf when it's not callable"); +assert.sameValue(({ + valueOf: 1, + toString: function() { + return 2n; + } +}) >> 1n, 1n, "ToPrimitive: skip valueOf when it's not callable"); +assert.sameValue(4n >> { + valueOf: 1, + toString: function() { + return 2n; + } +}, 1n, "ToPrimitive: skip valueOf when it's not callable"); +assert.sameValue(({ + valueOf: {}, + toString: function() { + return 2n; + } +}) >> 1n, 1n, "ToPrimitive: skip valueOf when it's not callable"); +assert.sameValue(4n >> { + valueOf: {}, + toString: function() { + return 2n; + } +}, 1n, "ToPrimitive: skip valueOf when it's not callable"); +assert.sameValue(({ + valueOf: function() { + return {}; + }, + toString: function() { + return 2n; + } +}) >> 1n, 1n, "ToPrimitive: skip valueOf when it returns an object"); +assert.sameValue(4n >> { + valueOf: function() { + return {}; + }, + toString: function() { + return 2n; + } +}, 1n, "ToPrimitive: skip valueOf when it returns an object"); +assert.sameValue(({ + valueOf: function() { + return Object(12345); + }, + toString: function() { + return 2n; + } +}) >> 1n, 1n, "ToPrimitive: skip valueOf when it returns an object"); +assert.sameValue(4n >> { + valueOf: function() { + return Object(12345); + }, + toString: function() { + return 2n; + } +}, 1n, "ToPrimitive: skip valueOf when it returns an object"); +assert.throws(TypeError, function() { + ({ + [Symbol.toPrimitive]: 1 + }) >> 0n; +}, "ToPrimitive: throw when @@toPrimitive is not callable"); +assert.throws(TypeError, function() { + 0n >> { + [Symbol.toPrimitive]: 1 + }; +}, "ToPrimitive: throw when @@toPrimitive is not callable"); +assert.throws(TypeError, function() { + ({ + [Symbol.toPrimitive]: {} + }) >> 0n; +}, "ToPrimitive: throw when @@toPrimitive is not callable"); +assert.throws(TypeError, function() { + 0n >> { + [Symbol.toPrimitive]: {} + }; +}, "ToPrimitive: throw when @@toPrimitive is not callable"); +assert.throws(TypeError, function() { + ({ + [Symbol.toPrimitive]: function() { + return Object(1); + } + }) >> 0n; +}, "ToPrimitive: throw when @@toPrimitive returns an object"); +assert.throws(TypeError, function() { + 0n >> { + [Symbol.toPrimitive]: function() { + return Object(1); + } + }; +}, "ToPrimitive: throw when @@toPrimitive returns an object"); +assert.throws(TypeError, function() { + ({ + [Symbol.toPrimitive]: function() { + return {}; + } + }) >> 0n; +}, "ToPrimitive: throw when @@toPrimitive returns an object"); +assert.throws(TypeError, function() { + 0n >> { + [Symbol.toPrimitive]: function() { + return {}; + } + }; +}, "ToPrimitive: throw when @@toPrimitive returns an object"); +assert.throws(MyError, function() { + ({ + [Symbol.toPrimitive]: function() { + throw new MyError(); + } + }) >> 0n; +}, "ToPrimitive: propagate errors from @@toPrimitive"); +assert.throws(MyError, function() { + 0n >> { + [Symbol.toPrimitive]: function() { + throw new MyError(); + } + }; +}, "ToPrimitive: propagate errors from @@toPrimitive"); +assert.throws(MyError, function() { + ({ + valueOf: function() { + throw new MyError(); + } + }) >> 0n; +}, "ToPrimitive: propagate errors from valueOf"); +assert.throws(MyError, function() { + 0n >> { + valueOf: function() { + throw new MyError(); + } + }; +}, "ToPrimitive: propagate errors from valueOf"); +assert.throws(MyError, function() { + ({ + toString: function() { + throw new MyError(); + } + }) >> 0n; +}, "ToPrimitive: propagate errors from toString"); +assert.throws(MyError, function() { + 0n >> { + toString: function() { + throw new MyError(); + } + }; +}, "ToPrimitive: propagate errors from toString"); +assert.throws(TypeError, function() { + ({ + valueOf: null, + toString: null + }) >> 0n; +}, "ToPrimitive: throw when skipping both valueOf and toString"); +assert.throws(TypeError, function() { + 0n >> { + valueOf: null, + toString: null + }; +}, "ToPrimitive: throw when skipping both valueOf and toString"); +assert.throws(TypeError, function() { + ({ + valueOf: 1, + toString: 1 + }) >> 0n; +}, "ToPrimitive: throw when skipping both valueOf and toString"); +assert.throws(TypeError, function() { + 0n >> { + valueOf: 1, + toString: 1 + }; +}, "ToPrimitive: throw when skipping both valueOf and toString"); +assert.throws(TypeError, function() { + ({ + valueOf: {}, + toString: {} + }) >> 0n; +}, "ToPrimitive: throw when skipping both valueOf and toString"); +assert.throws(TypeError, function() { + 0n >> { + valueOf: {}, + toString: {} + }; +}, "ToPrimitive: throw when skipping both valueOf and toString"); +assert.throws(TypeError, function() { + ({ + valueOf: function() { + return Object(1); + }, + toString: function() { + return Object(1); + } + }) >> 0n; +}, "ToPrimitive: throw when skipping both valueOf and toString"); +assert.throws(TypeError, function() { + 0n >> { + valueOf: function() { + return Object(1); + }, + toString: function() { + return Object(1); + } + }; +}, "ToPrimitive: throw when skipping both valueOf and toString"); +assert.throws(TypeError, function() { + ({ + valueOf: function() { + return {}; + }, + toString: function() { + return {}; + } + }) >> 0n; +}, "ToPrimitive: throw when skipping both valueOf and toString"); +assert.throws(TypeError, function() { + 0n >> { + valueOf: function() { + return {}; + }, + toString: function() { + return {}; + } + }; +}, "ToPrimitive: throw when skipping both valueOf and toString"); diff --git a/test/language/expressions/right-shift/bigint-wrapped-values.js b/test/language/expressions/right-shift/bigint-wrapped-values.js new file mode 100644 index 0000000000..dd0069afb8 --- /dev/null +++ b/test/language/expressions/right-shift/bigint-wrapped-values.js @@ -0,0 +1,40 @@ +// Copyright (C) 2017 Josh Wolfe. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +description: right-shift operator ToNumeric with BigInt operands +esid: sec-signed-right-shift-operator-runtime-semantics-evaluation +features: [BigInt, Symbol.toPrimitive, computed-property-names] +---*/ + +assert.sameValue(Object(2n) >> 1n, 1n, "ToPrimitive: unbox object with internal slot"); +assert.sameValue(4n >> Object(2n), 1n, "ToPrimitive: unbox object with internal slot"); +assert.sameValue(({ + [Symbol.toPrimitive]: function() { + return 2n; + } +}) >> 1n, 1n, "ToPrimitive: @@toPrimitive"); +assert.sameValue(4n >> { + [Symbol.toPrimitive]: function() { + return 2n; + } +}, 1n, "ToPrimitive: @@toPrimitive"); +assert.sameValue(({ + valueOf: function() { + return 2n; + } +}) >> 1n, 1n, "ToPrimitive: valueOf"); +assert.sameValue(4n >> { + valueOf: function() { + return 2n; + } +}, 1n, "ToPrimitive: valueOf"); +assert.sameValue(({ + toString: function() { + return 2n; + } +}) >> 1n, 1n, "ToPrimitive: toString"); +assert.sameValue(4n >> { + toString: function() { + return 2n; + } +}, 1n, "ToPrimitive: toString"); diff --git a/test/language/expressions/subtraction/bigint-errors.js b/test/language/expressions/subtraction/bigint-errors.js new file mode 100644 index 0000000000..b512c78ad5 --- /dev/null +++ b/test/language/expressions/subtraction/bigint-errors.js @@ -0,0 +1,62 @@ +// Copyright (C) 2017 Josh Wolfe. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +description: subtraction operator ToNumeric with BigInt operands +esid: sec-subtraction-operator-minus-runtime-semantics-evaluation +features: [BigInt, Symbol, Symbol.toPrimitive, computed-property-names] +---*/ + +assert.throws(TypeError, function() { + Symbol("1") - 0n; +}, "ToBigInt: Symbol => TypeError"); +assert.throws(TypeError, function() { + 0n - Symbol("1"); +}, "ToBigInt: Symbol => TypeError"); +assert.throws(TypeError, function() { + Object(Symbol("1")) - 0n; +}, "ToBigInt: unbox object with internal slot => Symbol => TypeError"); +assert.throws(TypeError, function() { + 0n - Object(Symbol("1")); +}, "ToBigInt: unbox object with internal slot => Symbol => TypeError"); +assert.throws(TypeError, function() { + ({ + [Symbol.toPrimitive]: function() { + return Symbol("1"); + } + }) - 0n; +}, "ToBigInt: @@toPrimitive => Symbol => TypeError"); +assert.throws(TypeError, function() { + 0n - { + [Symbol.toPrimitive]: function() { + return Symbol("1"); + } + }; +}, "ToBigInt: @@toPrimitive => Symbol => TypeError"); +assert.throws(TypeError, function() { + ({ + valueOf: function() { + return Symbol("1"); + } + }) - 0n; +}, "ToBigInt: valueOf => Symbol => TypeError"); +assert.throws(TypeError, function() { + 0n - { + valueOf: function() { + return Symbol("1"); + } + }; +}, "ToBigInt: valueOf => Symbol => TypeError"); +assert.throws(TypeError, function() { + ({ + toString: function() { + return Symbol("1"); + } + }) - 0n; +}, "ToBigInt: toString => Symbol => TypeError"); +assert.throws(TypeError, function() { + 0n - { + toString: function() { + return Symbol("1"); + } + }; +}, "ToBigInt: toString => Symbol => TypeError"); diff --git a/test/language/expressions/subtraction/bigint-toprimitive.js b/test/language/expressions/subtraction/bigint-toprimitive.js new file mode 100644 index 0000000000..70da440dd2 --- /dev/null +++ b/test/language/expressions/subtraction/bigint-toprimitive.js @@ -0,0 +1,308 @@ +// Copyright (C) 2017 Josh Wolfe. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +description: subtraction operator ToNumeric with BigInt operands +esid: sec-subtraction-operator-minus-runtime-semantics-evaluation +features: [BigInt, Symbol.toPrimitive, computed-property-names] +---*/ + +function err() { + throw new Test262Error(); +} + +function MyError() {} + +assert.sameValue(({ + [Symbol.toPrimitive]: function() { + return 2n; + }, + valueOf: err, + toString: err +}) - 1n, 1n, "ToPrimitive: @@toPrimitive takes precedence"); +assert.sameValue(3n - { + [Symbol.toPrimitive]: function() { + return 2n; + }, + valueOf: err, + toString: err +}, 1n, "ToPrimitive: @@toPrimitive takes precedence"); +assert.sameValue(({ + valueOf: function() { + return 2n; + }, + toString: err +}) - 1n, 1n, "ToPrimitive: valueOf takes precedence over toString"); +assert.sameValue(3n - { + valueOf: function() { + return 2n; + }, + toString: err +}, 1n, "ToPrimitive: valueOf takes precedence over toString"); +assert.sameValue(({ + toString: function() { + return 2n; + } +}) - 1n, 1n, "ToPrimitive: toString with no valueOf"); +assert.sameValue(3n - { + toString: function() { + return 2n; + } +}, 1n, "ToPrimitive: toString with no valueOf"); +assert.sameValue(({ + [Symbol.toPrimitive]: undefined, + valueOf: function() { + return 2n; + } +}) - 1n, 1n, "ToPrimitive: skip @@toPrimitive when it's undefined"); +assert.sameValue(3n - { + [Symbol.toPrimitive]: undefined, + valueOf: function() { + return 2n; + } +}, 1n, "ToPrimitive: skip @@toPrimitive when it's undefined"); +assert.sameValue(({ + [Symbol.toPrimitive]: null, + valueOf: function() { + return 2n; + } +}) - 1n, 1n, "ToPrimitive: skip @@toPrimitive when it's null"); +assert.sameValue(3n - { + [Symbol.toPrimitive]: null, + valueOf: function() { + return 2n; + } +}, 1n, "ToPrimitive: skip @@toPrimitive when it's null"); +assert.sameValue(({ + valueOf: null, + toString: function() { + return 2n; + } +}) - 1n, 1n, "ToPrimitive: skip valueOf when it's not callable"); +assert.sameValue(3n - { + valueOf: null, + toString: function() { + return 2n; + } +}, 1n, "ToPrimitive: skip valueOf when it's not callable"); +assert.sameValue(({ + valueOf: 1, + toString: function() { + return 2n; + } +}) - 1n, 1n, "ToPrimitive: skip valueOf when it's not callable"); +assert.sameValue(3n - { + valueOf: 1, + toString: function() { + return 2n; + } +}, 1n, "ToPrimitive: skip valueOf when it's not callable"); +assert.sameValue(({ + valueOf: {}, + toString: function() { + return 2n; + } +}) - 1n, 1n, "ToPrimitive: skip valueOf when it's not callable"); +assert.sameValue(3n - { + valueOf: {}, + toString: function() { + return 2n; + } +}, 1n, "ToPrimitive: skip valueOf when it's not callable"); +assert.sameValue(({ + valueOf: function() { + return {}; + }, + toString: function() { + return 2n; + } +}) - 1n, 1n, "ToPrimitive: skip valueOf when it returns an object"); +assert.sameValue(3n - { + valueOf: function() { + return {}; + }, + toString: function() { + return 2n; + } +}, 1n, "ToPrimitive: skip valueOf when it returns an object"); +assert.sameValue(({ + valueOf: function() { + return Object(12345); + }, + toString: function() { + return 2n; + } +}) - 1n, 1n, "ToPrimitive: skip valueOf when it returns an object"); +assert.sameValue(3n - { + valueOf: function() { + return Object(12345); + }, + toString: function() { + return 2n; + } +}, 1n, "ToPrimitive: skip valueOf when it returns an object"); +assert.throws(TypeError, function() { + ({ + [Symbol.toPrimitive]: 1 + }) - 0n; +}, "ToPrimitive: throw when @@toPrimitive is not callable"); +assert.throws(TypeError, function() { + 0n - { + [Symbol.toPrimitive]: 1 + }; +}, "ToPrimitive: throw when @@toPrimitive is not callable"); +assert.throws(TypeError, function() { + ({ + [Symbol.toPrimitive]: {} + }) - 0n; +}, "ToPrimitive: throw when @@toPrimitive is not callable"); +assert.throws(TypeError, function() { + 0n - { + [Symbol.toPrimitive]: {} + }; +}, "ToPrimitive: throw when @@toPrimitive is not callable"); +assert.throws(TypeError, function() { + ({ + [Symbol.toPrimitive]: function() { + return Object(1); + } + }) - 0n; +}, "ToPrimitive: throw when @@toPrimitive returns an object"); +assert.throws(TypeError, function() { + 0n - { + [Symbol.toPrimitive]: function() { + return Object(1); + } + }; +}, "ToPrimitive: throw when @@toPrimitive returns an object"); +assert.throws(TypeError, function() { + ({ + [Symbol.toPrimitive]: function() { + return {}; + } + }) - 0n; +}, "ToPrimitive: throw when @@toPrimitive returns an object"); +assert.throws(TypeError, function() { + 0n - { + [Symbol.toPrimitive]: function() { + return {}; + } + }; +}, "ToPrimitive: throw when @@toPrimitive returns an object"); +assert.throws(MyError, function() { + ({ + [Symbol.toPrimitive]: function() { + throw new MyError(); + } + }) - 0n; +}, "ToPrimitive: propagate errors from @@toPrimitive"); +assert.throws(MyError, function() { + 0n - { + [Symbol.toPrimitive]: function() { + throw new MyError(); + } + }; +}, "ToPrimitive: propagate errors from @@toPrimitive"); +assert.throws(MyError, function() { + ({ + valueOf: function() { + throw new MyError(); + } + }) - 0n; +}, "ToPrimitive: propagate errors from valueOf"); +assert.throws(MyError, function() { + 0n - { + valueOf: function() { + throw new MyError(); + } + }; +}, "ToPrimitive: propagate errors from valueOf"); +assert.throws(MyError, function() { + ({ + toString: function() { + throw new MyError(); + } + }) - 0n; +}, "ToPrimitive: propagate errors from toString"); +assert.throws(MyError, function() { + 0n - { + toString: function() { + throw new MyError(); + } + }; +}, "ToPrimitive: propagate errors from toString"); +assert.throws(TypeError, function() { + ({ + valueOf: null, + toString: null + }) - 0n; +}, "ToPrimitive: throw when skipping both valueOf and toString"); +assert.throws(TypeError, function() { + 0n - { + valueOf: null, + toString: null + }; +}, "ToPrimitive: throw when skipping both valueOf and toString"); +assert.throws(TypeError, function() { + ({ + valueOf: 1, + toString: 1 + }) - 0n; +}, "ToPrimitive: throw when skipping both valueOf and toString"); +assert.throws(TypeError, function() { + 0n - { + valueOf: 1, + toString: 1 + }; +}, "ToPrimitive: throw when skipping both valueOf and toString"); +assert.throws(TypeError, function() { + ({ + valueOf: {}, + toString: {} + }) - 0n; +}, "ToPrimitive: throw when skipping both valueOf and toString"); +assert.throws(TypeError, function() { + 0n - { + valueOf: {}, + toString: {} + }; +}, "ToPrimitive: throw when skipping both valueOf and toString"); +assert.throws(TypeError, function() { + ({ + valueOf: function() { + return Object(1); + }, + toString: function() { + return Object(1); + } + }) - 0n; +}, "ToPrimitive: throw when skipping both valueOf and toString"); +assert.throws(TypeError, function() { + 0n - { + valueOf: function() { + return Object(1); + }, + toString: function() { + return Object(1); + } + }; +}, "ToPrimitive: throw when skipping both valueOf and toString"); +assert.throws(TypeError, function() { + ({ + valueOf: function() { + return {}; + }, + toString: function() { + return {}; + } + }) - 0n; +}, "ToPrimitive: throw when skipping both valueOf and toString"); +assert.throws(TypeError, function() { + 0n - { + valueOf: function() { + return {}; + }, + toString: function() { + return {}; + } + }; +}, "ToPrimitive: throw when skipping both valueOf and toString"); diff --git a/test/language/expressions/subtraction/bigint-wrapped-values.js b/test/language/expressions/subtraction/bigint-wrapped-values.js new file mode 100644 index 0000000000..f75ea687fa --- /dev/null +++ b/test/language/expressions/subtraction/bigint-wrapped-values.js @@ -0,0 +1,40 @@ +// Copyright (C) 2017 Josh Wolfe. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +description: subtraction operator ToNumeric with BigInt operands +esid: sec-subtraction-operator-minus-runtime-semantics-evaluation +features: [BigInt, Symbol.toPrimitive, computed-property-names] +---*/ + +assert.sameValue(Object(2n) - 1n, 1n, "ToPrimitive: unbox object with internal slot"); +assert.sameValue(3n - Object(2n), 1n, "ToPrimitive: unbox object with internal slot"); +assert.sameValue(({ + [Symbol.toPrimitive]: function() { + return 2n; + } +}) - 1n, 1n, "ToPrimitive: @@toPrimitive"); +assert.sameValue(3n - { + [Symbol.toPrimitive]: function() { + return 2n; + } +}, 1n, "ToPrimitive: @@toPrimitive"); +assert.sameValue(({ + valueOf: function() { + return 2n; + } +}) - 1n, 1n, "ToPrimitive: valueOf"); +assert.sameValue(3n - { + valueOf: function() { + return 2n; + } +}, 1n, "ToPrimitive: valueOf"); +assert.sameValue(({ + toString: function() { + return 2n; + } +}) - 1n, 1n, "ToPrimitive: toString"); +assert.sameValue(3n - { + toString: function() { + return 2n; + } +}, 1n, "ToPrimitive: toString"); diff --git a/test/language/expressions/unsigned-right-shift/bigint-errors.js b/test/language/expressions/unsigned-right-shift/bigint-errors.js new file mode 100644 index 0000000000..47d9db0641 --- /dev/null +++ b/test/language/expressions/unsigned-right-shift/bigint-errors.js @@ -0,0 +1,63 @@ +// Copyright (C) 2017 Josh Wolfe. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +description: unsigned-right-shift operator ToNumeric with BigInt operands +esid: sec-unsigned-right-shift-operator-runtime-semantics-evaluation +info: After ToNumeric type coercion, unsigned-right-shift always throws for BigInt operands +features: [BigInt, Symbol, Symbol.toPrimitive, computed-property-names] +---*/ + +assert.throws(TypeError, function() { + Symbol("1") >>> 0n; +}, "ToBigInt: Symbol => TypeError"); +assert.throws(TypeError, function() { + 0n >>> Symbol("1"); +}, "ToBigInt: Symbol => TypeError"); +assert.throws(TypeError, function() { + Object(Symbol("1")) >>> 0n; +}, "ToBigInt: unbox object with internal slot => Symbol => TypeError"); +assert.throws(TypeError, function() { + 0n >>> Object(Symbol("1")); +}, "ToBigInt: unbox object with internal slot => Symbol => TypeError"); +assert.throws(TypeError, function() { + ({ + [Symbol.toPrimitive]: function() { + return Symbol("1"); + } + }) >>> 0n; +}, "ToBigInt: @@toPrimitive => Symbol => TypeError"); +assert.throws(TypeError, function() { + 0n >>> { + [Symbol.toPrimitive]: function() { + return Symbol("1"); + } + }; +}, "ToBigInt: @@toPrimitive => Symbol => TypeError"); +assert.throws(TypeError, function() { + ({ + valueOf: function() { + return Symbol("1"); + } + }) >>> 0n; +}, "ToBigInt: valueOf => Symbol => TypeError"); +assert.throws(TypeError, function() { + 0n >>> { + valueOf: function() { + return Symbol("1"); + } + }; +}, "ToBigInt: valueOf => Symbol => TypeError"); +assert.throws(TypeError, function() { + ({ + toString: function() { + return Symbol("1"); + } + }) >>> 0n; +}, "ToBigInt: toString => Symbol => TypeError"); +assert.throws(TypeError, function() { + 0n >>> { + toString: function() { + return Symbol("1"); + } + }; +}, "ToBigInt: toString => Symbol => TypeError"); diff --git a/test/language/expressions/unsigned-right-shift/bigint-toprimitive.js b/test/language/expressions/unsigned-right-shift/bigint-toprimitive.js new file mode 100644 index 0000000000..5d8c00d776 --- /dev/null +++ b/test/language/expressions/unsigned-right-shift/bigint-toprimitive.js @@ -0,0 +1,349 @@ +// Copyright (C) 2017 Josh Wolfe. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +description: unsigned-right-shift operator ToNumeric with BigInt operands +esid: sec-unsigned-right-shift-operator-runtime-semantics-evaluation +info: After ToNumeric type coercion, unsigned-right-shift always throws for BigInt operands +features: [BigInt, Symbol.toPrimitive, computed-property-names] +---*/ + +function err() { + throw new Test262Error(); +} + +function MyError() {} + +assert.throws(TypeError, function() { + ({ + [Symbol.toPrimitive]: function() { + return 2n; + }, + valueOf: err, + toString: err + }) >>> 0n; +}, "ToPrimitive: @@toPrimitive takes precedence"); +assert.throws(TypeError, function() { + 0n >>> { + [Symbol.toPrimitive]: function() { + return 2n; + }, + valueOf: err, + toString: err + }; +}, "ToPrimitive: @@toPrimitive takes precedence"); +assert.throws(TypeError, function() { + ({ + valueOf: function() { + return 2n; + }, + toString: err + }) >>> 0n; +}, "ToPrimitive: valueOf takes precedence over toString"); +assert.throws(TypeError, function() { + 0n >>> { + valueOf: function() { + return 2n; + }, + toString: err + }; +}, "ToPrimitive: valueOf takes precedence over toString"); +assert.throws(TypeError, function() { + ({ + toString: function() { + return 2n; + } + }) >>> 0n; +}, "ToPrimitive: toString with no valueOf"); +assert.throws(TypeError, function() { + 0n >>> { + toString: function() { + return 2n; + } + }; +}, "ToPrimitive: toString with no valueOf"); +assert.throws(TypeError, function() { + ({ + [Symbol.toPrimitive]: undefined, + valueOf: function() { + return 2n; + } + }) >>> 0n; +}, "ToPrimitive: skip @@toPrimitive when it's undefined"); +assert.throws(TypeError, function() { + 0n >>> { + [Symbol.toPrimitive]: undefined, + valueOf: function() { + return 2n; + } + }; +}, "ToPrimitive: skip @@toPrimitive when it's undefined"); +assert.throws(TypeError, function() { + ({ + [Symbol.toPrimitive]: null, + valueOf: function() { + return 2n; + } + }) >>> 0n; +}, "ToPrimitive: skip @@toPrimitive when it's null"); +assert.throws(TypeError, function() { + 0n >>> { + [Symbol.toPrimitive]: null, + valueOf: function() { + return 2n; + } + }; +}, "ToPrimitive: skip @@toPrimitive when it's null"); +assert.throws(TypeError, function() { + ({ + valueOf: null, + toString: function() { + return 2n; + } + }) >>> 0n; +}, "ToPrimitive: skip valueOf when it's not callable"); +assert.throws(TypeError, function() { + 0n >>> { + valueOf: null, + toString: function() { + return 2n; + } + }; +}, "ToPrimitive: skip valueOf when it's not callable"); +assert.throws(TypeError, function() { + ({ + valueOf: 1, + toString: function() { + return 2n; + } + }) >>> 0n; +}, "ToPrimitive: skip valueOf when it's not callable"); +assert.throws(TypeError, function() { + 0n >>> { + valueOf: 1, + toString: function() { + return 2n; + } + }; +}, "ToPrimitive: skip valueOf when it's not callable"); +assert.throws(TypeError, function() { + ({ + valueOf: {}, + toString: function() { + return 2n; + } + }) >>> 0n; +}, "ToPrimitive: skip valueOf when it's not callable"); +assert.throws(TypeError, function() { + 0n >>> { + valueOf: {}, + toString: function() { + return 2n; + } + }; +}, "ToPrimitive: skip valueOf when it's not callable"); +assert.throws(TypeError, function() { + ({ + valueOf: function() { + return {}; + }, + toString: function() { + return 2n; + } + }) >>> 0n; +}, "ToPrimitive: skip valueOf when it returns an object"); +assert.throws(TypeError, function() { + 0n >>> { + valueOf: function() { + return {}; + }, + toString: function() { + return 2n; + } + }; +}, "ToPrimitive: skip valueOf when it returns an object"); +assert.throws(TypeError, function() { + ({ + valueOf: function() { + return Object(12345); + }, + toString: function() { + return 2n; + } + }) >>> 0n; +}, "ToPrimitive: skip valueOf when it returns an object"); +assert.throws(TypeError, function() { + 0n >>> { + valueOf: function() { + return Object(12345); + }, + toString: function() { + return 2n; + } + }; +}, "ToPrimitive: skip valueOf when it returns an object"); +assert.throws(TypeError, function() { + ({ + [Symbol.toPrimitive]: 1 + }) >>> 0n; +}, "ToPrimitive: throw when @@toPrimitive is not callable"); +assert.throws(TypeError, function() { + 0n >>> { + [Symbol.toPrimitive]: 1 + }; +}, "ToPrimitive: throw when @@toPrimitive is not callable"); +assert.throws(TypeError, function() { + ({ + [Symbol.toPrimitive]: {} + }) >>> 0n; +}, "ToPrimitive: throw when @@toPrimitive is not callable"); +assert.throws(TypeError, function() { + 0n >>> { + [Symbol.toPrimitive]: {} + }; +}, "ToPrimitive: throw when @@toPrimitive is not callable"); +assert.throws(TypeError, function() { + ({ + [Symbol.toPrimitive]: function() { + return Object(1); + } + }) >>> 0n; +}, "ToPrimitive: throw when @@toPrimitive returns an object"); +assert.throws(TypeError, function() { + 0n >>> { + [Symbol.toPrimitive]: function() { + return Object(1); + } + }; +}, "ToPrimitive: throw when @@toPrimitive returns an object"); +assert.throws(TypeError, function() { + ({ + [Symbol.toPrimitive]: function() { + return {}; + } + }) >>> 0n; +}, "ToPrimitive: throw when @@toPrimitive returns an object"); +assert.throws(TypeError, function() { + 0n >>> { + [Symbol.toPrimitive]: function() { + return {}; + } + }; +}, "ToPrimitive: throw when @@toPrimitive returns an object"); +assert.throws(MyError, function() { + ({ + [Symbol.toPrimitive]: function() { + throw new MyError(); + } + }) >>> 0n; +}, "ToPrimitive: propagate errors from @@toPrimitive"); +assert.throws(MyError, function() { + 0n >>> { + [Symbol.toPrimitive]: function() { + throw new MyError(); + } + }; +}, "ToPrimitive: propagate errors from @@toPrimitive"); +assert.throws(MyError, function() { + ({ + valueOf: function() { + throw new MyError(); + } + }) >>> 0n; +}, "ToPrimitive: propagate errors from valueOf"); +assert.throws(MyError, function() { + 0n >>> { + valueOf: function() { + throw new MyError(); + } + }; +}, "ToPrimitive: propagate errors from valueOf"); +assert.throws(MyError, function() { + ({ + toString: function() { + throw new MyError(); + } + }) >>> 0n; +}, "ToPrimitive: propagate errors from toString"); +assert.throws(MyError, function() { + 0n >>> { + toString: function() { + throw new MyError(); + } + }; +}, "ToPrimitive: propagate errors from toString"); +assert.throws(TypeError, function() { + ({ + valueOf: null, + toString: null + }) >>> 0n; +}, "ToPrimitive: throw when skipping both valueOf and toString"); +assert.throws(TypeError, function() { + 0n >>> { + valueOf: null, + toString: null + }; +}, "ToPrimitive: throw when skipping both valueOf and toString"); +assert.throws(TypeError, function() { + ({ + valueOf: 1, + toString: 1 + }) >>> 0n; +}, "ToPrimitive: throw when skipping both valueOf and toString"); +assert.throws(TypeError, function() { + 0n >>> { + valueOf: 1, + toString: 1 + }; +}, "ToPrimitive: throw when skipping both valueOf and toString"); +assert.throws(TypeError, function() { + ({ + valueOf: {}, + toString: {} + }) >>> 0n; +}, "ToPrimitive: throw when skipping both valueOf and toString"); +assert.throws(TypeError, function() { + 0n >>> { + valueOf: {}, + toString: {} + }; +}, "ToPrimitive: throw when skipping both valueOf and toString"); +assert.throws(TypeError, function() { + ({ + valueOf: function() { + return Object(1); + }, + toString: function() { + return Object(1); + } + }) >>> 0n; +}, "ToPrimitive: throw when skipping both valueOf and toString"); +assert.throws(TypeError, function() { + 0n >>> { + valueOf: function() { + return Object(1); + }, + toString: function() { + return Object(1); + } + }; +}, "ToPrimitive: throw when skipping both valueOf and toString"); +assert.throws(TypeError, function() { + ({ + valueOf: function() { + return {}; + }, + toString: function() { + return {}; + } + }) >>> 0n; +}, "ToPrimitive: throw when skipping both valueOf and toString"); +assert.throws(TypeError, function() { + 0n >>> { + valueOf: function() { + return {}; + }, + toString: function() { + return {}; + } + }; +}, "ToPrimitive: throw when skipping both valueOf and toString"); diff --git a/test/language/expressions/unsigned-right-shift/bigint-wrapped-values.js b/test/language/expressions/unsigned-right-shift/bigint-wrapped-values.js new file mode 100644 index 0000000000..526bce6373 --- /dev/null +++ b/test/language/expressions/unsigned-right-shift/bigint-wrapped-values.js @@ -0,0 +1,57 @@ +// Copyright (C) 2017 Josh Wolfe. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +description: unsigned-right-shift operator ToNumeric with BigInt operands +esid: sec-unsigned-right-shift-operator-runtime-semantics-evaluation +info: After ToNumeric type coercion, unsigned-right-shift always throws for BigInt operands +features: [BigInt, Symbol.toPrimitive, computed-property-names] +---*/ + +assert.throws(TypeError, function() { + Object(2n) >>> 0n; +}, "ToPrimitive: unbox object with internal slot"); +assert.throws(TypeError, function() { + 0n >>> Object(2n); +}, "ToPrimitive: unbox object with internal slot"); +assert.throws(TypeError, function() { + ({ + [Symbol.toPrimitive]: function() { + return 2n; + } + }) >>> 0n; +}, "ToPrimitive: @@toPrimitive"); +assert.throws(TypeError, function() { + 0n >>> { + [Symbol.toPrimitive]: function() { + return 2n; + } + }; +}, "ToPrimitive: @@toPrimitive"); +assert.throws(TypeError, function() { + ({ + valueOf: function() { + return 2n; + } + }) >>> 0n; +}, "ToPrimitive: valueOf"); +assert.throws(TypeError, function() { + 0n >>> { + valueOf: function() { + return 2n; + } + }; +}, "ToPrimitive: valueOf"); +assert.throws(TypeError, function() { + ({ + toString: function() { + return 2n; + } + }) >>> 0n; +}, "ToPrimitive: toString"); +assert.throws(TypeError, function() { + 0n >>> { + toString: function() { + return 2n; + } + }; +}, "ToPrimitive: toString");