diff options
Diffstat (limited to 'deps/v8/test/mjsunit/harmony')
-rw-r--r-- | deps/v8/test/mjsunit/harmony/atomics.js | 251 | ||||
-rw-r--r-- | deps/v8/test/mjsunit/harmony/nullish.js | 143 | ||||
-rw-r--r-- | deps/v8/test/mjsunit/harmony/numeric-separator.js | 11 | ||||
-rw-r--r-- | deps/v8/test/mjsunit/harmony/optional-chaining.js | 119 | ||||
-rw-r--r-- | deps/v8/test/mjsunit/harmony/private-accessors.js | 91 | ||||
-rw-r--r-- | deps/v8/test/mjsunit/harmony/private-methods.js | 14 | ||||
-rw-r--r-- | deps/v8/test/mjsunit/harmony/weakrefs/cleanup-doesnt-iterate-all-holdings.js | 11 | ||||
-rw-r--r-- | deps/v8/test/mjsunit/harmony/weakrefs/cleanup-is-not-a-microtask.js (renamed from deps/v8/test/mjsunit/harmony/weakrefs/cleanup-is-a-microtask.js) | 36 | ||||
-rw-r--r-- | deps/v8/test/mjsunit/harmony/weakrefs/cleanup-on-detached-realm.js | 5 | ||||
-rw-r--r-- | deps/v8/test/mjsunit/harmony/weakrefs/finalizationgroup-and-weakref.js | 20 | ||||
-rw-r--r-- | deps/v8/test/mjsunit/harmony/weakrefs/two-weakrefs.js | 51 | ||||
-rw-r--r-- | deps/v8/test/mjsunit/harmony/weakrefs/weakref-creation-keeps-alive.js | 13 | ||||
-rw-r--r-- | deps/v8/test/mjsunit/harmony/weakrefs/weakref-deref-keeps-alive.js | 44 |
13 files changed, 609 insertions, 200 deletions
diff --git a/deps/v8/test/mjsunit/harmony/atomics.js b/deps/v8/test/mjsunit/harmony/atomics.js index ef90076103..5caeb7e8e5 100644 --- a/deps/v8/test/mjsunit/harmony/atomics.js +++ b/deps/v8/test/mjsunit/harmony/atomics.js @@ -5,27 +5,47 @@ // Flags: --harmony-sharedarraybuffer // -function toRangeWrapped(value) { - var range = this.max - this.min + 1; - while (value < this.min) { - value += range; - } - while (value > this.max) { - value -= range; +function toRangeWrapper(is_big) { + return function _toRangeWrapped(raw_value) { + var raw_range = this.max - this.min + (is_big ? 1n : 1); + let range = is_big ? BigInt(raw_range) : raw_range; + let value = is_big ? BigInt(raw_value) : raw_value; + while (value < this.min) { + value += range; + } + while (value > this.max) { + value -= range; + } + return value; } - return value; } function makeConstructorObject(constr, min, max, toRange) { var o = {constr: constr, min: min, max: max}; - o.toRange = toRangeWrapped.bind(o); + let is_big = constr.name.startsWith('Big') + o.toRange = toRangeWrapper(is_big).bind(o); return o; } +function IsBig(t) { + return t.constructor.name.startsWith('Big'); +} + +function MaybeIntToBigInt(arr, i) { + if (IsBig(arr)) { + return BigInt(i); + } else { + return i; + } +} + var IntegerTypedArrayConstructors = [ makeConstructorObject(Int8Array, -128, 127), makeConstructorObject(Int16Array, -32768, 32767), makeConstructorObject(Int32Array, -0x80000000, 0x7fffffff), + makeConstructorObject(BigInt64Array, -0x8000_0000_0000_0000n, + 0x7fff_ffff_ffff_ffffn), + makeConstructorObject(BigUint64Array, 0n, 0xffff_ffff_ffff_ffffn), makeConstructorObject(Uint8Array, 0, 255), makeConstructorObject(Uint16Array, 0, 65535), makeConstructorObject(Uint32Array, 0, 0xffffffff), @@ -189,16 +209,19 @@ function clearArray(sab) { var sta2 = new t.constr(sab, 5 * t.constr.BYTES_PER_ELEMENT); [sta, sta2].forEach(function(array) { + let _i = (i) => { return MaybeIntToBigInt(array, i); } clearArray(array.buffer); var name = Object.prototype.toString.call(array); for (var i = 0; i < array.length; ++i) { // array[i] == 0, CAS will store - assertEquals(0, Atomics.compareExchange(array, i, 0, 50), name); - assertEquals(50, array[i], name); + assertEquals(_i(0), Atomics.compareExchange(array, i, _i(0), _i(50)), + name); + assertEquals(_i(50), array[i], name); // array[i] == 50, CAS will not store - assertEquals(50, Atomics.compareExchange(array, i, 0, 100), name); - assertEquals(50, array[i], name); + assertEquals(_i(50), Atomics.compareExchange(array, i, _i(0), _i(100)), + name); + assertEquals(_i(50), array[i], name); } }) }); @@ -211,13 +234,14 @@ function clearArray(sab) { var sta2 = new t.constr(sab, 5 * t.constr.BYTES_PER_ELEMENT); [sta, sta2].forEach(function(array) { + let _i = (i) => { return MaybeIntToBigInt(array, i); } clearArray(array.buffer); var name = Object.prototype.toString.call(array); for (var i = 0; i < array.length; ++i) { - array[i] = 0; - assertEquals(0, Atomics.load(array, i), name); - array[i] = 50; - assertEquals(50, Atomics.load(array, i), name); + array[i] = _i(0); + assertEquals(_i(0), Atomics.load(array, i), name); + array[i] = _i(50); + assertEquals(_i(50), Atomics.load(array, i), name); } }) }); @@ -248,14 +272,15 @@ function clearArray(sab) { var sta2 = new t.constr(sab, 5 * t.constr.BYTES_PER_ELEMENT); [sta, sta2].forEach(function(array) { + let _i = (i) => { return MaybeIntToBigInt(array, i); } clearArray(array.buffer); var name = Object.prototype.toString.call(array); for (var i = 0; i < array.length; ++i) { - assertEquals(50, Atomics.store(array, i, 50), name); - assertEquals(50, array[i], name); + assertEquals(_i(50), Atomics.store(array, i, _i(50)), name); + assertEquals(_i(50), array[i], name); - assertEquals(100, Atomics.store(array, i, 100), name); - assertEquals(100, array[i], name); + assertEquals(_i(100), Atomics.store(array, i, _i(100)), name); + assertEquals(_i(100), array[i], name); } }) }); @@ -268,14 +293,15 @@ function clearArray(sab) { var sta2 = new t.constr(sab, 5 * t.constr.BYTES_PER_ELEMENT); [sta, sta2].forEach(function(array) { + let _i = (i) => { return MaybeIntToBigInt(array, i); } clearArray(array.buffer); var name = Object.prototype.toString.call(array); for (var i = 0; i < array.length; ++i) { - assertEquals(0, Atomics.add(array, i, 50), name); - assertEquals(50, array[i], name); + assertEquals(_i(0), Atomics.add(array, i, _i(50)), name); + assertEquals(_i(50), array[i], name); - assertEquals(50, Atomics.add(array, i, 70), name); - assertEquals(120, array[i], name); + assertEquals(_i(50), Atomics.add(array, i, _i(70)), name); + assertEquals(_i(120), array[i], name); } }) }); @@ -288,15 +314,16 @@ function clearArray(sab) { var sta2 = new t.constr(sab, 5 * t.constr.BYTES_PER_ELEMENT); [sta, sta2].forEach(function(array) { + let _i = (i) => { return MaybeIntToBigInt(array, i); } clearArray(array.buffer); var name = Object.prototype.toString.call(array); for (var i = 0; i < array.length; ++i) { - array[i] = 120; - assertEquals(120, Atomics.sub(array, i, 50), name); - assertEquals(70, array[i], name); + array[i] = _i(120); + assertEquals(_i(120), Atomics.sub(array, i, _i(50)), name); + assertEquals(_i(70), array[i], name); - assertEquals(70, Atomics.sub(array, i, 70), name); - assertEquals(0, array[i], name); + assertEquals(_i(70), Atomics.sub(array, i, _i(70)), name); + assertEquals(_i(0), array[i], name); } }) }); @@ -309,15 +336,16 @@ function clearArray(sab) { var sta2 = new t.constr(sab, 5 * t.constr.BYTES_PER_ELEMENT); [sta, sta2].forEach(function(array) { + let _i = (i) => { return MaybeIntToBigInt(array, i); } clearArray(array.buffer); var name = Object.prototype.toString.call(sta); for (var i = 0; i < array.length; ++i) { - array[i] = 0x3f; - assertEquals(0x3f, Atomics.and(array, i, 0x30), name); - assertEquals(0x30, array[i], name); + array[i] = _i(0x3f); + assertEquals(_i(0x3f), Atomics.and(array, i, _i(0x30)), name); + assertEquals(_i(0x30), array[i], name); - assertEquals(0x30, Atomics.and(array, i, 0x20), name); - assertEquals(0x20, array[i], name); + assertEquals(_i(0x30), Atomics.and(array, i, _i(0x20)), name); + assertEquals(_i(0x20), array[i], name); } }) }); @@ -330,15 +358,16 @@ function clearArray(sab) { var sta2 = new t.constr(sab, 5 * t.constr.BYTES_PER_ELEMENT); [sta, sta2].forEach(function(array) { + let _i = (i) => { return MaybeIntToBigInt(array, i); } clearArray(array.buffer); var name = Object.prototype.toString.call(array); for (var i = 0; i < array.length; ++i) { - array[i] = 0x30; - assertEquals(0x30, Atomics.or(array, i, 0x1c), name); - assertEquals(0x3c, array[i], name); + array[i] = _i(0x30); + assertEquals(_i(0x30), Atomics.or(array, i, _i(0x1c)), name); + assertEquals(_i(0x3c), array[i], name); - assertEquals(0x3c, Atomics.or(array, i, 0x09), name); - assertEquals(0x3d, array[i], name); + assertEquals(_i(0x3c), Atomics.or(array, i, _i(0x09)), name); + assertEquals(_i(0x3d), array[i], name); } }) }); @@ -351,15 +380,16 @@ function clearArray(sab) { var sta2 = new t.constr(sab, 5 * t.constr.BYTES_PER_ELEMENT); [sta, sta2].forEach(function(array) { + let _i = (i) => { return MaybeIntToBigInt(array, i); } clearArray(array.buffer); var name = Object.prototype.toString.call(array); for (var i = 0; i < array.length; ++i) { - array[i] = 0x30; - assertEquals(0x30, Atomics.xor(array, i, 0x1c), name); - assertEquals(0x2c, array[i], name); + array[i] = _i(0x30); + assertEquals(_i(0x30), Atomics.xor(array, i, _i(0x1c)), name); + assertEquals(_i(0x2c), array[i], name); - assertEquals(0x2c, Atomics.xor(array, i, 0x09), name); - assertEquals(0x25, array[i], name); + assertEquals(_i(0x2c), Atomics.xor(array, i, _i(0x09)), name); + assertEquals(_i(0x25), array[i], name); } }) }); @@ -372,15 +402,16 @@ function clearArray(sab) { var sta2 = new t.constr(sab, 5 * t.constr.BYTES_PER_ELEMENT); [sta, sta2].forEach(function(array) { + let _i = (i) => { return MaybeIntToBigInt(array, i); } clearArray(array.buffer); var name = Object.prototype.toString.call(array); for (var i = 0; i < array.length; ++i) { - array[i] = 0x30; - assertEquals(0x30, Atomics.exchange(array, i, 0x1c), name); - assertEquals(0x1c, array[i], name); + array[i] = _i(0x30); + assertEquals(_i(0x30), Atomics.exchange(array, i, _i(0x1c)), name); + assertEquals(_i(0x1c), array[i], name); - assertEquals(0x1c, Atomics.exchange(array, i, 0x09), name); - assertEquals(0x09, array[i], name); + assertEquals(_i(0x1c), Atomics.exchange(array, i, _i(0x09)), name); + assertEquals(_i(0x09), array[i], name); } }) }); @@ -397,72 +428,73 @@ function clearArray(sab) { }); // For all platforms we support, 1, 2 and 4 bytes should be lock-free. - assertEquals(true, Atomics.isLockFree(1)); - assertEquals(true, Atomics.isLockFree(2)); - assertEquals(true, Atomics.isLockFree(4)); - - // Sizes that aren't equal to a typedarray BYTES_PER_ELEMENT always return - // false. - var validSizes = {}; - IntegerTypedArrayConstructors.forEach(function(t) { - validSizes[t.constr.BYTES_PER_ELEMENT] = true; - }); - - for (var i = 0; i < 1000; ++i) { - if (!validSizes[i]) { - assertEquals(false, Atomics.isLockFree(i)); - } - } + assertTrue(Atomics.isLockFree(1)); + assertTrue(Atomics.isLockFree(2)); + assertTrue(Atomics.isLockFree(4)); + + assertFalse(Atomics.isLockFree(0)); + assertFalse(Atomics.isLockFree(3)); + assertFalse(Atomics.isLockFree(5)); + assertFalse(Atomics.isLockFree(6)); + assertFalse(Atomics.isLockFree(7)); + // isLockFree(8) is platform dependent. + for (var i = 9; i < 100; ++i) assertFalse(Atomics.isLockFree(i)); })(); (function TestToNumber() { IntegerTypedArrayConstructors.forEach(function(t) { var sab = new SharedArrayBuffer(1 * t.constr.BYTES_PER_ELEMENT); var sta = new t.constr(sab); + let _i = (i) => { return MaybeIntToBigInt(sta, i); } - var valueOf = {valueOf: function(){ return 3;}}; + var valueOf = {valueOf: function(){ return _i(3);}}; var toString = {toString: function(){ return '3';}}; [false, true, undefined, valueOf, toString].forEach(function(v) { + if (v === undefined && IsBig(sta)) { + // undefined does not convert to a BigInt. + return; + } + let _v = () => { return IsBig(sta) ? _i(v) : (v|0); } var name = Object.prototype.toString.call(sta) + ' - ' + v; // CompareExchange - sta[0] = 50; - assertEquals(50, Atomics.compareExchange(sta, 0, v, v), name); + sta[0] = _i(50); + assertEquals(_i(50), Atomics.compareExchange(sta, 0, v, v), name); // Store - assertEquals(v|0, Atomics.store(sta, 0, v), name); - assertEquals(v|0, sta[0], name); + assertEquals(_v(), Atomics.store(sta, 0, v), name); + assertEquals(_v(), sta[0], name); // Add - sta[0] = 120; - assertEquals(120, Atomics.add(sta, 0, v), name); - assertEquals(120 + (v|0), sta[0], name); + sta[0] = _i(120); + assertEquals(_i(120), Atomics.add(sta, 0, v), name); + assertEquals(_i(120) + _v(), sta[0], name); // Sub - sta[0] = 70; - assertEquals(70, Atomics.sub(sta, 0, v), name); - assertEquals(70 - (v|0), sta[0]); + sta[0] = _i(70); + assertEquals(_i(70), Atomics.sub(sta, 0, v), name); + assertEquals(_i(70) - _v(), sta[0]); // And - sta[0] = 0x20; - assertEquals(0x20, Atomics.and(sta, 0, v), name); - assertEquals(0x20 & (v|0), sta[0]); + sta[0] = _i(0x20); + assertEquals(_i(0x20), Atomics.and(sta, 0, v), name); + assertEquals(_i(0x20) & _v(), sta[0]); // Or - sta[0] = 0x3d; - assertEquals(0x3d, Atomics.or(sta, 0, v), name); - assertEquals(0x3d | (v|0), sta[0]); + sta[0] = _i(0x3d); + assertEquals(_i(0x3d), Atomics.or(sta, 0, v), name); + assertEquals(_i(0x3d) | _v(), sta[0]); // Xor - sta[0] = 0x25; - assertEquals(0x25, Atomics.xor(sta, 0, v), name); - assertEquals(0x25 ^ (v|0), sta[0]); + sta[0] = _i(0x25); + assertEquals(_i(0x25), Atomics.xor(sta, 0, v), name); + assertEquals(_i(0x25) ^ _v(), sta[0]); // Exchange - sta[0] = 0x09; - assertEquals(0x09, Atomics.exchange(sta, 0, v), name); - assertEquals(v|0, sta[0]); + sta[0] = _i(0x09); + assertEquals(_i(0x09), Atomics.exchange(sta, 0, v), name); + assertEquals(_v(), sta[0]); }); }); })(); @@ -472,7 +504,8 @@ function clearArray(sab) { var sab = new SharedArrayBuffer(10 * t.constr.BYTES_PER_ELEMENT); var sta = new t.constr(sab); var name = Object.prototype.toString.call(sta); - var range = t.max - t.min + 1; + let _i = (i) => { return MaybeIntToBigInt(sta, i); } + var range = t.max - t.min + _i(1); var offset; var operand; var val, newVal; @@ -480,52 +513,52 @@ function clearArray(sab) { for (offset = -range; offset <= range; offset += range) { // CompareExchange - sta[0] = val = 0; - newVal = val + offset + 1; + sta[0] = val = _i(0); + newVal = val + offset + _i(1); newValWrapped = t.toRange(newVal); assertEquals(val, Atomics.compareExchange(sta, 0, val, newVal), name); assertEquals(newValWrapped, sta[0], name); sta[0] = val = t.min; - newVal = val + offset - 1; + newVal = val + offset - _i(1); newValWrapped = t.toRange(newVal); assertEquals(val, Atomics.compareExchange(sta, 0, val, newVal), name); assertEquals(newValWrapped, sta[0], name); // Store - sta[0] = 0; - val = t.max + offset + 1; + sta[0] = _i(0); + val = t.max + offset + _i(1); valWrapped = t.toRange(val); assertEquals(val, Atomics.store(sta, 0, val), name); assertEquals(valWrapped, sta[0], name); - sta[0] = val = t.min + offset - 1; + sta[0] = val = t.min + offset - _i(1); valWrapped = t.toRange(val); assertEquals(val, Atomics.store(sta, 0, val), name); assertEquals(valWrapped, sta[0], name); // Add sta[0] = val = t.max; - operand = offset + 1; + operand = offset + _i(1); valWrapped = t.toRange(val + operand); assertEquals(val, Atomics.add(sta, 0, operand), name); assertEquals(valWrapped, sta[0], name); sta[0] = val = t.min; - operand = offset - 1; + operand = offset - _i(1); valWrapped = t.toRange(val + operand); assertEquals(val, Atomics.add(sta, 0, operand), name); assertEquals(valWrapped, sta[0], name); // Sub sta[0] = val = t.max; - operand = offset - 1; + operand = offset - _i(1); valWrapped = t.toRange(val - operand); assertEquals(val, Atomics.sub(sta, 0, operand), name); assertEquals(valWrapped, sta[0], name); sta[0] = val = t.min; - operand = offset + 1; + operand = offset + _i(1); valWrapped = t.toRange(val - operand); assertEquals(val, Atomics.sub(sta, 0, operand), name); assertEquals(valWrapped, sta[0], name); @@ -535,29 +568,29 @@ function clearArray(sab) { // to memory. // And - sta[0] = val = 0xf; - operand = 0x3 + offset; + sta[0] = val = _i(0xf); + operand = _i(0x3) + offset; valWrapped = t.toRange(val & operand); assertEquals(val, Atomics.and(sta, 0, operand), name); assertEquals(valWrapped, sta[0], name); // Or - sta[0] = val = 0x12; - operand = 0x22 + offset; + sta[0] = val = _i(0x12); + operand = _i(0x22) + offset; valWrapped = t.toRange(val | operand); assertEquals(val, Atomics.or(sta, 0, operand), name); assertEquals(valWrapped, sta[0], name); // Xor - sta[0] = val = 0x12; - operand = 0x22 + offset; + sta[0] = val = _i(0x12); + operand = _i(0x22) + offset; valWrapped = t.toRange(val ^ operand); assertEquals(val, Atomics.xor(sta, 0, operand), name); assertEquals(valWrapped, sta[0], name); // Exchange - sta[0] = val = 0x12; - operand = 0x22 + offset; + sta[0] = val = _i(0x12); + operand = _i(0x22) + offset; valWrapped = t.toRange(operand); assertEquals(val, Atomics.exchange(sta, 0, operand), name); assertEquals(valWrapped, sta[0], name); @@ -574,7 +607,7 @@ function clearArray(sab) { // The index should be checked before calling ToInteger on the value, so // valueof_has_been_called should not be modified. - sta[0] = 0; + sta[0] = MaybeIntToBigInt(sta, 0); assertThrows(function() { op(sta, index, value, value); }, RangeError); assertEquals(0, valueof_has_been_called); }; diff --git a/deps/v8/test/mjsunit/harmony/nullish.js b/deps/v8/test/mjsunit/harmony/nullish.js new file mode 100644 index 0000000000..87d35db4bc --- /dev/null +++ b/deps/v8/test/mjsunit/harmony/nullish.js @@ -0,0 +1,143 @@ +// Copyright 2019 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// Flags: --harmony-nullish + +// Basic sanity checks. +assertTrue(true ?? false); +assertFalse(false ?? true); +assertTrue(undefined ?? true); +assertTrue(null ?? true); +assertEquals([], [] ?? true); + +// Chaining nullish. +assertTrue(null ?? null ?? true); +assertTrue(null ?? null ?? true ?? null); +assertTrue(undefined ?? undefined ?? true); +assertTrue(undefined ?? undefined ?? true ?? undefined); +assertFalse(null ?? false ?? null); +assertFalse(undefined ?? false ?? undefined); + +// Nullish and conditionals. +assertTrue(null ?? true ? true : false); +assertTrue(null ?? null ?? true ? true : false); +assertTrue(undefined ?? true ? true : false); +assertTrue(undefined ?? undefined ?? true ? true : false); + +// Nullish mixed expressions. +assertTrue(null ?? 1 == 1); +assertTrue(undefined ?? 1 == 1); +assertTrue(null ?? null ?? 1 == 1); +assertTrue(undefined ??undefined ?? 1 == 1); +assertEquals(1, null ?? 1 | 0); +assertEquals(1, undefined ?? 1 | 0); +assertEquals(1, null ?? null ?? 1 | 0); +assertEquals(1, undefined ?? undefined ?? 1 | 0); + +// Short circuit. +{ + let ran = false; + let never_ran = () => { ran = true; } + let value = true ?? never_ran(); + assertTrue(value); + assertFalse(ran); +} + +{ + let ran = false; + let never_ran = () => { ran = true; } + let value = undefined ?? true ?? never_ran(); + assertTrue(value); + assertFalse(ran); +} + +{ + let ran = false; + let never_ran = () => { ran = true; } + let value = null ?? true ?? never_ran(); + assertTrue(value); + assertFalse(ran); +} + +// Nullish in tests evaluates only once. +{ + let run_count = 0; + let run = () => { run_count++; return null; } + if (run() ?? true) {} else { assertUnreachable(); } + assertEquals(1, run_count); +} + +// Nullish may not contain or be contained within || or &&. +assertThrows("true || true ?? true", SyntaxError); +assertThrows("true ?? true || true", SyntaxError); +assertThrows("true && true ?? true", SyntaxError); +assertThrows("true ?? true && true", SyntaxError); + +// Test boolean expressions and nullish. +assertTrue((false || true) ?? false); +assertTrue(null ?? (false || true)); +assertTrue((false || null) ?? true); +assertTrue((false || null) ?? (true && null) ?? true); +assertTrue((false || undefined) ?? true); +assertTrue((false || undefined) ?? (true && undefined) ?? true); +assertTrue(null ?? (false || true)); +assertTrue(undefined ?? (false || true)); +assertTrue(null ?? (false || null) ?? true); +assertTrue(undefined ?? (false || undefined) ?? true); +assertTrue(null ?? null ?? (false || true)); +assertTrue(undefined ?? undefined ?? (false || true)); +assertTrue((undefined ?? false) || true); +assertTrue((null ?? false) || true); +assertTrue((undefined ?? undefined ?? false) || false || true); +assertTrue((null ?? null ?? false) || false || true); +assertTrue(false || (undefined ?? true)); +assertTrue(false || (null ?? true)); +assertTrue(false || false || (undefined ?? undefined ?? true)); +assertTrue(false || false || (null ?? null ?? true)); + +// Test use when test true. +if (undefined ?? true) {} else { assertUnreachable(); } +if (null ?? true) {} else { assertUnreachable(); } + +if (undefined ?? undefined ?? true) {} else { assertUnreachable(); } +if (null ?? null ?? true) {} else { assertUnreachable(); } + +// test use when test false +if (undefined ?? false) { assertUnreachable(); } else {} +if (null ?? false) { assertUnreachable(); } else {} + +if (undefined ?? undefined ?? false) { assertUnreachable(); } else {} +if (null ?? null ?? false) { assertUnreachable(); } else {} + +if (undefined ?? false ?? true) { assertUnreachable(); } else {} +if (null ?? false ?? true) { assertUnreachable(); } else {} + +// Test use with nested boolean. +if ((false || undefined) ?? true) {} else { assertUnreachable(); } +if ((false || null) ?? true) {} else { assertUnreachable(); } + +if ((false || undefined) ?? undefined ?? true) {} else { assertUnreachable(); } +if ((false || null) ?? null ?? true) {} else { assertUnreachable(); } + +if (undefined ?? (false || true)) {} else { assertUnreachable(); } +if (null ?? (false || true)) {} else { assertUnreachable(); } + +if (undefined ?? undefined ?? (false || true)) {} else { assertUnreachable(); } +if (null ?? null ?? (false || true)) {} else { assertUnreachable(); } + +if (undefined ?? (false || undefined) ?? true) {} else { assertUnreachable(); } +if (null ?? (false || null) ?? true) {} else { assertUnreachable(); } + +// Nested nullish. +if ((null ?? true) || false) {} else { assertUnreachable(); } +if ((null ?? null ?? true) || false) {} else { assertUnreachable(); } + +if (false || (null ?? true)) {} else { assertUnreachable(); } +if (false || (null ?? null ?? true)) {} else { assertUnreachable(); } + +if ((null ?? false) || false) { assertUnreachable(); } else {} +if ((null ?? null ?? false) || false) { assertUnreachable(); } else {} + +if (false || (null ?? false)) { assertUnreachable(); } else {} +if (false || (null ?? null ?? false)) { assertUnreachable(); } else {} diff --git a/deps/v8/test/mjsunit/harmony/numeric-separator.js b/deps/v8/test/mjsunit/harmony/numeric-separator.js index 0ea3ac8f8d..c2c32b7db0 100644 --- a/deps/v8/test/mjsunit/harmony/numeric-separator.js +++ b/deps/v8/test/mjsunit/harmony/numeric-separator.js @@ -2,8 +2,6 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// Flags: --harmony-numeric-separator - { const basic = 1_0_0_0; assertEquals(basic, 1000); @@ -41,11 +39,6 @@ assertEquals(binary, 0b01010); } { - const leadingZeros = 09_1_3; - assertEquals(leadingZeros, 0913); -} - -{ const dot1 = 9_1.1_3; assertEquals(dot1, 91.13); @@ -54,6 +47,9 @@ const dot3 = 1_1.21; assertEquals(dot3, 11.21); + + const dot4 = 09.1_2 + assertEquals(dot4, 9.12); } { @@ -114,3 +110,4 @@ assertThrows('0o7__77', SyntaxError); assertThrows('0777_', SyntaxError); assertThrows('07__77', SyntaxError); assertThrows('07_7_7', SyntaxError); +assertThrows('09_1_3', SyntaxError); diff --git a/deps/v8/test/mjsunit/harmony/optional-chaining.js b/deps/v8/test/mjsunit/harmony/optional-chaining.js new file mode 100644 index 0000000000..72b0559e00 --- /dev/null +++ b/deps/v8/test/mjsunit/harmony/optional-chaining.js @@ -0,0 +1,119 @@ +// Copyright 2019 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Flags: --harmony-optional-chaining + +function shouldThrowSyntaxError(script) { + let error; + try { + eval(script); + } catch (e) { + error = e; + } + + if (!(error instanceof SyntaxError)) { + throw new Error('Expected SyntaxError!'); + } +} + +assertEquals(undefined?.valueOf(), undefined); +assertEquals(null?.valueOf(), undefined); +assertEquals(true?.valueOf(), true); +assertEquals(false?.valueOf(), false); +assertEquals(0?.valueOf(), 0); +assertEquals(1?.valueOf(), 1); +assertEquals(''?.valueOf(), ''); +assertEquals('hi'?.valueOf(), 'hi'); +assertEquals(({})?.constructor, Object); +assertEquals(({ x: 'hi' })?.x, 'hi'); +assertEquals([]?.length, 0); +assertEquals(['hi']?.length, 1); + +assertEquals(undefined?.['valueOf'](), undefined); +assertEquals(null?.['valueOf'](), undefined); +assertEquals(true?.['valueOf'](), true); +assertEquals(false?.['valueOf'](), false); +assertEquals(0?.['valueOf'](), 0); +assertEquals(1?.['valueOf'](), 1); +assertEquals(''?.['valueOf'](), ''); +assertEquals('hi'?.['valueOf'](), 'hi'); +assertEquals(({})?.['constructor'], Object); +assertEquals(({ x: 'hi' })?.['x'], 'hi'); +assertEquals([]?.['length'], 0); +assertEquals(['hi']?.[0], 'hi'); + +assertEquals(undefined?.(), undefined); +assertEquals(null?.(), undefined); +assertThrows(() => true?.(), TypeError); +assertThrows(() => false?.(), TypeError); +assertThrows(() => 0?.(), TypeError); +assertThrows(() => 1?.(), TypeError); +assertThrows(() => ''?.(), TypeError); +assertThrows(() => 'hi'?.(), TypeError); +assertThrows(() => ({})?.(), TypeError); +assertThrows(() => ({ x: 'hi' })?.(), TypeError); +assertThrows(() => []?.(), TypeError); +assertThrows(() => ['hi']?.(), TypeError); + +assertThrows(() => ({})?.a['b'], TypeError); +assertEquals(({})?.a?.['b'], undefined); +assertEquals(null?.a['b']().c, undefined); +assertThrows(() => ({})?.['a'].b); +assertEquals(({})?.['a']?.b, undefined); +assertEquals(null?.['a'].b()['c'], undefined); +assertThrows(() => (() => {})?.()(), TypeError); +assertEquals((() => {})?.()?.(), undefined); +assertEquals(null?.()().a['b'], undefined); + +assertEquals(delete undefined?.foo, true); +assertEquals(delete null?.foo, true); +assertEquals(delete undefined?.['foo'], true); +assertEquals(delete null?.['foo'], true); +assertEquals(delete undefined?.(), true); +assertEquals(delete null?.(), true); + +assertEquals(undefined?.(...a), undefined); +assertEquals(null?.(1, ...a), undefined); +assertEquals(({}).a?.(...a), undefined); +assertEquals(({ a: null }).a?.(...a), undefined); +assertEquals(undefined?.(...a)?.(1, ...a), undefined); +assertThrows(() => 5?.(...[]), TypeError); + +const o1 = { x: 0, y: 0, z() {} }; +assertEquals(delete o1?.x, true); +assertEquals(o1.x, undefined); +assertEquals(delete o1?.x, true); +assertEquals(delete o1?.['y'], true); +assertEquals(o1.y, undefined); +assertEquals(delete o1?.['y'], true); +assertEquals(delete o1.z?.(), true); +assertThrows(() => { delete ({})?.foo.bar; }); + +shouldThrowSyntaxError('class C {} class D extends C { foo() { return super?.bar; } }'); +shouldThrowSyntaxError('class C {} class D extends C { foo() { return super?.["bar"]; } }'); +shouldThrowSyntaxError('class C {} class D extends C { constructor() { super?.(); } }'); + +shouldThrowSyntaxError('const o = { C: class {} }; new o?.C();'); +shouldThrowSyntaxError('const o = { C: class {} }; new o?.["C"]();'); +shouldThrowSyntaxError('class C {} new C?.();'); +shouldThrowSyntaxError('function foo() { new?.target; }'); + +shouldThrowSyntaxError('function tag() {} tag?.``;'); +shouldThrowSyntaxError('const o = { tag() {} }; o?.tag``;'); + +const o2 = { + count: 0, + get x() { + this.count += 1; + return () => {}; + }, +}; +o2.x?.y; +assertEquals(o2.count, 1); +o2.x?.['y']; +assertEquals(o2.count, 2); +o2.x?.(); +assertEquals(o2.count, 3); + +assertEquals(true?.5:5, 0.5); diff --git a/deps/v8/test/mjsunit/harmony/private-accessors.js b/deps/v8/test/mjsunit/harmony/private-accessors.js new file mode 100644 index 0000000000..3a828116a1 --- /dev/null +++ b/deps/v8/test/mjsunit/harmony/private-accessors.js @@ -0,0 +1,91 @@ +// Copyright 2019 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Flags: --harmony-private-methods + +"use strict"; + +// Complementary private accessors. +{ + let store = 1; + class C { + get #a() { return store; } + set #a(val) { store = val; } + incA() { this.#a++; } // CountOperation + setA(val) { this.#a = val; } + getA() { return this.#a; } + } + + const c = new C; + assertEquals(store, c.getA()); + assertEquals(1, c.getA()); + c.setA(2); + assertEquals(store, c.getA()); + assertEquals(2, c.getA()); + c.incA(); + assertEquals(store, c.getA()); + assertEquals(3, c.getA()); +} + +// Compound assignment. +{ + let store; + class A { + get #a() { return store; } + set #a(val) { store = val; } + getA() { return this.#a; } + constructor(val) { + ({ y: this.#a } = val); + } + } + + const a = new A({y: 'test'}); + assertEquals('test', a.getA()); +} + +// Accessing super in private accessors. +{ + class A { foo(val) {} } + class C extends A { + set #a(val) { super.foo(val); } + } + new C(); + + class D extends A { + get #a() { return super.foo; } + } + new D(); + + class E extends A { + set #a(val) { super.foo(val); } + get #a() { return super.foo; } + } + new E(); +} + +// Nested private accessors. +{ + class C { + get #a() { + let storeD = 'd'; + class D { + // Shadows outer #a + get #a() { return storeD; } + getD() { return this.#a; } + } + return new D; + } + getA() { + return this.#a; + } + } + assertEquals('d', new C().getA().getD()); +} + +// Duplicate private accessors. +// https://tc39.es/proposal-private-methods/#sec-static-semantics-early-errors +{ + assertThrows('class C { get #a() {} get #a() {} }', SyntaxError); + assertThrows('class C { set #a(val) {} set #a(val) {} }', SyntaxError); +} diff --git a/deps/v8/test/mjsunit/harmony/private-methods.js b/deps/v8/test/mjsunit/harmony/private-methods.js index 360b065f17..fcd80823c1 100644 --- a/deps/v8/test/mjsunit/harmony/private-methods.js +++ b/deps/v8/test/mjsunit/harmony/private-methods.js @@ -281,3 +281,17 @@ new D; new E; } + +// Super access within private methods. +{ + class A { + foo() { return 1; } + } + + class C extends A { + #m() { return super.foo; } + fn() { return this.#m()(); } + } + + assertEquals(1, new C().fn()); +} diff --git a/deps/v8/test/mjsunit/harmony/weakrefs/cleanup-doesnt-iterate-all-holdings.js b/deps/v8/test/mjsunit/harmony/weakrefs/cleanup-doesnt-iterate-all-holdings.js index 20726284bb..ebc4ebf933 100644 --- a/deps/v8/test/mjsunit/harmony/weakrefs/cleanup-doesnt-iterate-all-holdings.js +++ b/deps/v8/test/mjsunit/harmony/weakrefs/cleanup-doesnt-iterate-all-holdings.js @@ -6,6 +6,7 @@ let cleanup_call_count = 0; let cleanup = function(iter) { + print("in cleanup"); if (cleanup_call_count == 0) { // First call: iterate 2 of the 3 holdings let holdings_list = []; @@ -74,11 +75,15 @@ let timeout_func_2 = function() { assertEquals(1, cleanup_call_count); // Create a new object and register it. - let obj = {}; - let wc = fg.register(obj, 100); - obj = null; + (function() { + let obj = {}; + let wc = fg.register(obj, 100); + obj = null; + })(); + // This GC will reclaim the targets. gc(); + assertEquals(1, cleanup_call_count); setTimeout(timeout_func_3, 0); } diff --git a/deps/v8/test/mjsunit/harmony/weakrefs/cleanup-is-a-microtask.js b/deps/v8/test/mjsunit/harmony/weakrefs/cleanup-is-not-a-microtask.js index c6b834e8fb..077bc21e82 100644 --- a/deps/v8/test/mjsunit/harmony/weakrefs/cleanup-is-a-microtask.js +++ b/deps/v8/test/mjsunit/harmony/weakrefs/cleanup-is-not-a-microtask.js @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// Flags: --harmony-weak-refs --expose-gc --noincremental-marking +// Flags: --harmony-weak-refs --expose-gc --noincremental-marking --allow-natives-syntax // This test asserts that the cleanup function call, scheduled by GC, is a // microtask and not a normal task. @@ -11,6 +11,8 @@ // microtask). lso schedule another microtask. Assert that the cleanup // function ran before the other microtask. +let cleanedUp = false; + function scheduleMicrotask(func) { Promise.resolve().then(func); } @@ -18,7 +20,7 @@ function scheduleMicrotask(func) { let log = []; let cleanup = (iter) => { - log.push("cleanup"); + cleanedUp = true; for (holdings of iter) { } } @@ -32,25 +34,29 @@ let o = null; fg.register(o, {}); })(); -let microtask_after_cleanup = () => { - log.push("microtask_after_cleanup"); -} - -let first_microtask = function() { +let microtask = function() { log.push("first_microtask"); - // This schedules the cleanup function as microtask. + // cause GC during a microtask o = null; gc(); - - // Schedule a microtask which should run after the cleanup microtask. - scheduleMicrotask(microtask_after_cleanup); } -scheduleMicrotask(first_microtask); +assertFalse(cleanedUp); + +// enqueue microtask that triggers GC +Promise.resolve().then(microtask); + +// but cleanup callback hasn't been called yet, as we're still in +// synchronous execution +assertFalse(cleanedUp); + +// flush the microtask queue to run the microtask that triggers GC +%PerformMicrotaskCheckpoint(); + +// still no cleanup callback, because it runs after as a separate task +assertFalse(cleanedUp); setTimeout(() => { - // Assert that the functions got called in the right order. - let wanted_log = ["first_microtask", "cleanup", "microtask_after_cleanup"]; - assertEquals(wanted_log, log); + assertTrue(cleanedUp); }, 0); diff --git a/deps/v8/test/mjsunit/harmony/weakrefs/cleanup-on-detached-realm.js b/deps/v8/test/mjsunit/harmony/weakrefs/cleanup-on-detached-realm.js index ca156e0574..9cc548920c 100644 --- a/deps/v8/test/mjsunit/harmony/weakrefs/cleanup-on-detached-realm.js +++ b/deps/v8/test/mjsunit/harmony/weakrefs/cleanup-on-detached-realm.js @@ -4,12 +4,13 @@ // Flags: --harmony-weak-refs --expose-gc --noincremental-marking +let cleanedUp = false; let r = Realm.create(); let FG = Realm.eval(r, "FinalizationGroup"); Realm.detachGlobal(r); let fg = new FG(()=> { - assertUnreachable(); + cleanedUp = true; }); (() => { @@ -20,3 +21,5 @@ let fg = new FG(()=> { })(); gc(); + +setTimeout(function() { assertTrue(cleanedUp); }, 0); diff --git a/deps/v8/test/mjsunit/harmony/weakrefs/finalizationgroup-and-weakref.js b/deps/v8/test/mjsunit/harmony/weakrefs/finalizationgroup-and-weakref.js index bd66f1ce1d..83de3a838b 100644 --- a/deps/v8/test/mjsunit/harmony/weakrefs/finalizationgroup-and-weakref.js +++ b/deps/v8/test/mjsunit/harmony/weakrefs/finalizationgroup-and-weakref.js @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// Flags: --harmony-weak-refs --expose-gc --noincremental-marking --allow-natives-syntax +// Flags: --harmony-weak-refs --expose-gc --noincremental-marking let cleanup_called = false; let cleanup = function(iter) { @@ -32,13 +32,13 @@ gc(); assertNotEquals(undefined, weak_ref.deref()); })(); -%PerformMicrotaskCheckpoint(); -// Next turn. +// Trigger gc in next task +setTimeout(() => { + gc(); -gc(); - -%PerformMicrotaskCheckpoint(); -// Next turn. - -assertTrue(cleanup_called); -assertEquals(undefined, weak_ref.deref()); + // Check that cleanup callback was called in a follow up task + setTimeout(() => { + assertTrue(cleanup_called); + assertEquals(undefined, weak_ref.deref()); + }, 0); +}, 0); diff --git a/deps/v8/test/mjsunit/harmony/weakrefs/two-weakrefs.js b/deps/v8/test/mjsunit/harmony/weakrefs/two-weakrefs.js index c3fc9f741c..c17e7aa969 100644 --- a/deps/v8/test/mjsunit/harmony/weakrefs/two-weakrefs.js +++ b/deps/v8/test/mjsunit/harmony/weakrefs/two-weakrefs.js @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// Flags: --harmony-weak-refs --expose-gc --noincremental-marking --allow-natives-syntax +// Flags: --harmony-weak-refs --expose-gc --noincremental-marking let o1 = {}; let o2 = {}; @@ -21,28 +21,27 @@ gc(); assertNotEquals(undefined, wr2.deref()); })(); -%PerformMicrotaskCheckpoint(); -// New turn. - -wr1.deref(); -o1 = null; -gc(); // deref makes sure we don't clean up wr1 - -%PerformMicrotaskCheckpoint(); -// New turn. - -wr2.deref(); -o2 = null; -gc(); // deref makes sure we don't clean up wr2 - -%PerformMicrotaskCheckpoint(); -// New turn. - -assertEquals(undefined, wr1.deref()); - -gc(); - -%PerformMicrotaskCheckpoint(); -// New turn. - -assertEquals(undefined, wr2.deref()); +// New task +setTimeout(function() { + wr1.deref(); + o1 = null; + gc(); // deref makes sure we don't clean up wr1 + + // New task + setTimeout(function() { + wr2.deref(); + o2 = null; + gc(); // deref makes sure we don't clean up wr2 + + // New task + setTimeout(function() { + assertEquals(undefined, wr1.deref()); + gc(); + + // New task + setTimeout(function() { + assertEquals(undefined, wr2.deref()); + }, 0); + }, 0); + }, 0); +}, 0); diff --git a/deps/v8/test/mjsunit/harmony/weakrefs/weakref-creation-keeps-alive.js b/deps/v8/test/mjsunit/harmony/weakrefs/weakref-creation-keeps-alive.js index 18e3af26ce..4c8641d8aa 100644 --- a/deps/v8/test/mjsunit/harmony/weakrefs/weakref-creation-keeps-alive.js +++ b/deps/v8/test/mjsunit/harmony/weakrefs/weakref-creation-keeps-alive.js @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// Flags: --harmony-weak-refs --expose-gc --noincremental-marking --allow-natives-syntax +// Flags: --harmony-weak-refs --expose-gc --noincremental-marking let wr; (function() { @@ -19,9 +19,8 @@ gc(); assertNotEquals(undefined, wr.deref()); })(); -%PerformMicrotaskCheckpoint(); -// Next turn. - -gc(); - -assertEquals(undefined, wr.deref()); +// Next task. +setTimeout(() => { + gc(); + assertEquals(undefined, wr.deref()); +}, 0); diff --git a/deps/v8/test/mjsunit/harmony/weakrefs/weakref-deref-keeps-alive.js b/deps/v8/test/mjsunit/harmony/weakrefs/weakref-deref-keeps-alive.js index c17f060713..eb02290dfd 100644 --- a/deps/v8/test/mjsunit/harmony/weakrefs/weakref-deref-keeps-alive.js +++ b/deps/v8/test/mjsunit/harmony/weakrefs/weakref-deref-keeps-alive.js @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// Flags: --harmony-weak-refs --expose-gc --noincremental-marking --allow-natives-syntax +// Flags: --harmony-weak-refs --expose-gc --noincremental-marking let wr; let wr_control; // control WeakRef for testing what happens without deref @@ -17,29 +17,29 @@ let strong = {a: wr.deref(), b: wr_control.deref()}; gc(); -%PerformMicrotaskCheckpoint(); -// Next turn. +// Next task. +setTimeout(function() { + // Call deref inside a closure, trying to avoid accidentally storing a strong + // reference into the object in the stack frame. + (function() { + wr.deref(); + })(); -// Call deref inside a closure, trying to avoid accidentally storing a strong -// reference into the object in the stack frame. -(function() { - wr.deref(); -})(); - -strong = null; - -// This GC will clear wr_control. -gc(); + strong = null; -(function() { - assertNotEquals(undefined, wr.deref()); - // Now the control WeakRef got cleared, since nothing was keeping it alive. - assertEquals(undefined, wr_control.deref()); -})(); + // This GC will clear wr_control. + gc(); -%PerformMicrotaskCheckpoint(); -// Next turn. + (function() { + assertNotEquals(undefined, wr.deref()); + // Now the control WeakRef got cleared, since nothing was keeping it alive. + assertEquals(undefined, wr_control.deref()); + })(); -gc(); + // Next task. + setTimeout(function() { + gc(); -assertEquals(undefined, wr.deref()); + assertEquals(undefined, wr.deref()); + }, 0); +}, 0); |