summaryrefslogtreecommitdiff
path: root/deps/v8/test/mjsunit/harmony
diff options
context:
space:
mode:
Diffstat (limited to 'deps/v8/test/mjsunit/harmony')
-rw-r--r--deps/v8/test/mjsunit/harmony/atomics.js251
-rw-r--r--deps/v8/test/mjsunit/harmony/nullish.js143
-rw-r--r--deps/v8/test/mjsunit/harmony/numeric-separator.js11
-rw-r--r--deps/v8/test/mjsunit/harmony/optional-chaining.js119
-rw-r--r--deps/v8/test/mjsunit/harmony/private-accessors.js91
-rw-r--r--deps/v8/test/mjsunit/harmony/private-methods.js14
-rw-r--r--deps/v8/test/mjsunit/harmony/weakrefs/cleanup-doesnt-iterate-all-holdings.js11
-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.js5
-rw-r--r--deps/v8/test/mjsunit/harmony/weakrefs/finalizationgroup-and-weakref.js20
-rw-r--r--deps/v8/test/mjsunit/harmony/weakrefs/two-weakrefs.js51
-rw-r--r--deps/v8/test/mjsunit/harmony/weakrefs/weakref-creation-keeps-alive.js13
-rw-r--r--deps/v8/test/mjsunit/harmony/weakrefs/weakref-deref-keeps-alive.js44
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);