From b4f121d866c6669ab5c6f33fc95fe158cfd9edb9 Mon Sep 17 00:00:00 2001
From: Josh Wolfe <jwolfe@igalia.com>
Date: Mon, 23 Oct 2017 21:38:43 -0700
Subject: [PATCH] BigInt bitshift operators

---
 .../left-shift/bigint-non-primitive.js        |  50 ++++++++
 .../language/expressions/left-shift/bigint.js | 108 ++++++++++++++++
 .../right-shift/bigint-non-primitive.js       |  50 ++++++++
 .../expressions/right-shift/bigint.js         | 115 ++++++++++++++++++
 .../bigint-non-primitive.js                   |  56 +++++++++
 .../unsigned-right-shift/bigint.js            |  64 ++++++++++
 6 files changed, 443 insertions(+)
 create mode 100644 test/language/expressions/left-shift/bigint-non-primitive.js
 create mode 100644 test/language/expressions/left-shift/bigint.js
 create mode 100644 test/language/expressions/right-shift/bigint-non-primitive.js
 create mode 100644 test/language/expressions/right-shift/bigint.js
 create mode 100644 test/language/expressions/unsigned-right-shift/bigint-non-primitive.js
 create mode 100644 test/language/expressions/unsigned-right-shift/bigint.js

diff --git a/test/language/expressions/left-shift/bigint-non-primitive.js b/test/language/expressions/left-shift/bigint-non-primitive.js
new file mode 100644
index 0000000000..ffa3405a96
--- /dev/null
+++ b/test/language/expressions/left-shift/bigint-non-primitive.js
@@ -0,0 +1,50 @@
+// Copyright (C) 2017 Josh Wolfe. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+description: Left shift for non-primitive BigInt values
+esid: sec-left-shift-operator-runtime-semantics-evaluation
+info: |
+  ShiftExpression : ShiftExpression << AdditiveExpression
+
+  1. Let lref be the result of evaluating ShiftExpression.
+  2. Let lval be ? GetValue(lref).
+  3. Let rref be the result of evaluating AdditiveExpression.
+  4. Let rval be ? GetValue(rref).
+  5. Let lnum be ? ToNumeric(lval).
+  6. Let rnum be ? ToNumeric(rval).
+  7. If Type(lnum) does not equal Type(rnum), throw a TypeError exception.
+  8. Let T be Type(lnum).
+  9. Return T::leftShift(lnum, rnum).
+
+features: [BigInt, Symbol.toPrimitive]
+---*/
+
+assert.sameValue(Object(0b101n) << 1n, 0b1010n, "Object(0b101n) << 1n === 0b1010n");
+assert.sameValue(Object(0b101n) << Object(1n), 0b1010n, "Object(0b101n) << Object(1n) === 0b1010n");
+
+function err() {
+  throw new Test262Error();
+}
+
+assert.sameValue(
+  {[Symbol.toPrimitive]: function() { return 0b101n; }, valueOf: err, toString: err} << 1n, 0b1010n,
+  "primitive from @@toPrimitive");
+assert.sameValue(
+  {valueOf: function() { return 0b101n; }, toString: err} << 1n, 0b1010n,
+  "primitive from {}.valueOf");
+assert.sameValue(
+  {toString: function() { return 0b101n; }} << 1n, 0b1010n,
+  "primitive from {}.toString");
+assert.sameValue(
+  0b101n << {[Symbol.toPrimitive]: function() { return 1n; }, valueOf: err, toString: err}, 0b1010n,
+  "primitive from @@toPrimitive");
+assert.sameValue(
+  0b101n << {valueOf: function() { return 1n; }, toString: err}, 0b1010n,
+  "primitive from {}.valueOf");
+assert.sameValue(
+  0b101n << {toString: function() { return 1n; }}, 0b1010n,
+  "primitive from {}.toString");
+assert.sameValue(
+  {valueOf: function() { return 0b101n; }} << {valueOf: function() { return 1n; }}, 0b1010n,
+  "primitive from {}.valueOf");
diff --git a/test/language/expressions/left-shift/bigint.js b/test/language/expressions/left-shift/bigint.js
new file mode 100644
index 0000000000..c325670416
--- /dev/null
+++ b/test/language/expressions/left-shift/bigint.js
@@ -0,0 +1,108 @@
+// Copyright (C) 2017 Josh Wolfe. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+description: Left shift for BigInt values
+esid: sec-numeric-types-bigint-leftShift
+info: |
+  BigInt::leftShift (x, y)
+
+  The abstract operation BigInt::leftShift with two arguments x and y of BigInt:
+
+  1. If y < 0,
+    a. Return a BigInt representing x divided by 2-y, rounding down to the nearest integer, including for negative numbers.
+  2. Return a BigInt representing x multiplied by 2y.
+
+  NOTE: Semantics here should be equivalent to a bitwise shift, treating the BigInt as an infinite length string of binary two's complement digits.
+
+features: [BigInt]
+---*/
+
+assert.sameValue(0n << 0n, 0n, "0n << 0n === 0n");
+assert.sameValue(0b101n << 1n, 0b1010n, "0b101n << 1n === 0b1010n");
+assert.sameValue(0b101n << 2n, 0b10100n, "0b101n << 2n === 0b10100n");
+assert.sameValue(0b101n << 3n, 0b101000n, "0b101n << 3n === 0b101000n");
+assert.sameValue(0b101n << -1n, 0b10n, "0b101n << -1n === 0b10n");
+assert.sameValue(0b101n << -2n, 1n, "0b101n << -2n === 1n");
+assert.sameValue(0b101n << -3n, 0n, "0b101n << -3n === 0n");
+assert.sameValue(0n << 128n, 0n, "0n << 128n === 0n");
+assert.sameValue(0n << -128n, 0n, "0n << -128n === 0n");
+assert.sameValue(0x246n << 0n, 0x246n, "0x246n << 0n === 0x246n");
+assert.sameValue(0x246n << 127n, 0x12300000000000000000000000000000000n, "0x246n << 127n === 0x12300000000000000000000000000000000n");
+assert.sameValue(0x246n << 128n, 0x24600000000000000000000000000000000n, "0x246n << 128n === 0x24600000000000000000000000000000000n");
+assert.sameValue(0x246n << 129n, 0x48c00000000000000000000000000000000n, "0x246n << 129n === 0x48c00000000000000000000000000000000n");
+assert.sameValue(0x246n << -128n, 0n, "0x246n << -128n === 0n");
+assert.sameValue(
+  0x123456789abcdef0fedcba9876543212345678n << 64n, 0x123456789abcdef0fedcba98765432123456780000000000000000n,
+  "0x123456789abcdef0fedcba9876543212345678n << 64n === 0x123456789abcdef0fedcba98765432123456780000000000000000n");
+assert.sameValue(
+  0x123456789abcdef0fedcba9876543212345678n << 32n, 0x123456789abcdef0fedcba987654321234567800000000n,
+  "0x123456789abcdef0fedcba9876543212345678n << 32n === 0x123456789abcdef0fedcba987654321234567800000000n");
+assert.sameValue(
+  0x123456789abcdef0fedcba9876543212345678n << 16n, 0x123456789abcdef0fedcba98765432123456780000n,
+  "0x123456789abcdef0fedcba9876543212345678n << 16n === 0x123456789abcdef0fedcba98765432123456780000n");
+assert.sameValue(
+  0x123456789abcdef0fedcba9876543212345678n << 0n, 0x123456789abcdef0fedcba9876543212345678n,
+  "0x123456789abcdef0fedcba9876543212345678n << 0n === 0x123456789abcdef0fedcba9876543212345678n");
+assert.sameValue(
+  0x123456789abcdef0fedcba9876543212345678n << -16n, 0x123456789abcdef0fedcba987654321234n,
+  "0x123456789abcdef0fedcba9876543212345678n << -16n === 0x123456789abcdef0fedcba987654321234n");
+assert.sameValue(
+  0x123456789abcdef0fedcba9876543212345678n << -32n, 0x123456789abcdef0fedcba98765432n,
+  "0x123456789abcdef0fedcba9876543212345678n << -32n === 0x123456789abcdef0fedcba98765432n");
+assert.sameValue(
+  0x123456789abcdef0fedcba9876543212345678n << -64n, 0x123456789abcdef0fedcban,
+  "0x123456789abcdef0fedcba9876543212345678n << -64n === 0x123456789abcdef0fedcban");
+assert.sameValue(
+  0x123456789abcdef0fedcba9876543212345678n << -127n, 0x2468acn,
+  "0x123456789abcdef0fedcba9876543212345678n << -127n === 0x2468acn");
+assert.sameValue(
+  0x123456789abcdef0fedcba9876543212345678n << -128n, 0x123456n,
+  "0x123456789abcdef0fedcba9876543212345678n << -128n === 0x123456n");
+assert.sameValue(
+  0x123456789abcdef0fedcba9876543212345678n << -129n, 0x91a2bn,
+  "0x123456789abcdef0fedcba9876543212345678n << -129n === 0x91a2bn");
+assert.sameValue(-5n << 1n, -0xan, "-5n << 1n === -0xan");
+assert.sameValue(-5n << 2n, -0x14n, "-5n << 2n === -0x14n");
+assert.sameValue(-5n << 3n, -0x28n, "-5n << 3n === -0x28n");
+assert.sameValue(-5n << -1n, -3n, "-5n << -1n === -3n");
+assert.sameValue(-5n << -2n, -2n, "-5n << -2n === -2n");
+assert.sameValue(-5n << -3n, -1n, "-5n << -3n === -1n");
+assert.sameValue(-1n << 128n, -0x100000000000000000000000000000000n, "-1n << 128n === -0x100000000000000000000000000000000n");
+assert.sameValue(-1n << 0n, -1n, "-1n << 0n === -1n");
+assert.sameValue(-1n << -128n, -1n, "-1n << -128n === -1n");
+assert.sameValue(-0x246n << 0n, -0x246n, "-0x246n << 0n === -0x246n");
+assert.sameValue(-0x246n << 127n, -0x12300000000000000000000000000000000n, "-0x246n << 127n === -0x12300000000000000000000000000000000n");
+assert.sameValue(-0x246n << 128n, -0x24600000000000000000000000000000000n, "-0x246n << 128n === -0x24600000000000000000000000000000000n");
+assert.sameValue(-0x246n << 129n, -0x48c00000000000000000000000000000000n, "-0x246n << 129n === -0x48c00000000000000000000000000000000n");
+assert.sameValue(-0x246n << -128n, -1n, "-0x246n << -128n === -1n");
+assert.sameValue(
+  -0x123456789abcdef0fedcba9876543212345678n << 64n, -0x123456789abcdef0fedcba98765432123456780000000000000000n,
+  "-0x123456789abcdef0fedcba9876543212345678n << 64n === -0x123456789abcdef0fedcba98765432123456780000000000000000n");
+assert.sameValue(
+  -0x123456789abcdef0fedcba9876543212345678n << 32n, -0x123456789abcdef0fedcba987654321234567800000000n,
+  "-0x123456789abcdef0fedcba9876543212345678n << 32n === -0x123456789abcdef0fedcba987654321234567800000000n");
+assert.sameValue(
+  -0x123456789abcdef0fedcba9876543212345678n << 16n, -0x123456789abcdef0fedcba98765432123456780000n,
+  "-0x123456789abcdef0fedcba9876543212345678n << 16n === -0x123456789abcdef0fedcba98765432123456780000n");
+assert.sameValue(
+  -0x123456789abcdef0fedcba9876543212345678n << 0n, -0x123456789abcdef0fedcba9876543212345678n,
+  "-0x123456789abcdef0fedcba9876543212345678n << 0n === -0x123456789abcdef0fedcba9876543212345678n");
+assert.sameValue(
+  -0x123456789abcdef0fedcba9876543212345678n << -16n, -0x123456789abcdef0fedcba987654321235n,
+  "-0x123456789abcdef0fedcba9876543212345678n << -16n === -0x123456789abcdef0fedcba987654321235n");
+assert.sameValue(
+  -0x123456789abcdef0fedcba9876543212345678n << -32n, -0x123456789abcdef0fedcba98765433n,
+  "-0x123456789abcdef0fedcba9876543212345678n << -32n === -0x123456789abcdef0fedcba98765433n");
+assert.sameValue(
+  -0x123456789abcdef0fedcba9876543212345678n << -64n, -0x123456789abcdef0fedcbbn,
+  "-0x123456789abcdef0fedcba9876543212345678n << -64n === -0x123456789abcdef0fedcbbn");
+assert.sameValue(
+  -0x123456789abcdef0fedcba9876543212345678n << -127n, -0x2468adn,
+  "-0x123456789abcdef0fedcba9876543212345678n << -127n === -0x2468adn");
+assert.sameValue(
+  -0x123456789abcdef0fedcba9876543212345678n << -128n, -0x123457n,
+  "-0x123456789abcdef0fedcba9876543212345678n << -128n === -0x123457n");
+assert.sameValue(
+  -0x123456789abcdef0fedcba9876543212345678n << -129n, -0x91a2cn,
+  "-0x123456789abcdef0fedcba9876543212345678n << -129n === -0x91a2cn");
diff --git a/test/language/expressions/right-shift/bigint-non-primitive.js b/test/language/expressions/right-shift/bigint-non-primitive.js
new file mode 100644
index 0000000000..6a44f7b03b
--- /dev/null
+++ b/test/language/expressions/right-shift/bigint-non-primitive.js
@@ -0,0 +1,50 @@
+// Copyright (C) 2017 Josh Wolfe. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+description: Right shift for non-primitive BigInt values
+esid: sec-signed-right-shift-operator-runtime-semantics-evaluation
+info: |
+  ShiftExpression : ShiftExpression >> AdditiveExpression
+
+  1. Let lref be the result of evaluating ShiftExpression.
+  2. Let lval be ? GetValue(lref).
+  3. Let rref be the result of evaluating AdditiveExpression.
+  4. Let rval be ? GetValue(rref).
+  5. Let lnum be ? ToNumeric(lval).
+  6. Let rnum be ? ToNumeric(rval).
+  7. If Type(lnum) does not equal Type(rnum), throw a TypeError exception.
+  8. Let T be Type(lnum).
+  9. Return T::signedRightShift(lnum, rnum).
+
+features: [BigInt, Symbol.toPrimitive]
+---*/
+
+assert.sameValue(Object(0b101n) >> 1n, 0b10n, "Object(0b101n) >> 1n === 0b10n");
+assert.sameValue(Object(0b101n) >> Object(1n), 0b10n, "Object(0b101n) >> Object(1n) === 0b10n");
+
+function err() {
+  throw new Test262Error();
+}
+
+assert.sameValue(
+  {[Symbol.toPrimitive]: function() { return 0b101n; }, valueOf: err, toString: err} >> 1n, 0b10n,
+  "primitive from @@toPrimitive");
+assert.sameValue(
+  {valueOf: function() { return 0b101n; }, toString: err} >> 1n, 0b10n,
+  "primitive from {}.valueOf");
+assert.sameValue(
+  {toString: function() { return 0b101n; }} >> 1n, 0b10n,
+  "primitive from {}.toString");
+assert.sameValue(
+  0b101n >> {[Symbol.toPrimitive]: function() { return 1n; }, valueOf: err, toString: err}, 0b10n,
+  "primitive from @@toPrimitive");
+assert.sameValue(
+  0b101n >> {valueOf: function() { return 1n; }, toString: err}, 0b10n,
+  "primitive from {}.valueOf");
+assert.sameValue(
+  0b101n >> {toString: function() { return 1n; }}, 0b10n,
+  "primitive from {}.toString");
+assert.sameValue(
+  {valueOf: function() { return 0b101n; }} >> {valueOf: function() { return 1n; }}, 0b10n,
+  "primitive from {}.valueOf");
diff --git a/test/language/expressions/right-shift/bigint.js b/test/language/expressions/right-shift/bigint.js
new file mode 100644
index 0000000000..5451d62eb6
--- /dev/null
+++ b/test/language/expressions/right-shift/bigint.js
@@ -0,0 +1,115 @@
+// Copyright (C) 2017 Josh Wolfe. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+description: Right shift for BigInt values
+esid: sec-numeric-types-bigint-signedRightShift
+info: |
+  BigInt::signedRightShift (x, y)
+
+  The abstract operation BigInt::signedRightShift with arguments x and y of type BigInt:
+
+  1. Return BigInt::leftShift(x, -y).
+
+  sec-numeric-types-bigint-leftShift
+  BigInt::leftShift (x, y)
+
+  The abstract operation BigInt::leftShift with two arguments x and y of BigInt:
+
+  1. If y < 0,
+    a. Return a BigInt representing x divided by 2-y, rounding down to the nearest integer, including for negative numbers.
+  2. Return a BigInt representing x multiplied by 2y.
+
+  NOTE: Semantics here should be equivalent to a bitwise shift, treating the BigInt as an infinite length string of binary two's complement digits.
+
+features: [BigInt]
+---*/
+
+assert.sameValue(0n >> 0n, 0n, "0n >> 0n === 0n");
+assert.sameValue(0b101n >> -1n, 0b1010n, "0b101n >> -1n === 0b1010n");
+assert.sameValue(0b101n >> -2n, 0b10100n, "0b101n >> -2n === 0b10100n");
+assert.sameValue(0b101n >> -3n, 0b101000n, "0b101n >> -3n === 0b101000n");
+assert.sameValue(0b101n >> 1n, 0b10n, "0b101n >> 1n === 0b10n");
+assert.sameValue(0b101n >> 2n, 1n, "0b101n >> 2n === 1n");
+assert.sameValue(0b101n >> 3n, 0n, "0b101n >> 3n === 0n");
+assert.sameValue(0n >> -128n, 0n, "0n >> -128n === 0n");
+assert.sameValue(0n >> 128n, 0n, "0n >> 128n === 0n");
+assert.sameValue(0x246n >> 0n, 0x246n, "0x246n >> 0n === 0x246n");
+assert.sameValue(0x246n >> -127n, 0x12300000000000000000000000000000000n, "0x246n >> -127n === 0x12300000000000000000000000000000000n");
+assert.sameValue(0x246n >> -128n, 0x24600000000000000000000000000000000n, "0x246n >> -128n === 0x24600000000000000000000000000000000n");
+assert.sameValue(0x246n >> -129n, 0x48c00000000000000000000000000000000n, "0x246n >> -129n === 0x48c00000000000000000000000000000000n");
+assert.sameValue(0x246n >> 128n, 0n, "0x246n >> 128n === 0n");
+assert.sameValue(
+  0x123456789abcdef0fedcba9876543212345678n >> -64n, 0x123456789abcdef0fedcba98765432123456780000000000000000n,
+  "0x123456789abcdef0fedcba9876543212345678n >> -64n === 0x123456789abcdef0fedcba98765432123456780000000000000000n");
+assert.sameValue(
+  0x123456789abcdef0fedcba9876543212345678n >> -32n, 0x123456789abcdef0fedcba987654321234567800000000n,
+  "0x123456789abcdef0fedcba9876543212345678n >> -32n === 0x123456789abcdef0fedcba987654321234567800000000n");
+assert.sameValue(
+  0x123456789abcdef0fedcba9876543212345678n >> -16n, 0x123456789abcdef0fedcba98765432123456780000n,
+  "0x123456789abcdef0fedcba9876543212345678n >> -16n === 0x123456789abcdef0fedcba98765432123456780000n");
+assert.sameValue(
+  0x123456789abcdef0fedcba9876543212345678n >> 0n, 0x123456789abcdef0fedcba9876543212345678n,
+  "0x123456789abcdef0fedcba9876543212345678n >> 0n === 0x123456789abcdef0fedcba9876543212345678n");
+assert.sameValue(
+  0x123456789abcdef0fedcba9876543212345678n >> 16n, 0x123456789abcdef0fedcba987654321234n,
+  "0x123456789abcdef0fedcba9876543212345678n >> 16n === 0x123456789abcdef0fedcba987654321234n");
+assert.sameValue(
+  0x123456789abcdef0fedcba9876543212345678n >> 32n, 0x123456789abcdef0fedcba98765432n,
+  "0x123456789abcdef0fedcba9876543212345678n >> 32n === 0x123456789abcdef0fedcba98765432n");
+assert.sameValue(
+  0x123456789abcdef0fedcba9876543212345678n >> 64n, 0x123456789abcdef0fedcban,
+  "0x123456789abcdef0fedcba9876543212345678n >> 64n === 0x123456789abcdef0fedcban");
+assert.sameValue(
+  0x123456789abcdef0fedcba9876543212345678n >> 127n, 0x2468acn,
+  "0x123456789abcdef0fedcba9876543212345678n >> 127n === 0x2468acn");
+assert.sameValue(
+  0x123456789abcdef0fedcba9876543212345678n >> 128n, 0x123456n,
+  "0x123456789abcdef0fedcba9876543212345678n >> 128n === 0x123456n");
+assert.sameValue(
+  0x123456789abcdef0fedcba9876543212345678n >> 129n, 0x91a2bn,
+  "0x123456789abcdef0fedcba9876543212345678n >> 129n === 0x91a2bn");
+assert.sameValue(-5n >> -1n, -0xan, "-5n >> -1n === -0xan");
+assert.sameValue(-5n >> -2n, -0x14n, "-5n >> -2n === -0x14n");
+assert.sameValue(-5n >> -3n, -0x28n, "-5n >> -3n === -0x28n");
+assert.sameValue(-5n >> 1n, -3n, "-5n >> 1n === -3n");
+assert.sameValue(-5n >> 2n, -2n, "-5n >> 2n === -2n");
+assert.sameValue(-5n >> 3n, -1n, "-5n >> 3n === -1n");
+assert.sameValue(-1n >> -128n, -0x100000000000000000000000000000000n, "-1n >> -128n === -0x100000000000000000000000000000000n");
+assert.sameValue(-1n >> 0n, -1n, "-1n >> 0n === -1n");
+assert.sameValue(-1n >> 128n, -1n, "-1n >> 128n === -1n");
+assert.sameValue(-0x246n >> 0n, -0x246n, "-0x246n >> 0n === -0x246n");
+assert.sameValue(-0x246n >> -127n, -0x12300000000000000000000000000000000n, "-0x246n >> -127n === -0x12300000000000000000000000000000000n");
+assert.sameValue(-0x246n >> -128n, -0x24600000000000000000000000000000000n, "-0x246n >> -128n === -0x24600000000000000000000000000000000n");
+assert.sameValue(-0x246n >> -129n, -0x48c00000000000000000000000000000000n, "-0x246n >> -129n === -0x48c00000000000000000000000000000000n");
+assert.sameValue(-0x246n >> 128n, -1n, "-0x246n >> 128n === -1n");
+assert.sameValue(
+  -0x123456789abcdef0fedcba9876543212345678n >> -64n, -0x123456789abcdef0fedcba98765432123456780000000000000000n,
+  "-0x123456789abcdef0fedcba9876543212345678n >> -64n === -0x123456789abcdef0fedcba98765432123456780000000000000000n");
+assert.sameValue(
+  -0x123456789abcdef0fedcba9876543212345678n >> -32n, -0x123456789abcdef0fedcba987654321234567800000000n,
+  "-0x123456789abcdef0fedcba9876543212345678n >> -32n === -0x123456789abcdef0fedcba987654321234567800000000n");
+assert.sameValue(
+  -0x123456789abcdef0fedcba9876543212345678n >> -16n, -0x123456789abcdef0fedcba98765432123456780000n,
+  "-0x123456789abcdef0fedcba9876543212345678n >> -16n === -0x123456789abcdef0fedcba98765432123456780000n");
+assert.sameValue(
+  -0x123456789abcdef0fedcba9876543212345678n >> 0n, -0x123456789abcdef0fedcba9876543212345678n,
+  "-0x123456789abcdef0fedcba9876543212345678n >> 0n === -0x123456789abcdef0fedcba9876543212345678n");
+assert.sameValue(
+  -0x123456789abcdef0fedcba9876543212345678n >> 16n, -0x123456789abcdef0fedcba987654321235n,
+  "-0x123456789abcdef0fedcba9876543212345678n >> 16n === -0x123456789abcdef0fedcba987654321235n");
+assert.sameValue(
+  -0x123456789abcdef0fedcba9876543212345678n >> 32n, -0x123456789abcdef0fedcba98765433n,
+  "-0x123456789abcdef0fedcba9876543212345678n >> 32n === -0x123456789abcdef0fedcba98765433n");
+assert.sameValue(
+  -0x123456789abcdef0fedcba9876543212345678n >> 64n, -0x123456789abcdef0fedcbbn,
+  "-0x123456789abcdef0fedcba9876543212345678n >> 64n === -0x123456789abcdef0fedcbbn");
+assert.sameValue(
+  -0x123456789abcdef0fedcba9876543212345678n >> 127n, -0x2468adn,
+  "-0x123456789abcdef0fedcba9876543212345678n >> 127n === -0x2468adn");
+assert.sameValue(
+  -0x123456789abcdef0fedcba9876543212345678n >> 128n, -0x123457n,
+  "-0x123456789abcdef0fedcba9876543212345678n >> 128n === -0x123457n");
+assert.sameValue(
+  -0x123456789abcdef0fedcba9876543212345678n >> 129n, -0x91a2cn,
+  "-0x123456789abcdef0fedcba9876543212345678n >> 129n === -0x91a2cn");
diff --git a/test/language/expressions/unsigned-right-shift/bigint-non-primitive.js b/test/language/expressions/unsigned-right-shift/bigint-non-primitive.js
new file mode 100644
index 0000000000..af88a121f7
--- /dev/null
+++ b/test/language/expressions/unsigned-right-shift/bigint-non-primitive.js
@@ -0,0 +1,56 @@
+// 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 always throws for non-primitive BigInt values
+esid: sec-unsigned-right-shift-operator-runtime-semantics-evaluation
+info: |
+  ShiftExpression : ShiftExpression >>> AdditiveExpression
+
+  1. Let lref be the result of evaluating ShiftExpression.
+  2. Let lval be ? GetValue(lref).
+  3. Let rref be the result of evaluating AdditiveExpression.
+  4. Let rval be ? GetValue(rref).
+  5. Let lnum be ? ToNumeric(lval).
+  6. Let rnum be ? ToNumeric(rval).
+  7. If Type(lnum) does not equal Type(rnum), throw a TypeError exception.
+  8. Let T be Type(lnum).
+  9. Return T::unsignedRightShift(lnum, rnum).
+
+  Note: BigInt::unsignedRightShift always throws a TypeError
+
+features: [BigInt, Symbol.toPrimitive]
+---*/
+
+assert.throws(TypeError,
+  function() { Object(0b101n) >>> 1n; },
+  "bigint >>> bigint throws a TypeError for Object(0b101n) >>> 1n");
+assert.throws(TypeError,
+  function() { Object(0b101n) >>> Object(1n); },
+  "bigint >>> bigint throws a TypeError for Object(0b101n) >>> Object(1n)");
+
+function err() {
+  throw new Test262Error();
+}
+
+assert.throws(TypeError,
+  function() { ({[Symbol.toPrimitive]: function() { return 0b101n; }, valueOf: err, toString: err} >>> 1n); },
+  "bigint >>> bigint throws a TypeError for primitive from @@toPrimitive");
+assert.throws(TypeError,
+  function() { ({valueOf: function() { return 0b101n; }, toString: err} >>> 1n); },
+  "bigint >>> bigint throws a TypeError for primitive from {}.valueOf");
+assert.throws(TypeError,
+  function() { ({toString: function() { return 0b101n; }} >>> 1n); },
+  "bigint >>> bigint throws a TypeError for primitive from {}.toString");
+assert.throws(TypeError,
+  function() { 0b101n >>> {[Symbol.toPrimitive]: function() { return 1n; }, valueOf: err, toString: err}; },
+  "bigint >>> bigint throws a TypeError for primitive from @@toPrimitive");
+assert.throws(TypeError,
+  function() { 0b101n >>> {valueOf: function() { return 1n; }, toString: err}; },
+  "bigint >>> bigint throws a TypeError for primitive from {}.valueOf");
+assert.throws(TypeError,
+  function() { 0b101n >>> {toString: function() { return 1n; }}; },
+  "bigint >>> bigint throws a TypeError for primitive from {}.toString");
+assert.throws(TypeError,
+  function() { ({valueOf: function() { return 0b101n; }} >>> {valueOf: function() { return 1n; }}); },
+  "bigint >>> bigint throws a TypeError for primitive from {}.valueOf");
diff --git a/test/language/expressions/unsigned-right-shift/bigint.js b/test/language/expressions/unsigned-right-shift/bigint.js
new file mode 100644
index 0000000000..14ba9f1e2f
--- /dev/null
+++ b/test/language/expressions/unsigned-right-shift/bigint.js
@@ -0,0 +1,64 @@
+// 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 always throws for BigInt values
+esid: sec-numeric-types-bigint-unsignedRightShift
+info: |
+  BigInt::unsignedRightShift (x, y)
+
+  The abstract operation BigInt::unsignedRightShift with two arguments x and y of type BigInt:
+
+  1. Throw a TypeError exception.
+
+features: [BigInt]
+---*/
+
+assert.throws(TypeError, function() { 0n >>> 0n; }, "bigint >>> bigint throws a TypeError");
+assert.throws(TypeError, function() { 5n >>> 1n; }, "bigint >>> bigint throws a TypeError");
+assert.throws(TypeError, function() { 5n >>> 2n; }, "bigint >>> bigint throws a TypeError");
+assert.throws(TypeError, function() { 5n >>> 3n; }, "bigint >>> bigint throws a TypeError");
+assert.throws(TypeError, function() { 5n >>> -1n; }, "bigint >>> bigint throws a TypeError");
+assert.throws(TypeError, function() { 5n >>> -2n; }, "bigint >>> bigint throws a TypeError");
+assert.throws(TypeError, function() { 5n >>> -3n; }, "bigint >>> bigint throws a TypeError");
+assert.throws(TypeError, function() { 0n >>> 128n; }, "bigint >>> bigint throws a TypeError");
+assert.throws(TypeError, function() { 0n >>> -128n; }, "bigint >>> bigint throws a TypeError");
+assert.throws(TypeError, function() { 582n >>> 0n; }, "bigint >>> bigint throws a TypeError");
+assert.throws(TypeError, function() { 582n >>> 127n; }, "bigint >>> bigint throws a TypeError");
+assert.throws(TypeError, function() { 582n >>> 128n; }, "bigint >>> bigint throws a TypeError");
+assert.throws(TypeError, function() { 582n >>> 129n; }, "bigint >>> bigint throws a TypeError");
+assert.throws(TypeError, function() { 582n >>> -128n; }, "bigint >>> bigint throws a TypeError");
+assert.throws(TypeError, function() { 405972677036361916727469983882855107238581880n >>> 64n; }, "bigint >>> bigint throws a TypeError");
+assert.throws(TypeError, function() { 405972677036361916727469983882855107238581880n >>> 32n; }, "bigint >>> bigint throws a TypeError");
+assert.throws(TypeError, function() { 405972677036361916727469983882855107238581880n >>> 16n; }, "bigint >>> bigint throws a TypeError");
+assert.throws(TypeError, function() { 405972677036361916727469983882855107238581880n >>> 0n; }, "bigint >>> bigint throws a TypeError");
+assert.throws(TypeError, function() { 405972677036361916727469983882855107238581880n >>> -16n; }, "bigint >>> bigint throws a TypeError");
+assert.throws(TypeError, function() { 405972677036361916727469983882855107238581880n >>> -32n; }, "bigint >>> bigint throws a TypeError");
+assert.throws(TypeError, function() { 405972677036361916727469983882855107238581880n >>> -64n; }, "bigint >>> bigint throws a TypeError");
+assert.throws(TypeError, function() { 405972677036361916727469983882855107238581880n >>> -127n; }, "bigint >>> bigint throws a TypeError");
+assert.throws(TypeError, function() { 405972677036361916727469983882855107238581880n >>> -128n; }, "bigint >>> bigint throws a TypeError");
+assert.throws(TypeError, function() { 405972677036361916727469983882855107238581880n >>> -129n; }, "bigint >>> bigint throws a TypeError");
+assert.throws(TypeError, function() { -5n >>> 1n; }, "bigint >>> bigint throws a TypeError");
+assert.throws(TypeError, function() { -5n >>> 2n; }, "bigint >>> bigint throws a TypeError");
+assert.throws(TypeError, function() { -5n >>> 3n; }, "bigint >>> bigint throws a TypeError");
+assert.throws(TypeError, function() { -5n >>> -1n; }, "bigint >>> bigint throws a TypeError");
+assert.throws(TypeError, function() { -5n >>> -2n; }, "bigint >>> bigint throws a TypeError");
+assert.throws(TypeError, function() { -5n >>> -3n; }, "bigint >>> bigint throws a TypeError");
+assert.throws(TypeError, function() { -1n >>> 128n; }, "bigint >>> bigint throws a TypeError");
+assert.throws(TypeError, function() { -1n >>> 0n; }, "bigint >>> bigint throws a TypeError");
+assert.throws(TypeError, function() { -1n >>> -128n; }, "bigint >>> bigint throws a TypeError");
+assert.throws(TypeError, function() { -582n >>> 0n; }, "bigint >>> bigint throws a TypeError");
+assert.throws(TypeError, function() { -582n >>> 127n; }, "bigint >>> bigint throws a TypeError");
+assert.throws(TypeError, function() { -582n >>> 128n; }, "bigint >>> bigint throws a TypeError");
+assert.throws(TypeError, function() { -582n >>> 129n; }, "bigint >>> bigint throws a TypeError");
+assert.throws(TypeError, function() { -582n >>> -128n; }, "bigint >>> bigint throws a TypeError");
+assert.throws(TypeError, function() { -405972677036361916727469983882855107238581880n >>> 64n; }, "bigint >>> bigint throws a TypeError");
+assert.throws(TypeError, function() { -405972677036361916727469983882855107238581880n >>> 32n; }, "bigint >>> bigint throws a TypeError");
+assert.throws(TypeError, function() { -405972677036361916727469983882855107238581880n >>> 16n; }, "bigint >>> bigint throws a TypeError");
+assert.throws(TypeError, function() { -405972677036361916727469983882855107238581880n >>> 0n; }, "bigint >>> bigint throws a TypeError");
+assert.throws(TypeError, function() { -405972677036361916727469983882855107238581880n >>> -16n; }, "bigint >>> bigint throws a TypeError");
+assert.throws(TypeError, function() { -405972677036361916727469983882855107238581880n >>> -32n; }, "bigint >>> bigint throws a TypeError");
+assert.throws(TypeError, function() { -405972677036361916727469983882855107238581880n >>> -64n; }, "bigint >>> bigint throws a TypeError");
+assert.throws(TypeError, function() { -405972677036361916727469983882855107238581880n >>> -127n; }, "bigint >>> bigint throws a TypeError");
+assert.throws(TypeError, function() { -405972677036361916727469983882855107238581880n >>> -128n; }, "bigint >>> bigint throws a TypeError");
+assert.throws(TypeError, function() { -405972677036361916727469983882855107238581880n >>> -129n; }, "bigint >>> bigint throws a TypeError");
-- 
GitLab