Upload Kmake

This commit is contained in:
Gorochu
2026-05-26 23:36:42 -07:00
parent ba051b2f74
commit 555ec72358
41615 changed files with 13344630 additions and 1 deletions

View File

@ -0,0 +1,194 @@
// Copyright 2020 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.
(function TestNoParameters() {
// Can't omit the "errors" parameter; there's nothing to iterate.
assertThrows(() => { new AggregateError(); });
})();
(function TestNoParameters_NoNew() {
// Can't omit the "errors" parameter; there's nothing to iterate.
assertThrows(() => { AggregateError(); });
})();
(function TestOneParameterErrorsIsArray() {
let error = new AggregateError([1, 20, 4]);
assertEquals('', error.message);
assertEquals([1, 20, 4], error.errors);
})();
(function TestOneParameterErrorsIsArray_NoNew() {
let error = AggregateError([1, 20, 4]);
assertEquals('', error.message);
assertEquals([1, 20, 4], error.errors);
})();
(function TestOneParameterErrosIsAnEmptyArray() {
let error = new AggregateError([]);
assertEquals('', error.message);
assertEquals([], error.errors);
})();
(function TestOneParameterErrorsIsASet() {
let set = new Set();
set.add(5);
set.add(100);
let error = new AggregateError(set);
assertEquals('', error.message);
assertEquals(2, error.errors.length);
assertTrue(error.errors[0] == 5 || error.errors[1] == 5);
assertTrue(error.errors[0] == 100 || error.errors[1] == 100);
})();
(function TestOneParameterErrorsNotIterable() {
assertThrows(() => { new AggregateError(5); });
})();
(function TestOneParameterErrorsNotIterable_NoNew() {
assertThrows(() => { AggregateError(5); });
})();
(function TestTwoParameters() {
let error = new AggregateError([1, 20, 4], 'custom message');
assertEquals('custom message', error.message);
assertEquals([1, 20, 4], error.errors);
})();
(function TestTwoParameters_NoNew() {
let error = AggregateError([1, 20, 4], 'custom message');
assertEquals('custom message', error.message);
assertEquals([1, 20, 4], error.errors);
})();
(function TestTwoParametersMessageNotString() {
let custom = { toString() { return 'hello'; } };
let error = new AggregateError([], custom);
assertEquals('hello', error.message);
})();
(function TestTwoParametersMessageIsSMI() {
let error = new AggregateError([], 44);
assertEquals('44', error.message);
})();
(function TestTwoParametersMessageUndefined() {
let error = new AggregateError([], undefined);
assertFalse(Object.prototype.hasOwnProperty.call(error, 'message'));
})();
(function SetErrors() {
let e = new AggregateError([1]);
e.errors = [4, 5, 6];
assertEquals([4, 5, 6], e.errors);
})();
(function SubClassProto() {
class A extends AggregateError {
constructor() {
super([]);
}
}
let o = new A();
assertEquals(o.__proto__, A.prototype);
})();
(function ErrorsWithHoles() {
let errors = [0];
errors[2] = 2;
let a = new AggregateError(errors);
assertEquals([0, undefined, 2], a.errors);
})();
(function ErrorsIsANewArray(){
let array = [8, 9];
let e = new AggregateError(array);
array.push(1);
assertEquals([8, 9], e.errors);
})();
(function ErrorsIsTheSameArray(){
let e = new AggregateError([9, 6, 3]);
const errors1 = e.errors;
const errors2 = e.errors;
assertSame(errors1, errors2);
})();
(function ErrorsModified(){
let e = new AggregateError([9, 6, 3]);
const errors1 = e.errors;
errors1[0] = 50;
const errors2 = e.errors;
assertEquals([50, 6, 3], errors1);
assertEquals([50, 6, 3], errors2);
})();
(function EmptyErrorsModified1(){
let e = new AggregateError([]);
const errors1 = e.errors;
errors1[0] = 50;
const errors2 = e.errors;
assertEquals([50], errors1);
assertEquals([50], errors2);
})();
(function EmptyErrorsModified2(){
let e = new AggregateError([]);
const errors1 = e.errors;
errors1.push(50);
const errors2 = e.errors;
assertEquals([50], errors1);
assertEquals([50], errors2);
})();
(function AggregateErrorCreation() {
// Verify that we match the spec wrt getting the prototype from the
// newTarget, iterating the errors array and calling toString on the
// message.
let counter = 1;
let prototype_got = 0;
let errors_iterated = 0;
let to_string_called = 0;
// For observing Get(new target, "prototype")
function target() {}
let handler = {
get: (target, prop, receiver) => {
if (prop == 'prototype') {
prototype_got = counter++;
return target.prototype;
}
}
};
let p = new Proxy(target, handler);
// For observing IterableToList(errors)
var errors = {
[Symbol.iterator]() {
return {
next() {
errors_iterated = counter++;
return { done: true };
}
};
}
};
// For observing ToString(message)
let message = { toString: () => { to_string_called = counter++;}}
let o = Reflect.construct(AggregateError, [errors, message], p);
assertEquals(1, prototype_got);
assertEquals(2, to_string_called);
assertEquals(3, errors_iterated);
})();
(function TestErrorsProperties() {
let error = new AggregateError([1, 20, 4]);
let desc = Object.getOwnPropertyDescriptor(error, 'errors');
assertEquals(true, desc.configurable);
assertEquals(false, desc.enumerable);
assertEquals(true, desc.writable);
})();

View File

@ -0,0 +1,53 @@
// Copyright 2016 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.
// Check that @@isConcatSpreadable is checked when set on Object.prototype
"use strict"
var array = [1, 2, 3];
var object = {length: 1, '0': 'a'};
function testConcatDefaults() {
assertEquals(array, [].concat(array));
assertEquals(array, array.concat([]));
assertEquals([1, 2, 3, 1, 2, 3], array.concat(array));
assertEquals([object], [].concat(object));
assertEquals([1, 2, 3, object], array.concat(object));
assertEquals([object], Array.prototype.concat.call(object,[]));
assertEquals([object, 1, 2, 3], Array.prototype.concat.call(object, array));
assertEquals([object, object], Array.prototype.concat.call(object, object));
}
testConcatDefaults();
var concatSpreadable = false;
Object.defineProperty(Array.prototype, Symbol.isConcatSpreadable, {
get() { return concatSpreadable },
configurable: true
});
assertEquals([[], array], [].concat(array));
assertEquals([array, []], array.concat([]));
assertEquals([array, array], array.concat(array));
assertEquals([[], object], [].concat(object));
assertEquals([array, object], array.concat(object));
assertEquals([object, []], Array.prototype.concat.call(object,[]));
assertEquals([object, array], Array.prototype.concat.call(object, array));
assertEquals([object, object], Array.prototype.concat.call(object, object));
concatSpreadable = true;
assertEquals(array, [].concat(array));
assertEquals(array, array.concat([]));
assertEquals([1, 2, 3, 1, 2, 3], array.concat(array));
assertEquals([object], [].concat(object));
assertEquals([1, 2, 3, object], array.concat(object));
assertEquals([object], Array.prototype.concat.call(object,[]));
assertEquals([object, 1, 2, 3], Array.prototype.concat.call(object, array));
assertEquals([object, object], Array.prototype.concat.call(object, object));
delete Array.prototype[Symbol.isConcatSpreadable];
testConcatDefaults();

View File

@ -0,0 +1,48 @@
// Copyright 2016 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.
// Check that @@isConcatSpreadable is checked when set on Object.prototype
"use strict"
var array = [1, 2, 3];
var object = {length: 1, '0': 'a'};
function testConcatDefaults() {
assertEquals(array, [].concat(array));
assertEquals(array, array.concat([]));
assertEquals([1, 2, 3, 1, 2, 3], array.concat(array));
assertEquals([object], [].concat(object));
assertEquals([1, 2, 3, object], array.concat(object));
assertEquals([object], Array.prototype.concat.call(object,[]));
assertEquals([object, 1, 2, 3], Array.prototype.concat.call(object, array));
assertEquals([object, object], Array.prototype.concat.call(object, object));
}
testConcatDefaults();
Array.prototype[Symbol.isConcatSpreadable] = false;
assertEquals([[], array], [].concat(array));
assertEquals([array, []], array.concat([]));
assertEquals([array, array], array.concat(array));
assertEquals([[], object], [].concat(object));
assertEquals([array, object], array.concat(object));
assertEquals([object, []], Array.prototype.concat.call(object,[]));
assertEquals([object, array], Array.prototype.concat.call(object, array));
assertEquals([object, object], Array.prototype.concat.call(object, object));
Array.prototype[Symbol.isConcatSpreadable] = true;
assertEquals(array, [].concat(array));
assertEquals(array, array.concat([]));
assertEquals([1, 2, 3, 1, 2, 3], array.concat(array));
assertEquals([object], [].concat(object));
assertEquals([1, 2, 3, object], array.concat(object));
assertEquals([object], Array.prototype.concat.call(object,[]));
assertEquals([object, 1, 2, 3], Array.prototype.concat.call(object, array));
assertEquals([object, object], Array.prototype.concat.call(object, object));
delete Array.prototype[Symbol.isConcatSpreadable];
testConcatDefaults();

View File

@ -0,0 +1,57 @@
// Copyright 2016 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.
// Check that @@isConcatSpreadable is checked when set on Object.prototype
// with a dictionary backing store.
// Force Object.prototype into dictionary backing store by adding many
// properties.
for (var i = 0; i < 10*1000; i++) {
Object.prototype['generatedProperty'+i] = true;
}
var array = [1, 2, 3];
var object = {length: 1, '0': 'a'};
function testConcatDefaults() {
assertEquals(array, [].concat(array));
assertEquals(array, array.concat([]));
assertEquals([1, 2, 3, 1, 2, 3], array.concat(array));
assertEquals([object], [].concat(object));
assertEquals([1, 2, 3, object], array.concat(object));
assertEquals([object], Array.prototype.concat.call(object,[]));
assertEquals([object, 1, 2, 3], Array.prototype.concat.call(object, array));
assertEquals([object, object], Array.prototype.concat.call(object, object));
}
testConcatDefaults();
var concatSpreadable = false;
Object.defineProperty(Object.prototype, Symbol.isConcatSpreadable, {
get() { return concatSpreadable },
configurable: true
});
assertEquals([[], array], [].concat(array));
assertEquals([array, []], array.concat([]));
assertEquals([array, array], array.concat(array));
assertEquals([[], object], [].concat(object));
assertEquals([array, object], array.concat(object));
assertEquals([object, []], Array.prototype.concat.call(object,[]));
assertEquals([object, array], Array.prototype.concat.call(object, array));
assertEquals([object, object], Array.prototype.concat.call(object, object));
concatSpreadable = true;
assertEquals(array, [].concat(array));
assertEquals(array, array.concat([]));
assertEquals([1, 2, 3, 1, 2, 3], array.concat(array));
assertEquals(['a'], [].concat(object));
assertEquals([1, 2, 3, 'a'], array.concat(object));
assertEquals(['a'], Array.prototype.concat.call(object,[]));
assertEquals(['a', 1, 2, 3], Array.prototype.concat.call(object, array));
assertEquals(['a', 'a'], Array.prototype.concat.call(object, object));
delete Object.prototype[Symbol.isConcatSpreadable];
testConcatDefaults();

View File

@ -0,0 +1,53 @@
// Copyright 2016 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.
// Check that @@isConcatSpreadable is checked when set on Object.prototype
// with a dictionary backing store.
// Force Object.prototype into dictionary backing store by adding many
// properties.
for (var i = 0; i < 10*1000; i++) {
Object.prototype['generatedProperty'+i] = true;
}
var array = [1, 2, 3];
var object = {length: 1, '0': 'a'};
function testConcatDefaults() {
assertEquals(array, [].concat(array));
assertEquals(array, array.concat([]));
assertEquals([1, 2, 3, 1, 2, 3], array.concat(array));
assertEquals([object], [].concat(object));
assertEquals([1, 2, 3, object], array.concat(object));
assertEquals([object], Array.prototype.concat.call(object,[]));
assertEquals([object, 1, 2, 3], Array.prototype.concat.call(object, array));
assertEquals([object, object], Array.prototype.concat.call(object, object));
}
testConcatDefaults();
Object.prototype[Symbol.isConcatSpreadable] = false;
assertEquals([[], array], [].concat(array));
assertEquals([array, []], array.concat([]));
assertEquals([array, array], array.concat(array));
assertEquals([[], object], [].concat(object));
assertEquals([array, object], array.concat(object));
assertEquals([object, []], Array.prototype.concat.call(object,[]));
assertEquals([object, array], Array.prototype.concat.call(object, array));
assertEquals([object, object], Array.prototype.concat.call(object, object));
Object.prototype[Symbol.isConcatSpreadable] = true;
assertEquals(array, [].concat(array));
assertEquals(array, array.concat([]));
assertEquals([1, 2, 3, 1, 2, 3], array.concat(array));
assertEquals(['a'], [].concat(object));
assertEquals([1, 2, 3, 'a'], array.concat(object));
assertEquals(['a'], Array.prototype.concat.call(object,[]));
assertEquals(['a', 1, 2, 3], Array.prototype.concat.call(object, array));
assertEquals(['a', 'a'], Array.prototype.concat.call(object, object));
delete Object.prototype[Symbol.isConcatSpreadable];
testConcatDefaults();

View File

@ -0,0 +1,65 @@
// Copyright 2016 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.
// Check that @@isConcatSpreadable is checked when set on Object.prototype
// with a dictionary backing store.
// Force Object.prototype into dictionary backing store by adding many
// properties.
for (var i = 0; i < 10*1000; i++) {
Object.prototype['generatedProperty'+i] = true;
}
var array = [1, 2, 3];
var object = {length: 1, '0': 'a'};
function SetProperty(receiver, key, value) {
receiver[key] = value;
}
// Force the Keyed Store IC in SetProperty to be generic.
var receiver = {};
for (var i = 0; i < 100; i++) {
SetProperty(receiver, 'prop'+i, 'value');
}
function testConcatDefaults() {
assertEquals(array, [].concat(array));
assertEquals(array, array.concat([]));
assertEquals([1, 2, 3, 1, 2, 3], array.concat(array));
assertEquals([object], [].concat(object));
assertEquals([1, 2, 3, object], array.concat(object));
assertEquals([object], Array.prototype.concat.call(object,[]));
assertEquals([object, 1, 2, 3], Array.prototype.concat.call(object, array));
assertEquals([object, object], Array.prototype.concat.call(object, object));
}
testConcatDefaults();
// Use a generic IC to set @@isConcatSpreadable
SetProperty(Object.prototype, Symbol.isConcatSpreadable, false);
assertEquals([[], array], [].concat(array));
assertEquals([array, []], array.concat([]));
assertEquals([array, array], array.concat(array));
assertEquals([[], object], [].concat(object));
assertEquals([array, object], array.concat(object));
assertEquals([object, []], Array.prototype.concat.call(object,[]));
assertEquals([object, array], Array.prototype.concat.call(object, array));
assertEquals([object, object], Array.prototype.concat.call(object, object));
// Use a generic IC to set @@isConcatSpreadable
SetProperty(Object.prototype, Symbol.isConcatSpreadable, true);
assertEquals(array, [].concat(array));
assertEquals(array, array.concat([]));
assertEquals([1, 2, 3, 1, 2, 3], array.concat(array));
assertEquals(['a'], [].concat(object));
assertEquals([1, 2, 3, 'a'], array.concat(object));
assertEquals(['a'], Array.prototype.concat.call(object,[]));
assertEquals(['a', 1, 2, 3], Array.prototype.concat.call(object, array));
assertEquals(['a', 'a'], Array.prototype.concat.call(object, object));
delete Object.prototype[Symbol.isConcatSpreadable];
testConcatDefaults();

View File

@ -0,0 +1,48 @@
// Copyright 2016 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.
// Check that @@isConcatSpreadable is checked when set on Object.prototype
"use strict"
var array = [1, 2, 3];
var object = {length: 1, '0': 'a'};
function testConcatDefaults() {
assertEquals(array, [].concat(array));
assertEquals(array, array.concat([]));
assertEquals([1, 2, 3, 1, 2, 3], array.concat(array));
assertEquals([object], [].concat(object));
assertEquals([1, 2, 3, object], array.concat(object));
assertEquals([object], Array.prototype.concat.call(object,[]));
assertEquals([object, 1, 2, 3], Array.prototype.concat.call(object, array));
assertEquals([object, object], Array.prototype.concat.call(object, object));
}
testConcatDefaults();
Object.prototype[Symbol.isConcatSpreadable] = false;
assertEquals([[], array], [].concat(array));
assertEquals([array, []], array.concat([]));
assertEquals([array, array], array.concat(array));
assertEquals([[], object], [].concat(object));
assertEquals([array, object], array.concat(object));
assertEquals([object, []], Array.prototype.concat.call(object,[]));
assertEquals([object, array], Array.prototype.concat.call(object, array));
assertEquals([object, object], Array.prototype.concat.call(object, object));
Object.prototype[Symbol.isConcatSpreadable] = true;
assertEquals(array, [].concat(array));
assertEquals(array, array.concat([]));
assertEquals([1, 2, 3, 1, 2, 3], array.concat(array));
assertEquals(['a'], [].concat(object));
assertEquals([1, 2, 3, 'a'], array.concat(object));
assertEquals(['a'], Array.prototype.concat.call(object,[]));
assertEquals(['a', 1, 2, 3], Array.prototype.concat.call(object, array));
assertEquals(['a', 'a'], Array.prototype.concat.call(object, object));
delete Object.prototype[Symbol.isConcatSpreadable];
testConcatDefaults();

View File

@ -0,0 +1,14 @@
// Copyright 2021 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.
var findLast = 'local findLast';
var findLastIndex = 'local findLastIndex';
var array = [];
with (array) {
assertEquals('local findLast', findLast);
assertEquals('local findLastIndex', findLastIndex);
}

View File

@ -0,0 +1,29 @@
// Copyright 2018 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.
{
class MyArray extends Array {
static get [Symbol.species]() {
return Array;
}
}
const wannabe = new MyArray();
const flattened = wannabe.flat(Infinity);
assertEquals(false, flattened instanceof MyArray);
assertEquals(true, flattened instanceof Array);
}
{
class MyArray extends Array {
static get [Symbol.species]() {
return this;
}
}
const wannabe = new MyArray();
const flattened = wannabe.flat(Infinity);
assertEquals(true, flattened instanceof MyArray);
assertEquals(true, flattened instanceof Array);
}

View File

@ -0,0 +1,63 @@
// Copyright 2018 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.
assertEquals(Array.prototype.flat.length, 0);
assertEquals(Array.prototype.flat.name, 'flat');
{
const input = [1, [2], [[3]]];
assertEquals(input.flat(), [1, 2, [3]]);
assertEquals(input.flat(1), [1, 2, [3]]);
assertEquals(input.flat(true), [1, 2, [3]]);
assertEquals(input.flat(undefined), [1, 2, [3]]);
assertEquals(input.flat(-Infinity), [1, [2], [[3]]]);
assertEquals(input.flat(-1), [1, [2], [[3]]]);
assertEquals(input.flat(-0), [1, [2], [[3]]]);
assertEquals(input.flat(0), [1, [2], [[3]]]);
assertEquals(input.flat(false), [1, [2], [[3]]]);
assertEquals(input.flat(null), [1, [2], [[3]]]);
assertEquals(input.flat(''), [1, [2], [[3]]]);
assertEquals(input.flat('foo'), [1, [2], [[3]]]);
assertEquals(input.flat(/./), [1, [2], [[3]]]);
assertEquals(input.flat([]), [1, [2], [[3]]]);
assertEquals(input.flat({}), [1, [2], [[3]]]);
assertEquals(
input.flat(new Proxy({}, {})), [1, [2], [[3]]]);
assertEquals(input.flat((x) => x), [1, [2], [[3]]]);
assertEquals(
input.flat(String), [1, [2], [[3]]]);
assertEquals(input.flat(2), [1, 2, 3]);
assertEquals(input.flat(Infinity), [1, 2, 3]);
assertThrows(() => { input.flat(Symbol()); }, TypeError);
assertThrows(() => { input.flat(Object.create(null)); }, TypeError);
}
{
const input = { 0: 'a', 1: 'b', 2: 'c', length: 'wat' };
assertEquals(Array.prototype.flat.call(input, Infinity), []);
}
{
let count = 0;
const input = {
get length() { ++count; return 0; }
};
const result = Array.prototype.flat.call(input, Infinity);
assertEquals(count, 1);
}
{
const descriptor = Object.getOwnPropertyDescriptor(
Array.prototype,
'flat'
);
assertEquals(descriptor.value, Array.prototype.flat);
assertEquals(descriptor.writable, true);
assertEquals(descriptor.enumerable, false);
assertEquals(descriptor.configurable, true);
}

View File

@ -0,0 +1,29 @@
// Copyright 2018 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.
{
class MyArray extends Array {
static get [Symbol.species]() {
return Array;
}
}
const wannabe = new MyArray();
const result = wannabe.flatMap(x => [x, x]);
assertEquals(false, result instanceof MyArray);
assertEquals(true, result instanceof Array);
}
{
class MyArray extends Array {
static get [Symbol.species]() {
return this;
}
}
const wannabe = new MyArray();
const result = wannabe.flatMap(x => [x, x]);
assertEquals(true, result instanceof MyArray);
assertEquals(true, result instanceof Array);
}

View File

@ -0,0 +1,162 @@
// Copyright 2018 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: --allow-natives-syntax
assertEquals(Array.prototype.flatMap.length, 1);
assertEquals(Array.prototype.flatMap.name, 'flatMap');
assertEquals(
[1, 2, 3, 4].flatMap((element) => [element, element ** 2]),
[1, 1, 2, 4, 3, 9, 4, 16]
);
assertEquals(
[1, 2, 3, 4].flatMap((element) => [[element, element ** 2]]),
[[1, 1], [2, 4], [3, 9], [4, 16]]
);
{
const elements = new Set([
-Infinity,
-1,
-0,
+0,
+1,
Infinity,
null,
undefined,
true,
false,
'',
'foo',
/./,
[],
{},
Object.create(null),
new Proxy({}, {}),
Symbol(),
x => x ** 2,
String
]);
for (const value of elements) {
assertEquals(
[value].flatMap((element) => [element, element]),
[value, value]
);
}
}
{
const array = [42];
assertEquals(
[array].flatMap((element) => [element, element]),
[array, array]
);
}
{
const nonCallables = new Set([
-Infinity,
-1,
-0,
+0,
+1,
Infinity,
null,
undefined,
true,
false,
'',
'foo',
/./,
[],
{},
Object.create(null),
new Proxy({}, {}),
Symbol(),
]);
for (const nonCallable of nonCallables) {
assertThrows(() => {
[].flatMap(nonCallable);
}, TypeError);
}
}
{
const object = {
foo: 42,
get length() {
object.foo = 0;
}
};
const result = [object].flatMap((element) => [element, element]);
%HeapObjectVerify(result);
assertEquals(result, [object, object]);
assertEquals(result[0].foo, 42);
}
assertThrows(() => {
Array.prototype.flatMap.call(null, (element) => element);
}, TypeError);
assertThrows(() => {
Array.prototype.flatMap.call(undefined, (element) => element);
}, TypeError);
assertEquals(
Array.prototype.flatMap.call(
{
length: 1,
0: 'a',
1: 'b',
},
(element) => element
),
['a']
);
assertEquals(
Array.prototype.flatMap.call(
{
length: 2,
0: 'a',
1: 'b',
},
(element) => element
),
['a', 'b']
);
{
const result = [1, 2, 3].flatMap(function() {
return [this];
}, 'abc');
assertEquals(true, result[0] == 'abc');
assertEquals(true, result[1] == 'abc');
assertEquals(true, result[2] == 'abc');
}
{
const input = { 0: 'a', 1: 'b', 2: 'c', length: 'wat' };
assertEquals(Array.prototype.flatMap.call(input, x => [x]), []);
}
{
let count = 0;
const input = {
get length() { ++count; return 0; }
};
const result = Array.prototype.flatMap.call(input, x => [x]);
assertEquals(count, 1);
}
{
const descriptor = Object.getOwnPropertyDescriptor(
Array.prototype,
'flatMap'
);
assertEquals(descriptor.value, Array.prototype.flatMap);
assertEquals(descriptor.writable, true);
assertEquals(descriptor.enumerable, false);
assertEquals(descriptor.configurable, true);
}

View File

@ -0,0 +1,60 @@
// Copyright 2023 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.
async function* asyncGen(n) {
for (let i = 0; i < n; i++) yield i * 2;
}
function* gen() {
yield 42;
yield 43;
yield 44;
}
(async function TestArrayFromAsync() {
const arr = await Array.fromAsync(asyncGen(4));
assertEquals([0, 2, 4, 6], arr);
})();
(async function TestArrayFromAsyncSyncIterator() {
const arr = await Array.fromAsync(gen());
assertEquals([42, 43, 44], arr);
})();
(async function TestArrayFromAsyncWithMapping() {
const arr = await Array.fromAsync(asyncGen(4), v => v **2);
assertEquals([0, 4, 16, 36], arr);
})();
(async function TestArrayFromAsyncSyncIteratorWithMapping() {
const arr = await Array.fromAsync(gen(), v => v + 4);
assertEquals([46, 47, 48], arr);
})();
(async function TestArrayFromAsyncSyncArrayWithMapping() {
const arr = await Array.fromAsync([1, 2, 3], v => v + 4);
assertEquals([5, 6, 7], arr);
})();
(async function TestArrayFromAsyncArrayLike() {
const arrayLike = {
length: 3,
0: 1,
1: 2,
2: 3
};
const arr = await Array.fromAsync(arrayLike);
assertEquals([1, 2, 3], arr);
})();
(async function TestArrayFromAsyncArrayLikeWithMapping() {
const arrayLike = {
length: 3,
0: 1,
1: 2,
2: 3
};
const arr = await Array.fromAsync(arrayLike, v => v **2);
assertEquals([1, 4, 9], arr);
})();

View File

@ -0,0 +1,20 @@
// Copyright 2021 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.
(function () {
var array = [,];
function findLast() {
return array.findLast(v => v > 0);
}
assertEquals(findLast(), undefined);
array.__proto__.push(6);
assertEquals(findLast(), 6);
array = [6, -1, 5];
assertEquals(findLast(), 5);
})();

View File

@ -0,0 +1,20 @@
// Copyright 2021 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.
(function () {
var array = [,];
function findLastIndex() {
return array.findLastIndex(v => v > 0);
}
assertEquals(findLastIndex(), -1);
array.__proto__.push(6);
assertEquals(findLastIndex(), 0);
array = [6, -1, 5];
assertEquals(findLastIndex(), 2);
})();

View File

@ -0,0 +1,42 @@
// Copyright 2017 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.
// Array.prototype.sort + TypedArray.prototype.sort: comparefn must be either a
// function or undefined.
// https://github.com/tc39/ecma262/pull/785
const types = [
Array,
Int8Array, Uint8Array,
Int16Array, Uint16Array,
Int32Array, Uint32Array,
Uint8ClampedArray,
Float32Array, Float64Array,
];
for (const type of types) {
const array = new type();
array[0] = 1;
array[1] = 2;
array[2] = 3;
array.sort();
array.sort(undefined);
array.sort(() => {});
assertThrows(() => { array.sort(null); }, TypeError);
assertThrows(() => { array.sort(true); }, TypeError);
assertThrows(() => { array.sort(false); }, TypeError);
assertThrows(() => { array.sort(''); }, TypeError);
assertThrows(() => { array.sort(0); }, TypeError);
assertThrows(() => { array.sort(42); }, TypeError);
assertThrows(() => { array.sort([]); }, TypeError);
assertThrows(() => { array.sort(/./); }, TypeError);
assertThrows(() => { array.sort({}); }, TypeError);
assertThrows(() => { array.sort(Symbol()); }, TypeError);
}
assertThrows(
() => Array.prototype.sort.call(null, 42), TypeError,
'The comparison function must be either a function or undefined: 42');

View File

@ -0,0 +1,13 @@
// Copyright 2022 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.
(function TestBigPacked() {
let a = [];
for (let i = 0; i < 50000; i++) a.push(i);
let r = a.toReversed();
for (let i = 0; i < 50000; i++) {
assertEquals(r[i], a.at(-(i+1)));
}
})();

View File

@ -0,0 +1,141 @@
// Copyright 2022 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.
assertEquals(0, Array.prototype.toReversed.length);
assertEquals("toReversed", Array.prototype.toReversed.name);
(function TestSmiPacked() {
let a = [1,2,3,4];
let r = a.toReversed();
assertEquals([1,2,3,4], a);
assertEquals([4,3,2,1], r);
assertFalse(a === r);
})();
(function TestDoublePacked() {
let a = [1.1,2.2,3.3,4.4];
let r = a.toReversed();
assertEquals([1.1,2.2,3.3,4.4], a);
assertEquals([4.4,3.3,2.2,1.1], r);
assertFalse(a === r);
})();
(function TestPacked() {
let a = [true,false,1,42.42];
let r = a.toReversed();
assertEquals([true,false,1,42.42], a);
assertEquals([42.42,1,false,true], r);
assertFalse(a === r);
})();
(function TestSmiHoley() {
let a = [1,,3,4];
let r = a.toReversed();
assertEquals([1,,3,4], a);
assertEquals([4,3,undefined,1], r);
assertFalse(a.hasOwnProperty(1));
assertTrue(r.hasOwnProperty(2));
assertFalse(a === r);
})();
(function TestDoubleHoley() {
let a = [1.1,,3.3,4.4];
let r = a.toReversed();
assertEquals([1.1,,3.3,4.4], a);
assertEquals([4.4,3.3,undefined,1.1], r);
assertFalse(a.hasOwnProperty(1));
assertTrue(r.hasOwnProperty(2));
assertFalse(a === r);
})();
(function TestHoley() {
let a = [true,false,,1,42.42];
let r = a.toReversed();
assertEquals([true,false,,1,42.42], a);
assertEquals([42.42,1,undefined,false,true], r);
assertFalse(a.hasOwnProperty(2));
assertTrue(r.hasOwnProperty(2));
assertFalse(a === r);
})();
(function TestGeneric() {
let a = { length: 4,
get "0"() { return "hello"; },
get "1"() { return "cursed"; },
get "2"() { return "java"; },
get "3"() { return "script" } };
let r = Array.prototype.toReversed.call(a);
assertEquals("hello", a[0]);
assertEquals(["script","java","cursed","hello"], r);
assertFalse(a === r);
assertTrue(Array.isArray(r));
assertEquals(Array, r.constructor);
})();
(function TestReadOrder() {
let order = [];
let a = { length: 4,
get "0"() { order.push("4th"); return "4th"; },
get "1"() { order.push("3rd"); return "3rd"; },
get "2"() { order.push("2nd"); return "2nd"; },
get "3"() { order.push("1st"); return "1st"; } };
let r = Array.prototype.toReversed.call(a);
assertEquals(["1st","2nd","3rd","4th"], r);
assertEquals(["1st","2nd","3rd","4th"], order);
})();
(function TestEmpty() {
assertEquals([], [].toReversed());
})();
(function TestTooBig() {
let a = { length: Math.pow(2, 32) };
assertThrows(() => Array.prototype.toReversed.call(a), RangeError);
})();
(function TestNoSpecies() {
class MyArray extends Array {
static get [Symbol.species]() { return MyArray; }
}
assertEquals(Array, (new MyArray()).toReversed().constructor);
})();
// All tests after this have an invalidated elements-on-prototype protector.
(function TestNoHoles() {
let a = [,,,,];
Array.prototype[3] = "on proto";
let r = a.toReversed();
assertEquals(["on proto",undefined,undefined,undefined], r);
for (let i = 0; i < a.length; i++) {
assertFalse(a.hasOwnProperty(i));
assertTrue(r.hasOwnProperty(i));
}
})();
(function TestMidIterationShenanigans() {
let a = { length: 4,
"0": 1,
get "1"() { a.length = 1; return 2; },
"2": 3,
"3": 4,
__proto__: Array.prototype };
// The length is cached before iteration, so mid-iteration resizing does not
// affect the copied array length.
let r = a.toReversed();
assertEquals(1, a.length);
assertEquals([4,3,2,1], r);
// Values can be changed mid-iteration.
a = { length: 4,
"0": 1,
get "1"() { a[0] = "poof"; return 2; },
"2": 3,
"3": 4,
__proto__: Array.prototype };
r = a.toReversed();
assertEquals([4,3,2,"poof"], r);
})();
assertEquals(Array.prototype[Symbol.unscopables].toReversed, true);

View File

@ -0,0 +1,134 @@
// Copyright 2022 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.
assertEquals(1, Array.prototype.toSorted.length);
assertEquals("toSorted", Array.prototype.toSorted.name);
function TerribleCopy(input, fillHoles) {
let copy;
if (Array.isArray(input)) {
copy = new Array(input.length);
} else {
copy = { length: input.length };
}
for (let i = 0; i < input.length; ++i) {
if (i in input) {
copy[i] = input[i];
} else if (fillHoles) {
copy[i] = undefined;
}
}
return copy;
}
function AssertToSortedAndSortSameResult(input, ...args) {
const orig = TerribleCopy(input, false);
const s = Array.prototype.toSorted.apply(input, args);
const copy = TerribleCopy(input, true);
Array.prototype.sort.apply(copy, args);
// The in-place sorted version should be pairwise equal to the toSorted,
// modulo being an actual Array if the input is generic, and holes should
// be filled with undefined.
if (Array.isArray(input)) {
assertEquals(copy, s);
} else {
assertEquals(copy.length, s.length);
for (let i = 0; i < copy.length; i++) {
assertTrue(i in copy);
assertTrue(i in s);
assertEquals(copy[i], s[i]);
}
}
// The original input should be unchanged.
assertEquals(orig, input);
// The result of toSorted() is a copy.
assertFalse(s === input);
}
function TestToSortedBasicBehaviorHelper(input) {
// No custom comparator.
AssertToSortedAndSortSameResult(input);
// Custom comparator.
AssertToSortedAndSortSameResult(input, (x, y) => {
if (x < y) return -1;
if (x > y) return 1;
return 0;
});
}
// Smi packed
TestToSortedBasicBehaviorHelper([1,3,2,4]);
// Double packed
TestToSortedBasicBehaviorHelper([1.1,3.3,2.2,4.4]);
// Packed
TestToSortedBasicBehaviorHelper([true,false,1,42.42,null,"foo"]);
// Smi holey
TestToSortedBasicBehaviorHelper([1,,3,,2,,4,,]);
// Double holey
TestToSortedBasicBehaviorHelper([1.1,,3.3,,2.2,,4.4,,]);
// Holey
TestToSortedBasicBehaviorHelper([true,,false,,1,,42.42,,null,,"foo",,]);
// Generic
TestToSortedBasicBehaviorHelper({ length: 4,
get "0"() { return "hello"; },
get "1"() { return "cursed"; },
get "2"() { return "java"; },
get "3"() { return "script" } });
(function TestSnapshotAtBeginning() {
const a = [1,3,4,2];
// Use a cursed comparator that mutates the original array. toSorted, like
// sort, takes a snapshot at the beginning.
const s = a.toSorted((x, y) => {
a.pop();
if (x < y) return -1;
if (x > y) return 1;
return 0;
});
assertEquals([1,2,3,4], s);
assertEquals(0, a.length);
})();
(function TestBig() {
const a = [];
a[50001] = 42.42;
a.toSorted();
})();
(function TestTooBig() {
const a = { length: Math.pow(2, 32) };
assertThrows(() => Array.prototype.toSorted.call(a), RangeError);
})();
(function TestNoSpecies() {
class MyArray extends Array {
static get [Symbol.species]() { return MyArray; }
}
assertEquals(Array, (new MyArray()).toSorted().constructor);
})();
// All tests after this have an invalidated elements-on-prototype protector.
(function TestNoHoles() {
const a = [,,,,];
Array.prototype[3] = "on proto";
const s = a.toSorted();
assertEquals(["on proto",undefined,undefined,undefined], s);
assertEquals(a.length, s.length)
for (let i = 0; i < a.length; i++) {
assertFalse(a.hasOwnProperty(i));
assertTrue(s.hasOwnProperty(i));
}
})();
assertEquals(Array.prototype[Symbol.unscopables].toSorted, true);

View File

@ -0,0 +1,10 @@
// Copyright 2022 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.
(function TestBigPacked() {
let a = [];
for (let i = 0; i < 50000; i++) a.push(i);
let r = a.toSpliced();
})();

View File

@ -0,0 +1,159 @@
// Copyright 2022 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.
assertEquals(2, Array.prototype.toSpliced.length);
assertEquals("toSpliced", Array.prototype.toSpliced.name);
function TerribleCopy(input) {
let copy;
if (Array.isArray(input)) {
copy = [...input];
} else {
copy = { length: input.length };
for (let i = 0; i < input.length; i++) {
copy[i] = input[i];
}
}
return copy;
}
function AssertToSplicedAndSpliceSameResult(input, ...args) {
const orig = TerribleCopy(input);
const s = Array.prototype.toSpliced.apply(input, args);
const copy = TerribleCopy(input);
Array.prototype.splice.apply(copy, args);
// The in-place spliced version should be pairwise equal to the toSpliced,
// modulo being an actual Array if the input is generic.
if (Array.isArray(input)) {
assertEquals(copy, s);
} else {
assertEquals(copy.length, s.length);
for (let i = 0; i < copy.length; i++) {
assertEquals(copy[i], s[i]);
}
}
// The original input should be unchanged.
assertEquals(orig, input);
// The result of toSpliced() is a copy.
assertFalse(s === input);
}
function TestToSplicedBasicBehaviorHelper(input, itemsToInsert) {
const startIndices = [0, 1, -1, -100, Infinity, -Infinity];
const deleteCounts = [0, 1, 2, 3];
AssertToSplicedAndSpliceSameResult(input);
for (let startIndex of startIndices) {
AssertToSplicedAndSpliceSameResult(input, startIndex);
for (let deleteCount of deleteCounts) {
AssertToSplicedAndSpliceSameResult(input, startIndex, deleteCount);
AssertToSplicedAndSpliceSameResult(input, startIndex, deleteCount,
...itemsToInsert);
}
}
}
// Smi packed
TestToSplicedBasicBehaviorHelper([1,2,3,4], [5,6]);
// Double packed
TestToSplicedBasicBehaviorHelper([1.1,2.2,3.3,4.4], [5.5,6.6]);
// Packed
TestToSplicedBasicBehaviorHelper([true,false,1,42.42], [null,"foo"]);
// Generic
TestToSplicedBasicBehaviorHelper({ length: 4,
get "0"() { return "hello"; },
get "1"() { return "cursed"; },
get "2"() { return "java"; },
get "3"() { return "script" } },
["foo","bar"]);
(function TestReadOrder() {
const order = [];
const a = { length: 4,
get "0"() { order.push("1st"); return "1st"; },
get "1"() { order.push("2nd"); return "2nd"; },
get "2"() { order.push("3rd"); return "3rd"; },
get "3"() { order.push("4th"); return "4th"; } };
const s = Array.prototype.toSpliced.call(a);
assertEquals(["1st","2nd","3rd","4th"], s);
assertEquals(["1st","2nd","3rd","4th"], order);
})();
(function TestTooBig() {
const a = { length: Math.pow(2, 32) };
assertThrows(() => Array.prototype.toSpliced.call(a), RangeError);
})();
(function TestNoSpecies() {
class MyArray extends Array {
static get [Symbol.species]() { return MyArray; }
}
assertEquals(Array, (new MyArray()).toSpliced().constructor);
})();
(function TestEmpty() {
assertEquals([], [].toSpliced());
})();
function TestFastSourceEmpty(input, itemsToInsert) {
// Create an empty input Array of the same ElementsKind with splice().
TestToSplicedBasicBehaviorHelper(input.splice(), itemsToInsert);
}
// Packed
TestFastSourceEmpty([1,2,3,4], [5,6]);
// Double packed
TestFastSourceEmpty([1.1,2.2,3.3,4.4], [5.5,6.6]);
// Packed
TestFastSourceEmpty([true,false,1,42.42], [null,"foo"]);
// All tests after this have an invalidated elements-on-prototype protector.
(function TestNoHoles() {
const a = [,,,,];
Array.prototype[3] = "on proto";
const s = a.toSpliced();
assertEquals([undefined,undefined,undefined,"on proto"], s);
for (let i = 0; i < a.length; i++) {
assertFalse(a.hasOwnProperty(i));
assertTrue(s.hasOwnProperty(i));
}
})();
(function TestMidIterationShenanigans() {
{
const a = { length: 4,
"0": 1,
get "1"() { a.length = 1; return 2; },
"2": 3,
"3": 4,
__proto__: Array.prototype };
// The length is cached before iteration, so mid-iteration resizing does not
// affect the copied array length.
const s = a.toSpliced();
assertEquals(1, a.length);
assertEquals([1,2,3,4], s);
}
{
// Values can be changed mid-iteration.
const a = { length: 4,
"0": 1,
get "1"() { a[3] = "poof"; return 2; },
"2": 3,
"3": 4,
__proto__: Array.prototype };
const s = a.toSpliced();
assertEquals([1,2,3,"poof"], s);
}
})();
assertEquals(Array.prototype[Symbol.unscopables].toSpliced, true);

View File

@ -0,0 +1,135 @@
// Copyright 2022 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.
"use strict";
assertEquals(2, Array.prototype.with.length);
assertEquals("with", Array.prototype.with.name);
const values = [1, 1.1, true, false, undefined, null, "foo", {}];
(function TestSmiPacked() {
let a = [1,2,3,4];
for (let v of values) {
let b = a.with(1, v);
assertEquals([1,2,3,4], a);
assertEquals([1,v,3,4], b);
assertFalse(a === b);
let c = a.with(-1, v);
assertEquals([1,2,3,4], a);
assertEquals([1,2,3,v], c);
assertFalse(a === c);
}
})();
(function TestDoublePacked() {
let a = [1.1,2.2,3.3,4.4];
for (let v of values) {
let b = a.with(1, v);
assertEquals([1.1,2.2,3.3,4.4], a);
assertEquals([1.1,v,3.3,4.4], b);
assertFalse(a === b);
let c = a.with(-1, v);
assertEquals([1.1,2.2,3.3,4.4], a);
assertEquals([1.1,2.2,3.3,v], c);
assertFalse(a === c);
}
})();
(function TestPacked() {
let a = [true,false,1,42.42];
for (let v of values) {
let b = a.with(1, v);
assertEquals([true,false,1,42.42], a);
assertEquals([true,v,1,42.42], b);
assertFalse(a === b);
let c = a.with(-1, v);
assertEquals([true,false,1,42.42], a);
assertEquals([true,false,1,v], c);
assertFalse(a === c);
}
})();
(function TestGeneric() {
let a = { length: 4,
get "0"() { return "hello"; },
get "1"() { return "cursed"; },
get "2"() { return "java"; },
get "3"() { return "script" } };
for (let v of values) {
let b = Array.prototype.with.call(a, 1, v);
assertEquals("cursed", a[1]);
assertEquals(["hello",v,"java","script"], b);
assertFalse(a === b);
assertTrue(Array.isArray(b));
assertEquals(Array, b.constructor);
let c = Array.prototype.with.call(a, -1, v);
assertEquals("script", a[a.length-1]);
assertEquals(["hello","cursed","java",v], c);
assertFalse(a === c);
assertTrue(Array.isArray(c));
assertEquals(Array, c.constructor);
}
})();
(function TestTooBig() {
let a = { length: Math.pow(2, 32) };
assertThrows(() => Array.prototype.with.call(a, 1, 42), RangeError);
})();
(function TestNoSpecies() {
class MyArray extends Array {
static get [Symbol.species]() { return MyArray; }
}
let a = new MyArray();
a.length = 4;
assertEquals(Array, a.with(1,42).constructor);
})();
(function TestOutOfBounds() {
let a = [1,2,3,4];
assertThrows(() => { a.with(a.length, 42); }, RangeError);
assertThrows(() => { a.with(-a.length - 1, 42); }, RangeError);
})();
(function TestIndexShenanigans() {
let a = [1,2,3,4];
// The index can resize and do other shenanigans since it's coerced before
// iteration.
let b = a.with({ valueOf() { a.length = 2; return 1; } }, 42);
assertEquals([1,2], a);
assertEquals([1,42,undefined,undefined], b);
// Holey.
a = [1,2,3,4,,,];
let c = a.with({ valueOf() { a.length = 2; return 1; } }, 42);
assertEquals([1,2], a);
assertEquals([1,42,undefined,undefined,undefined,undefined], c);
a = [1,2,3,4];
let d = a.with({ valueOf() { a[2] = "barf"; return 1; } }, 42);
assertEquals([1,2,"barf",4], a);
assertEquals([1,42,"barf",4], d);
})();
(function TestValuePassthrough() {
let a = [1,2,3,4];
// The value isn't used in any meaningful sense by with.
a.with(1, { valueOf() { assertUnreachable(); } });
})();
// All tests after this have an invalidated elements-on-prototype protector.
(function TestNoHoles() {
let a = [,,,,];
Array.prototype[3] = "on proto";
for (let v of values) {
let b = a.with(1,v);
assertEquals([undefined,v,undefined,"on proto"], b);
assertTrue(b.hasOwnProperty('0'));
assertTrue(b.hasOwnProperty('1'));
assertTrue(b.hasOwnProperty('2'));
assertTrue(b.hasOwnProperty('3'));
}
})();

View File

@ -0,0 +1,172 @@
// Copyright 2022 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: --allow-natives-syntax
function TestTransfer(method) {
assertEquals(0, ArrayBuffer.prototype[method].length);
assertEquals(method, ArrayBuffer.prototype[method].name);
function AssertDetached(ab) {
assertTrue(ab.detached);
assertEquals(0, ab.byteLength);
assertThrows(() => (new Uint8Array(ab)).sort(), TypeError);
}
function AssertResizable(originalResizable, newResizable) {
if (method === 'transfer') {
assertEquals(originalResizable, newResizable);
} else {
assertFalse(newResizable);
}
}
const IndicesAndValuesForTesting = [[1, 4], [4, 18], [17, 255], [518, 48]];
function WriteTestData(ab) {
let u8 = new Uint8Array(ab);
for (let [idx, val] of IndicesAndValuesForTesting) {
u8[idx] = val;
}
}
function AssertBufferContainsTestData(ab) {
let u8 = new Uint8Array(ab);
for (let [idx, val] of IndicesAndValuesForTesting) {
if (idx < u8.length) {
assertEquals(val, u8[idx]);
}
}
}
function TestSameLength(len, opts) {
let ab = new ArrayBuffer(len, opts);
WriteTestData(ab);
const resizable = ab.resizable;
const xfer = ab[method]();
assertEquals(len, xfer.byteLength);
AssertResizable(resizable, xfer.resizable);
AssertBufferContainsTestData(xfer);
AssertDetached(ab);
}
TestSameLength(1024);
TestSameLength(1024, {maxByteLength: 2048});
function TestGrow(len, opts) {
let ab = new ArrayBuffer(len, opts);
const resizable = ab.resizable;
WriteTestData(ab);
const newLen = len * 2 + 128; // +128 to ensure newLen is never 0
const xfer = ab[method](newLen);
assertEquals(newLen, xfer.byteLength);
AssertResizable(resizable, xfer.resizable);
if (len > 0) AssertBufferContainsTestData(xfer);
AssertDetached(ab);
// The new memory should be zeroed.
let u8 = new Uint8Array(xfer);
for (let i = len; i < newLen; i++) {
assertEquals(0, u8[i]);
}
}
TestGrow(1024);
TestGrow(0);
if (method === 'transfer') {
// Cannot transfer to a new byte length > max byte length.
assertThrows(() => TestGrow(1024, {maxByteLength: 2048}), RangeError);
} else {
TestGrow(1024, {maxByteLength: 2048});
}
TestGrow(0, {maxByteLength: 2048});
function TestNonGrow(len, opts) {
for (let newLen
of [len / 2, // shrink
0 // 0 special case
]) {
let ab = new ArrayBuffer(len, opts);
WriteTestData(ab);
const resizable = ab.resizable;
const xfer = ab[method](newLen);
assertEquals(newLen, xfer.byteLength);
AssertResizable(resizable, xfer.resizable);
if (len > 0) AssertBufferContainsTestData(xfer);
AssertDetached(ab);
}
}
TestNonGrow(1024);
TestNonGrow(1024, {maxByteLength: 2048});
TestNonGrow(0);
TestNonGrow(0, {maxByteLength: 2048});
(function TestParameterConversion() {
const len = 1024;
{
let ab = new ArrayBuffer(len);
const detach = {
valueOf() {
%ArrayBufferDetach(ab);
return len;
}
};
assertThrows(() => ab[method](detach), TypeError);
}
{
let ab = new ArrayBuffer(len, {maxByteLength: len * 4});
const resizable = ab.resizable;
const shrink = {
valueOf() {
ab.resize(len / 2);
return len;
}
};
const xfer = ab[method](shrink);
AssertResizable(resizable, xfer.resizable);
assertEquals(len, xfer.byteLength);
}
{
let ab = new ArrayBuffer(len, {maxByteLength: len * 4});
const resizable = ab.resizable;
const grow = {
valueOf() {
ab.resize(len * 2);
return len;
}
};
const xfer = ab[method](grow);
AssertResizable(resizable, xfer.resizable);
assertEquals(len, xfer.byteLength);
}
})();
(function TestCannotBeSAB() {
const len = 1024;
let sab = new SharedArrayBuffer(1024);
let gsab = new SharedArrayBuffer(len, {maxByteLength: len * 4});
assertThrows(() => ArrayBuffer.prototype[method].call(sab), TypeError);
assertThrows(() => ArrayBuffer.prototype[method].call(gsab), TypeError);
})();
(function TestInvalidLength() {
for (let newLen of [-1024, Number.MAX_SAFE_INTEGER + 1]) {
let ab = new ArrayBuffer(1024);
assertThrows(() => ab[method](newLen), RangeError);
}
})();
(function TestEmptySourceStore() {
let ab = new ArrayBuffer();
let xfer = ab[method]()[method](1024);
})();
if (typeof WebAssembly !== 'undefined') {
// WebAssembly buffers cannot be detached.
const memory = new WebAssembly.Memory({initial: 1});
assertThrows(() => memory.buffer[method](), TypeError);
}
}
TestTransfer('transfer');
TestTransfer('transferToFixedLength');

View File

@ -0,0 +1,123 @@
// Copyright 2018 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.
// test basic interleaving
(function () {
const actual = [];
const expected = [ 'await', 1, 'await', 2 ];
const iterations = 2;
async function pushAwait() {
actual.push('await');
}
async function callAsync() {
for (let i = 0; i < iterations; i++) {
await pushAwait();
}
return 0;
}
function checkAssertions() {
assertArrayEquals(expected, actual,
'Async/await and promises should be interleaved.');
}
assertPromiseResult((async() => {
callAsync();
return new Promise(function (resolve) {
actual.push(1);
resolve();
}).then(function () {
actual.push(2);
}).then(checkAssertions);
})());
})();
// test async generators
(function () {
const actual = [];
const expected = [ 'await', 1, 'await', 2 ];
const iterations = 2;
async function pushAwait() {
actual.push('await');
}
async function* callAsync() {
for (let i = 0; i < iterations; i++) {
await pushAwait();
}
return 0;
}
function checkAssertions() {
assertArrayEquals(expected, actual,
'Async/await and promises should be interleaved when using async generators.');
}
assertPromiseResult((async() => {
callAsync().next();
return new Promise(function (resolve) {
actual.push(1);
resolve();
}).then(function () {
actual.push(2);
}).then(checkAssertions);
})());
})();
// test yielding from async generators
(function () {
const actual = [];
const expected = [
'Promise: 6',
'Promise: 5',
'Await: 3',
'Promise: 4',
'Promise: 3',
'Await: 2',
'Promise: 2',
'Promise: 1',
'Await: 1',
'Promise: 0'
];
const iterations = 3;
async function* naturalNumbers(start) {
let current = start;
while (current > 0) {
yield Promise.resolve(current--);
}
}
async function trigger() {
for await (const num of naturalNumbers(iterations)) {
actual.push('Await: ' + num);
}
}
async function checkAssertions() {
assertArrayEquals(expected, actual,
'Async/await and promises should be interleaved when yielding.');
}
async function countdown(counter) {
actual.push('Promise: ' + counter);
if (counter > 0) {
return Promise.resolve(counter - 1).then(countdown);
} else {
await checkAssertions();
}
}
assertPromiseResult((async() => {
trigger();
return countdown(iterations * 2);
})());
})();

View File

@ -0,0 +1,41 @@
// Copyright 2024 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: --js-staging
let values = [];
(async () => {
for (let i = 0; i < 10; ++i) {
values.push(i);
await 0;
}
})();
async function TestCountTicks() {
let stack = new AsyncDisposableStack();
const firstDisposable = {
value: 1,
[Symbol.asyncDispose]() {
values.push(42);
}
};
const secondDisposable = {
value: 2,
[Symbol.asyncDispose]() {
values.push(43);
}
};
stack.use(firstDisposable);
stack.use(secondDisposable);
await stack.disposeAsync();
values.push(44);
}
async function RunTest() {
await TestCountTicks();
assertSame('0,43,1,42,2,3,44,4', values.join(','));
}
RunTest();

View File

@ -0,0 +1,34 @@
// Copyright 2024 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: --js-staging
let values = [];
(async () => {
for (let i = 0; i < 10; ++i) {
values.push(i);
await 0;
}
})();
async function TestCountTicks() {
values.push(42);
let stack = new AsyncDisposableStack();
stack.use(null);
stack.use(undefined);
stack.use(null);
stack.use(undefined);
stack.use(null);
stack.use(undefined);
await stack.disposeAsync();
values.push(43);
}
async function RunTest() {
await TestCountTicks();
assertSame('0,42,1,2,43,3', values.join(','));
}
RunTest();

View File

@ -0,0 +1,20 @@
// Copyright 2017 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.
var done = false;
async function f() {
try {
for await ([a] of {}) {
UNREACHABLE();
}
UNREACHABLE();
} catch (e) {
assertEquals(e.message, "{} is not async iterable");
done = true;
}
}
f();
assertTrue(done);

View File

@ -0,0 +1,33 @@
// 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: --allow-natives-syntax
const actual = [];
function createIterator() {
return {
[Symbol.iterator]() { return this; },
next() {
return { value: Promise.resolve(1), done: true};
}
};
}
actual.push("start");
iter = %CreateAsyncFromSyncIterator(createIterator());
Promise.resolve(0)
.then(() => actual.push("tick 1"))
.then(() => actual.push("tick 2"))
.then(() => actual.push("tick 3"))
.then(() => actual.push("tick 4"))
.then(() => actual.push("tick 5"));
let p = iter.next();
p.then(_ => { actual.push("done"); } );
%PerformMicrotaskCheckpoint();
assertSame("start,tick 1,tick 2,done,tick 3,tick 4,tick 5", actual.join(","))

View File

@ -0,0 +1,33 @@
// 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: --allow-natives-syntax
const actual = [];
function createIterator() {
return {
[Symbol.iterator]() { return this; },
return() {
return { value: Promise.resolve(1), done: true};
}
};
}
actual.push("start");
iter = %CreateAsyncFromSyncIterator(createIterator());
Promise.resolve(0)
.then(() => actual.push("tick 1"))
.then(() => actual.push("tick 2"))
.then(() => actual.push("tick 3"))
.then(() => actual.push("tick 4"))
.then(() => actual.push("tick 5"));
let p = iter.return();
p.then(_ => { actual.push("done"); } );
%PerformMicrotaskCheckpoint();
assertSame("start,tick 1,tick 2,done,tick 3,tick 4,tick 5", actual.join(","))

View File

@ -0,0 +1,33 @@
// 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: --allow-natives-syntax
const actual = [];
function createIterator() {
return {
[Symbol.iterator]() { return this; },
throw() {
return { value: Promise.resolve(1), done: true};
}
};
}
actual.push("start");
iter = %CreateAsyncFromSyncIterator(createIterator());
Promise.resolve(0)
.then(() => actual.push("tick 1"))
.then(() => actual.push("tick 2"))
.then(() => actual.push("tick 3"))
.then(() => actual.push("tick 4"))
.then(() => actual.push("tick 5"));
let p = iter.throw();
p.then(_ => { actual.push("done"); } );
%PerformMicrotaskCheckpoint();
assertSame("start,tick 1,tick 2,done,tick 3,tick 4,tick 5", actual.join(","))

View File

@ -0,0 +1,765 @@
// Copyright 2017 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: --allow-natives-syntax
let testFailed = false;
let testFailure;
function assertThrowsAsync(run, errorType, message) {
var actual;
var hadValue = false;
var hadError = false;
var promise = run();
if (typeof promise !== "object" || typeof promise.then !== "function") {
throw new MjsUnitAssertionError(
"Expected " + run.toString() +
" to return a Promise, but it returned " + PrettyPrint(promise));
}
promise.then(function(value) { hadValue = true; actual = value; },
function(error) { hadError = true; actual = error; });
assertFalse(hadValue || hadError);
%PerformMicrotaskCheckpoint();
if (!hadError) {
throw new MjsUnitAssertionError(
"Expected " + run + "() to throw " + errorType.name +
", but did not throw.");
}
if (!(actual instanceof errorType))
throw new MjsUnitAssertionError(
"Expected " + run + "() to throw " + errorType.name +
", but threw '" + actual + "'");
if (message !== void 0 && actual.message !== message)
throw new MjsUnitAssertionError(
"Expected " + run + "() to throw '" + message + "', but threw '" +
actual.message + "'");
};
function resolveLater(value) {
return new Promise(function(resolve) {
Promise.resolve().then(function() {
resolve(value);
});
});
}
function rejectLater(value) {
return new Promise(function(resolve, reject) {
Promise.resolve().then(function() {
reject(value);
});
});
}
const kNext = 1;
const kThrow = 2;
const kReturn = 4;
const kNextThrows = kNext | 8;
const kReturnThrows = kReturn | 16;
const kThrowNormal = kThrow | 32;
const kNextUnchanged = kNext | 64;
const kReturnUnchanged = kReturn | 128;
const kThrowUnchanged = kThrow | 256;
function sync(array, features, log) {
// `log` is a required parameter
if (log === void 0) %AbortJS("`log` is undefined");
let i = 0;
let methods = {
next(sent) {
let done = i >= array.length;
let value = array[i];
log.push({ method: "next", sent, value, done });
if ((features & kNextThrows) === kNextThrows) throw sent;
if ((features & kNextUnchanged) === kNextUnchanged) return sent;
i++;
return { value, done };
},
throw(sent) {
let done = i >= array.length;
log.push({ method: "throw", sent, done });
if ((features & kThrowNormal) === kThrowNormal)
return { value: sent, done };
if ((features & kThrowUnchanged) === kThrowUnchanged) return sent;
throw sent;
},
return(sent) {
let done = true;
log.push({ method: "return", sent, done });
if ((features & kReturnThrows) === kReturnThrows) throw sent;
if ((features & kReturnUnchanged) === kReturnUnchanged) return sent;
return { value: sent, done };
}
};
return {
[Symbol.iterator]() { return this; },
next: (features & kNext) ? methods.next : undefined,
throw: (features & kThrow) ? methods.throw : undefined,
return: (features & kReturn) ? methods.return : undefined
};
}
class MyError extends Error {};
(async function AsyncFromSyncWithGenerator() {
function* gen() {
yield "sync value";
try {
yield new Promise(function(resolve) {
resolve("async value");
});
} catch (error) {
throw error;
}
assertUnreachable("generator is closed");
}
let iter = %CreateAsyncFromSyncIterator(gen());
// [Async-from-Sync Iterator] wraps sync iterator values in a Promise
let promise = iter.next();
assertInstanceof(promise, Promise);
let iter_result = await promise;
assertEquals({ value: "sync value", done: false }, iter_result);
// [Async-from-Sync Iterator] will wait for resolution of Promise values
promise = iter.next();
assertInstanceof(promise, Promise);
iter_result = await promise;
assertEquals({ value: "async value", done: false }, iter_result);
// [Async-from-Sync Iterator].throw delegates to .throw() method of sync
// iterator.
promise = iter.throw(new MyError("Error#1"));
assertInstanceof(promise, Promise);
try {
await promise;
assertUnreachable("promise should be rejected");
} catch (e) {
// If assertUnreachable failed, rethrow
if (e instanceof MjsUnitAssertionError) throw e;
assertInstanceof(e, MyError);
assertEquals("Error#1", e.message);
}
// Generator is closed, subsequent calls to .next() will not resume.
promise = iter.next("floof");
iter_result = await promise;
assertEquals({ value: undefined, done: true }, iter_result);
promise = iter.return("generator closed");
assertInstanceof(promise, Promise);
iter_result = await promise;
assertEquals({ value: "generator closed", done: true }, iter_result);
// .next(), .return() and .throw() delegate to sync iterator methods, without
// keeping track of the state of the generator.
promise = iter.next("unused");
assertInstanceof(promise, Promise);
iter_result = await promise;
assertEquals({ value: undefined, done: true }, iter_result);
promise = iter.throw(new MyError("Error#2"));
assertInstanceof(promise, Promise);
try {
await promise;
assertUnreachable("promise should be rejected");
} catch (e) {
// If assertUnreachable failed, rethrow
if (e instanceof MjsUnitAssertionError) throw e;
assertInstanceof(e, MyError);
assertEquals("Error#2", e.message);
}
promise = iter.return("return-after-completed");
assertInstanceof(promise, Promise);
iter_result = await promise;
assertEquals({ value: "return-after-completed", done: true }, iter_result);
})().catch(function(error) {
testFailed = true;
testFailure = error;
});
%PerformMicrotaskCheckpoint();
if (testFailed) {
throw testFailure;
}
(async function AsyncFromSyncOrderOfOperations() {
let log = [];
iter = %CreateAsyncFromSyncIterator(sync(["sync-value"], 0, log));
try {
await iter.next();
assertUnreachable("Iterator.next() method is not optional");
} catch (e) {
assertInstanceof(e, TypeError);
assertEquals([], log);
}
log = [];
iter = %CreateAsyncFromSyncIterator(sync(["sync-value"], kNext, log));
assertEquals({ value: "sync-value", done: false }, await iter.next("a"));
assertEquals([
{
method: "next",
sent: "a",
value: "sync-value",
done: false
}
], log);
log = [];
let asyncValue = resolveLater("async-value");
iter = %CreateAsyncFromSyncIterator(sync([asyncValue], kNext, log));
assertEquals({ value: "async-value", done: false }, await iter.next("b"));
assertEquals([
{
method: "next",
sent: "b",
value: asyncValue,
done: false
}
], log);
// If [sync_iterator].next() produces a rejected Promise or an exception is
// thrown, Promise is rejected with thrown/rejected value.
log = [];
asyncValue = rejectLater("Boo!");
iter = %CreateAsyncFromSyncIterator(sync([asyncValue], kNext, log));
try {
await iter.next('c');
assertUnreachable('Expected `iter.next(\'c\') to throw, but did not throw');
} catch (e) {
assertEquals("Boo!", e);
assertEquals([
{
method: 'next',
sent: 'c',
value: asyncValue,
done: false
}
], log);
}
log = [];
iter = %CreateAsyncFromSyncIterator(sync(['sync-value'], kNextThrows, log));
try {
await iter.next('Boo!');
assertUnreachable('Expected `iter.next(\'c\') to throw, but did not throw');
} catch (e) {
assertEquals("Boo!", e);
assertEquals([
{
method: 'next',
sent: 'Boo!',
value: 'sync-value',
done: false
}
], log);
}
// [Async-from-Sync Iterator].next() will be rejected with a TypeError if
// Type([sync_iterator].next()) is not Object.
log = [];
iter = %CreateAsyncFromSyncIterator(sync(['sync-value'], kNextUnchanged,
log));
try {
await iter.next('not-a-JSReceiver');
assertUnreachable('Expected `iter.next(\'not-a-JSReceiver\')` to ' +
'throw, but did not throw')
} catch (e) {
assertEquals(e.constructor, TypeError);
}
assertEquals([
{
method: 'next',
sent: 'not-a-JSReceiver',
value: 'sync-value',
done: false
}
], log);
// If [sync_iterator] does not have a .return() method, return a Promise
// resolved with the value `{ value: <<sent value>>, done: true }`.
log = [];
iter = %CreateAsyncFromSyncIterator(sync(['sync-return'], kNext, log));
assertEquals({
value: 'd',
done: true
}, await iter.return('d'));
// [Async-from-Sync Iterator] merely delegates, and does not keep track of
// whether [sync_iterator] is completed or not.
assertEquals({
value: 'sync-return',
done: false
}, await iter.next('e'));
assertEquals([
{
method: 'next',
sent: 'e',
value: 'sync-return',
done: false
}
], log);
// If [sync_iterator] does have a .return() method, return a Promise
// fulfilled with the iterator result of [sync_iterator].return().
log = [];
iter = %CreateAsyncFromSyncIterator(sync(['sync-return'],
kNext|kReturn, log));
assertEquals({
value: 'f',
done: true
}, await iter.return('f'));
// [Async-from-Sync Iterator] merely delegates, and does not keep track of
// whether [sync_iterator] is completed or not.
assertEquals({
value: 'sync-return',
done: false
}, await iter.next('g'));
assertEquals([
{
method: 'return',
sent: 'f',
done: true
},
{
method: 'next',
sent: 'g',
value: 'sync-return',
done: false
}
], log);
// If [sync_iterator].return() produces a rejected Promise or an exception is
// thrown, Promise is rejected with thrown/rejected value.
log = [];
iter = %CreateAsyncFromSyncIterator(sync(['sync-value'], kNext|kReturnThrows,
log));
try {
await iter.return('Boo!!');
assertUnreachable('Expected `iter.return(\'Boo!!\')` to throw, but did ' +
'not throw');
} catch (e) {
assertEquals("Boo!!", e);
}
// [Async-from-Sync Iterator] merely delegates, and does not keep track of
// whether [sync_iterator] is completed or not.
assertEquals({ value: 'sync-value', done: false }, await iter.next('h'));
assertEquals([
{
method: 'return',
sent: 'Boo!!',
done: true
},
{
method: 'next',
sent: 'h',
value: 'sync-value',
done: false
}
], log);
log = [];
iter = %CreateAsyncFromSyncIterator(sync(['sync-value'], kNext|kReturn, log));
let rejection = Promise.reject('Boo!!');
try {
await iter.return(rejection);
assertUnreachable('Expected `iter.return(Promise.reject(\'Boo!!\'))` to ' +
'throw, but did not throw');
} catch (e) {
assertEquals('Boo!!', e);
}
// [Async-from-Sync Iterator] merely delegates, and does not keep track of
// whether [sync_iterator] is completed or not.
assertEquals({ value: 'sync-value', done: false }, await iter.next('i'));
assertEquals([
{
method: 'return',
sent: rejection,
done: true
},
{
method: 'next',
sent: 'i',
value: 'sync-value',
done: false
}
], log);
// [Async-from-Sync Iterator].return() will be rejected with a TypeError if
// Type([sync_iterator].return()) is not Object.
log = [];
iter = %CreateAsyncFromSyncIterator(sync(['sync-value'],
kNext|kReturnUnchanged, log));
try {
await iter.return('not-a-JSReceiver');
assertUnreachable('Expected `iter.return(\'not-a-JSReceiver\')` to ' +
'throw, but did not throw')
} catch (e) {
assertEquals(e.constructor, TypeError);
}
// [Async-from-Sync Iterator] merely delegates, and does not keep track of
// whether [sync_iterator] is completed or not.
assertEquals({ value: 'sync-value', done: false }, await iter.next('j'));
assertEquals([
{
method: 'return',
sent: 'not-a-JSReceiver',
done: true
},
{
method: 'next',
sent: 'j',
value: 'sync-value',
done: false
}
], log);
// If [sync_iterator] does not have a .throw method, return a Promise rejected
// with the a TypeError signaling the protocol error of missing the .throw.
log = [];
iter = %CreateAsyncFromSyncIterator(sync(['sync-value'], kNext, log));
try {
await iter.throw('Boo!!');
assertUnreachable('Expected iter.throw(\'Boo!!\') to throw, but did not ' +
'throw');
} catch (e) {
assertTrue(e instanceof TypeError);
}
// [Async-from-Sync Iterator] merely delegates, and does not keep track of
// whether [sync_iterator] is completed or not.
assertEquals({ value: 'sync-value', done: false }, await iter.next('k'));
assertEquals([
{
method: 'next',
sent: 'k',
value: 'sync-value',
done: false
}
], log);
log = [];
iter = %CreateAsyncFromSyncIterator(sync(['sync-value'], kNext|kThrow, log));
try {
await iter.throw('Boo!!');
assertUnreachable('Expected iter.throw(\'Boo!!\') to throw, but did not ' +
'throw');
} catch (e) {
assertEquals('Boo!!', e);
}
// [Async-from-Sync Iterator] merely delegates, and does not keep track of
// whether [sync_iterator] is completed or not.
assertEquals({ value: 'sync-value', done: false }, await iter.next('l'));
assertEquals([
{
method: 'throw',
sent: 'Boo!!',
done: false
},
{
method: 'next',
sent: 'l',
value: 'sync-value',
done: false
}
], log);
// If [sync_iterator].throw() returns a resolved Promise or a Completion
// with [[Type]] "normal" or "return", return a resolved Promise
log = [];
iter = %CreateAsyncFromSyncIterator(sync(['sync-value'], kNext|kThrowNormal,
log));
assertEquals({
value: 'Boo!!',
done: false
}, await iter.throw('Boo!!'));
// [Async-from-Sync Iterator] merely delegates, and does not keep track of
// whether [sync_iterator] is completed or not.
assertEquals({ value: 'sync-value', done: false }, await iter.next('m'));
assertEquals([
{
method: 'throw',
sent: 'Boo!!',
done: false
},
{
method: 'next',
sent: 'm',
value: 'sync-value',
done: false
}
], log);
// [Async-from-Sync Iterator].throw() will be rejected with a TypeError if
// Type([sync_iterator].throw()) is not Object.
log = [];
iter = %CreateAsyncFromSyncIterator(sync(['sync-value'],
kNext|kThrowUnchanged, log));
try {
await iter.throw('not-a-JSReceiver');
assertUnreachable('Expected `iter.throw(\'not-a-JSReceiver\')` to ' +
'throw, but did not throw')
} catch (e) {
assertEquals(e.constructor, TypeError);
}
// [Async-from-Sync Iterator] merely delegates, and does not keep track of
// whether [sync_iterator] is completed or not.
assertEquals({ value: 'sync-value', done: false }, await iter.next('n'));
assertEquals([
{
method: 'throw',
sent: 'not-a-JSReceiver',
done: false
},
{
method: 'next',
sent: 'n',
value: 'sync-value',
done: false
}
], log);
// Let nextValue be IteratorValue(nextResult).
// IfAbruptRejectPromise(nextValue, promiseCapability).)
iter = %CreateAsyncFromSyncIterator({
next() { return { get value() { throw "BadValue!" }, done: false }; }
});
try {
await iter.next();
assertUnreachable('Expected `iter.next()` to throw, but did not throw');
} catch (e) {
assertEquals('BadValue!', e);
}
// Let nextDone be IteratorComplete(nextResult).
// IfAbruptRejectPromise(nextDone, promiseCapability).
iter = %CreateAsyncFromSyncIterator({
next() { return { value: undefined, get done() { throw "BadValue!" } }; }
});
try {
await iter.next();
assertUnreachable('Expected `iter.next()` to throw, but did not throw');
} catch (e) {
assertEquals('BadValue!', e);
}
// IfAbruptRejectPromise(returnResult, promiseCapability).
// Let returnValue be IteratorValue(returnResult).
iter = %CreateAsyncFromSyncIterator({
return() { return { get value() { throw "BadValue!" }, done: false }; }
});
try {
await iter.return();
assertUnreachable('Expected `iter.return()` to throw, but did not throw');
} catch (e) {
assertEquals('BadValue!', e);
}
// IfAbruptRejectPromise(returnValue, promiseCapability).
// Let returnDone be IteratorComplete(returnResult).
iter = %CreateAsyncFromSyncIterator({
return() { return { value: undefined, get done() { throw "BadValue!" } }; }
});
try {
await iter.return();
assertUnreachable('Expected `iter.return()` to throw, but did not throw');
} catch (e) {
assertEquals('BadValue!', e);
}
// IfAbruptRejectPromise(throwResult, promiseCapability).
// Let throwValue be IteratorValue(throwResult).
iter = %CreateAsyncFromSyncIterator({
throw() { return { get value() { throw "BadValue!" }, done: false }; }
});
try {
await iter.throw();
assertUnreachable('Expected `iter.throw()` to throw, but did not throw');
} catch (e) {
assertEquals('BadValue!', e);
}
// IfAbruptRejectPromise(throwValue, promiseCapability).
// Let throwDone be IteratorComplete(throwResult).
iter = %CreateAsyncFromSyncIterator({
throw() { return { value: undefined, get done() { throw "BadValue!" } }; }
});
try {
await iter.throw();
assertUnreachable('Expected `iter.throw()` to throw, but did not throw');
} catch (e) {
assertEquals('BadValue!', e);
}
})().catch(function(error) {
testFailed = true;
testFailure = error;
});
%PerformMicrotaskCheckpoint();
if (testFailed) {
throw testFailure;
}
(function ExtractedAsyncFromSyncIteratorMethods() {
// TODO(ishell, caitp): Rewrite the test without using function.caller.
// According to ES#sec-built-in-function-objects all built-in functions
// must be strict. And ES#sec-forbidden-extensions states that the value of
// a function.caller must not be a strict function.
return;
// Async-from-Sync iterator methods can be extracted via function.caller.
// TODO(caitp): test extracted `throw` method using yield* in async generator.
let extractor = [0, 1, 2, 3, 4,5,6,7,8,9];
let extractedNext;
let extractedReturn;
extractor[Symbol.iterator] = function() {
let it = [][Symbol.iterator].call(extractor);
let origNext = it.next, origThrow = it.throw, origReturn = it.return;
function extractNext() {
extractedNext = extractNext.caller;
return origNext;
}
function extractReturn() {
extractedReturn = extractReturn.caller;
return origReturn;
}
Object.defineProperties(it, {
"next": { get: extractNext, configurable: true },
"return": { get: extractReturn, configurable: true }
});
return it;
};
async function f() {
let i;
let it = extractor[Symbol.iterator]();
for await (let x of it) break;
for await (let x of it) return "x";
}
// Cycle through `f` to extract iterator methods
f().catch(function() { %AbortJS("No error should have occurred"); });
%PerformMicrotaskCheckpoint();
assertEquals(typeof extractedNext, "function");
assertThrowsAsync(() => extractedNext.call(undefined), TypeError);
assertThrowsAsync(() => extractedNext.call(1), TypeError);
assertEquals(typeof extractedReturn, "function");
assertThrowsAsync(() => extractedReturn.call(undefined), TypeError);
assertThrowsAsync(() => extractedReturn.call(1), TypeError);
})();
(function AsyncFromSyncIteratorOrdering() {
let i = 0;
let log = [];
function r(value, done) {
let number = (++i);
return {
get value() {
log.push("get iterResult #" + number + ".value");
return {
get then() {
log.push("get nextValue#" + number + ".then");
return (r) => {
log.push("call nextValue#" + number + ".then");
r(value);
}
}
};
},
get done() {
log.push("get iterResult #" + number + ".done");
return done;
}
};
}
var results = [r("value1", false), r("value2", false), r("value3", true),
r("value4", false)];
var iter = {
get [Symbol.asyncIterator]() {
log.push("get syncIterable[@@asyncIterator]");
return null;
},
get [Symbol.iterator]() {
log.push("get syncIterable[@@iterator]");
return (...args) => {
log.push("call syncIterable[@@iterator](" + args.join(", ") + ")");
return this;
}
},
next_: 0,
get next() {
log.push("get syncIterable.next");
return (...args) => {
let i = this.next_++;
log.push("call syncIterable.next(" + args.join(", ") + ")");
return results[i];
}
}
};
async function iterate(iterable) {
log.push("before");
for await (let x of iterable) {
log.push("got value " + x);
}
log.push("after");
return log;
}
iterate(iter).then(log => {
assertEquals([
"before",
"get syncIterable[@@asyncIterator]",
"get syncIterable[@@iterator]",
"call syncIterable[@@iterator]()",
"get syncIterable.next",
"call syncIterable.next()",
"get iterResult #1.done",
"get iterResult #1.value",
"get nextValue#1.then",
"call nextValue#1.then",
"got value value1",
"call syncIterable.next()",
"get iterResult #2.done",
"get iterResult #2.value",
"get nextValue#2.then",
"call nextValue#2.then",
"got value value2",
"call syncIterable.next()",
"get iterResult #3.done",
"get iterResult #3.value",
"get nextValue#3.then",
"call nextValue#3.then",
"after"
], log)
}).catch(x => %AbortJS(String(x)));
})();

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,152 @@
// Copyright 2017 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: --allow-natives-syntax
d8.file.execute('test/mjsunit/test-async.js');
// .return() from state suspendedStart with undefined
testAsync(test => {
test.plan(3);
async function* gen() {
test.unreachable();
}
let didResolvePromise = false;
let g = gen();
g.return(undefined).then(
(iterResult) => {
test.equals(true, didResolvePromise);
test.equals({ value: undefined, done: true }, iterResult);
},
test.unexpectedRejection());
g.next().then(
(iterResult) => {
test.equals({ value: undefined, done: true }, iterResult);
},
test.unexpectedRejection());
// Race: generator request's promise should resolve after this Promise.
Promise.resolve("already-resolved").then(
_ => { didResolvePromise = true },
test.unexpectedRejection());
}, "AsyncGenerator.return(undefined) / suspendStart");
// .return() from state suspendedStart with thenable
testAsync(test => {
test.plan(3);
async function* gen() {
test.unreachable();
}
let didResolvePromise = false;
let g = gen();
let resolve;
let awaitedThenable = { then(resolveFn) { resolve = resolveFn; } };
g.return(awaitedThenable).then(
(iterResult) => {
test.equals(true, didResolvePromise);
test.equals({ value: "resolvedPromise", done: true }, iterResult);
},
test.unexpectedRejection());
g.next().then(
(iterResult) => {
test.equals({ value: undefined, done: true }, iterResult);
},
test.unexpectedRejection());
test.drainMicrotasks();
resolve("resolvedPromise");
// Race: generator request's promise should resolve after this Promise.
Promise.resolve("already-resolved").then(
_ => { didResolvePromise = true },
test.unexpectedRejection());
}, "AsyncGenerator.return(thenable) / suspendStart");
// .return() from state suspendedYield with undefined
testAsync(test => {
test.plan(4);
async function* gen() {
yield;
test.unreachable();
}
let didResolvePromise = false;
let g = gen();
g.next().then(
(iterResult) => {
test.equals({ value: undefined, done: false }, iterResult);
},
test.unexpectedRejection());
g.return(undefined).then(
(iterResult) => {
test.equals(true, didResolvePromise);
test.equals({ value: undefined, done: true }, iterResult);
},
test.unexpectedRejection());
g.next().then(
(iterResult) => {
test.equals({ value: undefined, done: true }, iterResult);
},
test.unexpectedRejection());
// Race: generator request's promise should resolve after this Promise.
Promise.resolve("already-resolved").then(
_ => { didResolvePromise = true },
test.unexpectedRejection());
}, "AsyncGenerator.return(undefined) / suspendedYield");
// .return() from state suspendedYield with thenable
testAsync(test => {
test.plan(4);
async function* gen() {
yield;
test.unreachable();
}
let didResolvePromise = false;
let g = gen();
let resolve;
let awaitedThenable = { then(resolveFn) { resolve = resolveFn; } };
g.next().then(
(iterResult) => {
test.equals({ value: undefined, done: false }, iterResult);
},
test.unexpectedRejection());
g.return(awaitedThenable).then(
(iterResult) => {
test.equals(true, didResolvePromise);
test.equals({ value: "resolvedPromise", done: true }, iterResult);
},
test.unexpectedRejection());
g.next().then(
(iterResult) => {
test.equals({ value: undefined, done: true }, iterResult);
},
test.unexpectedRejection());
test.drainMicrotasks();
resolve("resolvedPromise");
// Race: generator request's promise should resolve after this Promise.
Promise.resolve("already-resolved").then(
_ => { didResolvePromise = true },
test.unexpectedRejection());
}, "AsyncGenerator.return(thenable) / suspendYield");

View File

@ -0,0 +1,82 @@
// Copyright 2022 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: --allow-natives-syntax
d8.file.execute('test/mjsunit/test-async.js');
function getBrokenPromise() {
let brokenPromise = Promise.resolve(42);
Object.defineProperty(brokenPromise, 'constructor', {
get: function () {
throw new Error('broken promise');
}
});
return brokenPromise;
}
testAsync(test => {
test.plan(1);
let gen = (async function* () { })();
gen.return(getBrokenPromise())
.then(
() => {
test.unreachable();
},
(err) => {
test.equals(err.message, 'broken promise');
}
);
}, "close suspendedStart async generator");
testAsync(test => {
test.plan(1);
let unblock;
let blocking = new Promise(res => { unblock = res; });
let gen = (async function* (){ await blocking; })();
gen.next();
gen.return(getBrokenPromise())
.then(
() => {
test.unreachable();
},
(err) => {
test.equals(err.message, 'broken promise');
}
);
unblock();
}, "close blocked suspendedStart async generator");
testAsync(test => {
test.plan(2);
let gen = (async function* (){
try {
yield 1;
} catch (err) {
test.equals(err.message, 'broken promise');
return 2;
}
})();
gen.next()
.then(() => {
try {
return gen.return(getBrokenPromise())
} catch {
test.unreachable();
}
})
.then(
val => {
test.equals(val, {done: true, value: 2});
},
test.unexpectedRejection()
);
}, "resume suspendedYield async generator with throw completion");

View File

@ -0,0 +1,122 @@
// Copyright 2017 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: --allow-natives-syntax
d8.file.execute('test/mjsunit/test-async.js');
testAsync(test => {
test.plan(2);
async function* gen() {
return;
test.unreachable();
}
let didResolvePromise = false;
gen().next().then(
(iterResult) => {
test.equals(false, didResolvePromise);
test.equals({ value: undefined, done: true }, iterResult);
},
test.unexpectedRejection());
// Race: generator request's promise should resolve before this Promise.
Promise.resolve("already-resolved").then(
_ => { didResolvePromise = true },
test.unexpectedRejection());
}, "return-race-no-operand");
testAsync(test => {
test.plan(2);
async function* gen() {
return undefined;
test.unreachable();
}
let didResolvePromise = false;
gen().next().then(
(iterResult) => {
test.equals(true, didResolvePromise);
test.equals({ value: undefined, done: true }, iterResult);
},
test.unexpectedRejection());
// Race: generator request's promise should resolve after this Promise.
Promise.resolve("already-resolved").then(
_ => { didResolvePromise = true },
test.unexpectedRejection());
}, "return-race-with-operand");
// Return a thenable which is never settled
testAsync(test => {
test.plan(0);
let promise = { then() { } };
async function* gen() {
return promise;
test.unreachable();
}
gen().next().then(
(iterResult) => test.unreachable(),
test.unexpectedRejection());
}, "return-await-thenable-pending");
// Return a thenable which is fulfilled later
testAsync(test => {
test.plan(3);
let resolve;
let awaitedThenable = { then(resolveFn) { resolve = resolveFn; } };
let finallyEvaluated = false;
async function* gen() {
try {
return awaitedThenable;
} finally {
finallyEvaluated = true;
}
}
gen().next().then(
(iterResult) => {
test.equals("resolvedPromise", iterResult.value);
test.equals(true, iterResult.done);
test.equals(true, finallyEvaluated);
},
test.unexpectedRejection());
test.drainMicrotasks();
resolve("resolvedPromise");
}, "yield-await-thenable-resolved");
// Return a thenable which is rejected later
testAsync(test => {
test.plan(2);
let reject;
let awaitedThenable = { then(resolveFn, rejectFn) { reject = rejectFn; } };
async function* gen() {
try {
yield awaitedThenable;
} catch (e) {
test.equals("rejection", e);
return e;
}
}
gen().next().then(
(iterResult) => {
test.equals({ value: "rejection", done: true }, iterResult);
},
test.unexpectedRejection());
test.drainMicrotasks();
reject("rejection");
}, "yield-await-thenable-rejected");

View File

@ -0,0 +1,24 @@
// Copyright 2020 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.
let caught_in_gen = false;
async function* catch_gen() {
try {
yield 42;
} catch (e) {
caught_in_gen = true;
}
}
(async () => {
const g = catch_gen();
await g.next();
try {
await g.throw(new Error()); // Should be caught in catch_gen, then catch_gen
// completes normally.
} catch (e) {
assertUnreachable();
}
assertTrue(caught_in_gen);
})();

View File

@ -0,0 +1,70 @@
// Copyright 2017 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: --allow-natives-syntax
d8.file.execute('test/mjsunit/test-async.js');
// Yield a thenable which is never settled
testAsync(test => {
test.plan(0);
let awaitedThenable = { then() { } };
async function* gen() {
yield awaitedThenable;
test.unreachable();
}
gen().next().then(
(iterResult) => test.unreachable(),
test.unexpectedRejection());
}, "yield-await-thenable-pending");
// Yield a thenable which is fulfilled later
testAsync(test => {
test.plan(1);
let resolve;
let awaitedThenable = { then(resolveFn) { resolve = resolveFn; } };
async function* gen() {
let input = yield awaitedThenable;
test.equals("resolvedPromise", input);
}
gen().next().then(
(iterResult) => {
test.equals({ value: "resolvedPromise", done: false }, iterResult);
},
test.unexpectedRejection());
test.drainMicrotasks();
resolve("resolvedPromise");
}, "yield-await-thenable-resolved");
// Yield a thenable which is rejected later
testAsync(test => {
test.plan(2);
let reject;
let awaitedThenable = { then(resolveFn, rejectFn) { reject = rejectFn; } };
async function* gen() {
try {
yield awaitedThenable;
} catch (e) {
test.equals("rejection", e);
return e;
}
}
gen().next().then(
(iterResult) => {
test.equals({ value: "rejection", done: true }, iterResult);
},
test.unexpectedRejection());
test.drainMicrotasks();
reject("rejection");
}, "yield-await-thenable-rejected");

View File

@ -0,0 +1,29 @@
// 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: --allow-natives-syntax
let actual = [];
async function f() {
var p = Promise.resolve(0);
Object.defineProperty(p, "constructor", {
get() {
throw new Error();
}
});
actual.push("start");
for await (var x of [p]);
actual.push("never reached");
}
Promise.resolve(0)
.then(() => actual.push("tick 1"))
.then(() => actual.push("tick 2"))
f().catch(() => actual.push("catch"));
%PerformMicrotaskCheckpoint();
assertSame(["start", "tick 1", "tick 2", "catch"].join(), actual.join());

View File

@ -0,0 +1,4 @@
// Copyright 2024 Nathan Whitaker. All rights reserved. MIT license.
import run from "./skip-run.mjs";
await run();

View File

@ -0,0 +1,7 @@
// Copyright 2024 Nathan Whitaker. All rights reserved. MIT license.
import common from "./skip-common.mjs";
export default () => {
common;
};

View File

@ -0,0 +1,5 @@
// Copyright 2024 Nathan Whitaker. All rights reserved. MIT license.
await Promise.resolve();
export default () => {};

View File

@ -0,0 +1,7 @@
// Copyright 2024 Nathan Whitaker. All rights reserved. MIT license.
import common from "./skip-common.mjs";
export default () => {
common;
};

View File

@ -0,0 +1,7 @@
// Copyright 2024 Nathan Whitaker. All rights reserved. MIT license.
import common from "./skip-common.mjs";
export default () => {
common;
};

View File

@ -0,0 +1,7 @@
// Copyright 2024 Nathan Whitaker. All rights reserved. MIT license.
// make sure it takes >1 tick to evaluate the module
await import("./dummy").catch(() => {});
await import("./dummy").catch(() => {});
export default () => {};

View File

@ -0,0 +1,7 @@
// Copyright 2024 Nathan Whitaker. All rights reserved. MIT license.
import common from "./skip-common.mjs";
export default () => {
common;
};

View File

@ -0,0 +1,7 @@
// Copyright 2024 Nathan Whitaker. All rights reserved. MIT license.
import common from "./skip-common.mjs";
export default () => {
common;
};

View File

@ -0,0 +1,7 @@
// Copyright 2024 Nathan Whitaker. All rights reserved. MIT license.
import common from "./skip-common.mjs";
export default () => {
common;
};

View File

@ -0,0 +1,4 @@
// Copyright 2024 Nathan Whitaker. All rights reserved. MIT license.
import * as m from "./skip-async-module.mjs";
m;

View File

@ -0,0 +1,25 @@
// Copyright 2024 Nathan Whitaker. All rights reserved. MIT license.
export default async () => {
// depends on `skip-common.mjs` which contains a TLA
const a = import("./skip-a.mjs");
// this resolves, resetting the async ordinal counter
await import("./skip-imports-async-module.mjs");
// start evaluating more modules that depend on `skip-common.mjs`.
// one of these will receive a duplicate ordinal to
// `skip-a.mjs`
await Promise.all([
a,
import("./skip-b.mjs"),
import("./skip-c.mjs"),
import("./skip-d.mjs"),
import("./skip-e.mjs"),
import("./skip-f.mjs"),
]);
// when `common.mjs` settles, we go to update the state
// of the modules waiting on it. Due to the duplicate
// ordinal, one of the modules will be skipped and
// be stuck pending forever.
};

View File

@ -0,0 +1,99 @@
// Copyright 2020 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: --allow-natives-syntax
// Test for the buffer becoming detached in surprising places. Test262 covers
// the case where the buffer starts off detached.
function makePoison(arr, val) {
return { valueOf() { %ArrayBufferDetach(arr.buffer); return val; } };
}
function forEachIntegerTypedArray(cb) {
for (let C of [Int8Array, Uint8Array, Uint8ClampedArray,
Int16Array, Uint16Array,
Int32Array, Uint32Array,
BigInt64Array, BigUint64Array]) {
let arr = new C(32);
let zero, valuePoison;
if (C === BigInt64Array || C === BigUint64Array) {
zero = 0n;
valuePoison = makePoison(arr, 0n);
} else {
zero = 0;
valuePoison = makePoison(arr, 0);
}
cb(arr, makePoison(arr, 0), valuePoison, zero);
}
}
forEachIntegerTypedArray((arr, indexPoison, valuePoison, zero) => {
assertThrows(() => Atomics.add(arr, indexPoison, zero), TypeError);
});
forEachIntegerTypedArray((arr, indexPoison, valuePoison, zero) => {
assertThrows(() => Atomics.add(arr, 0, valuePoison), TypeError);
});
forEachIntegerTypedArray((arr, indexPoison, valuePoison, zero) => {
assertThrows(() => Atomics.and(arr, indexPoison, zero), TypeError);
});
forEachIntegerTypedArray((arr, indexPoison, valuePoison, zero) => {
assertThrows(() => Atomics.and(arr, 0, valuePoison), TypeError);
});
forEachIntegerTypedArray((arr, indexPoison, valuePoison, zero) => {
assertThrows(() => Atomics.compareExchange(arr, indexPoison, zero, zero),
TypeError);
});
forEachIntegerTypedArray((arr, indexPoison, valuePoison, zero) => {
assertThrows(() => Atomics.compareExchange(arr, 0, valuePoison, zero),
TypeError);
});
forEachIntegerTypedArray((arr, indexPoison, valuePoison, zero) => {
assertThrows(() => Atomics.compareExchange(arr, 0, zero, valuePoison),
TypeError);
});
forEachIntegerTypedArray((arr, indexPoison, valuePoison, zero) => {
assertThrows(() => Atomics.exchange(arr, indexPoison, zero), TypeError);
});
forEachIntegerTypedArray((arr, indexPoison, valuePoison, zero) => {
assertThrows(() => Atomics.exchange(arr, 0, valuePoison), TypeError);
});
forEachIntegerTypedArray((arr, indexPoison, valuePoison, zero) => {
assertThrows(() => Atomics.load(arr, indexPoison), TypeError);
});
forEachIntegerTypedArray((arr, indexPoison, valuePoison, zero) => {
assertThrows(() => Atomics.or(arr, indexPoison, zero), TypeError);
});
forEachIntegerTypedArray((arr, indexPoison, valuePoison, zero) => {
assertThrows(() => Atomics.or(arr, 0, valuePoison), TypeError);
});
forEachIntegerTypedArray((arr, indexPoison, valuePoison, zero) => {
assertThrows(() => Atomics.store(arr, indexPoison, 0n), TypeError);
});
forEachIntegerTypedArray((arr, indexPoison, valuePoison, zero) => {
assertThrows(() => Atomics.store(arr, 0, valuePoison), TypeError);
});
forEachIntegerTypedArray((arr, indexPoison, valuePoison, zero) => {
assertThrows(() => Atomics.sub(arr, indexPoison, zero), TypeError);
});
forEachIntegerTypedArray((arr, indexPoison, valuePoison, zero) => {
assertThrows(() => Atomics.sub(arr, 0, valuePoison), TypeError);
});
forEachIntegerTypedArray((arr, indexPoison, valuePoison, zero) => {
assertThrows(() => Atomics.xor(arr, indexPoison, zero), TypeError);
});
forEachIntegerTypedArray((arr, indexPoison, valuePoison, zero) => {
assertThrows(() => Atomics.xor(arr, 0, valuePoison), TypeError);
});
// Atomics.wait always throws on non-SABs.
// Atomics.notify always returns 0 on non-SABs.

View File

@ -0,0 +1,42 @@
// Copyright 2017 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.
var sab = new SharedArrayBuffer(4);
var sta = new Int8Array(sab);
sta[0] = 5;
function workerCode() {
onmessage = function({data:msg}) {
postMessage(0);
};
}
var worker = new Worker(workerCode, {type: 'function'});
var value_obj = {
valueOf: function() {worker.postMessage({sab:sab}, [sta.buffer]);
return 5}
}
var value = Object.create(value_obj);
assertThrows(function() {Atomics.exchange(sta, 0, value)});
assertThrows(function() {Atomics.compareExchange(sta, 0, 5, value)});
assertThrows(function() {Atomics.compareExchange(sta, 0, value, 5)});
assertThrows(function() {Atomics.add(sta, 0, value)});
assertThrows(function() {Atomics.sub(sta, 0, value)});
assertThrows(function() {Atomics.and(sta, 0, value)});
assertThrows(function() {Atomics.or(sta, 0, value)});
assertThrows(function() {Atomics.xor(sta, 0, value)});
var index_obj = {
valueOf: function() {worker.postMessage({sab:sab}, [sta.buffer]);
return 0}
}
var index = Object.create(index_obj);
assertThrows(function() {Atomics.exchange(sta, index, 1)});
assertThrows(function() {Atomics.compareExchange(sta, index, 5, 2)});
assertThrows(function() {Atomics.add(sta, index, 3)});
assertThrows(function() {Atomics.sub(sta, index, 4)});
assertThrows(function() {Atomics.and(sta, index, 5)});
assertThrows(function() {Atomics.or(sta, index, 6)});
assertThrows(function() {Atomics.xor(sta, index, 7)});

View File

@ -0,0 +1,38 @@
// Copyright 2020 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.
d8.file.execute("test/mjsunit/harmony/atomics-waitasync-helpers.js");
function workerCode() {
const sab = new SharedArrayBuffer(16);
const i32a = new Int32Array(sab);
onmessage = function() {
// Create a waiter with a long timeout.
const result_slow = Atomics.waitAsync(i32a, 0, 0, 200000);
// Create a waiter with a short timeout.
const result_fast = Atomics.waitAsync(i32a, 0, 0, 1);
result_slow.value.then(
(value) => { postMessage("slow " + value); },
() => { postMessage("unexpected"); });
result_fast.value.then(
(value) => {
postMessage("fast " + value);
// Wake up the waiter with the long time out.
const notify_return_value = Atomics.notify(i32a, 0, 1);
postMessage("notify return value " + notify_return_value);
},
() => { postMessage("unexpected"); });
};
}
const expected_messages = [
"fast timed-out",
"notify return value 1",
"slow ok"
];
runTestWithWorker(workerCode, expected_messages);

View File

@ -0,0 +1,43 @@
// Copyright 2020 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: --expose-gc
d8.file.execute("test/mjsunit/harmony/atomics-waitasync-helpers.js");
function workerCode() {
onmessage = function() {
(function() {
const sab = new SharedArrayBuffer(16);
const i32a = new Int32Array(sab);
// Create a waiter with a timeout.
const result = Atomics.waitAsync(i32a, 0, 0, 1);
result.value.then(
(value) => { postMessage("result " + value); },
() => { postMessage("unexpected"); });
})();
// Make sure sab, ia32 and result get gc()d.
gc();
// Even if the buffer went out of scope, we keep the waitAsync alive so that it can still time out.
let resolved = false;
const sab2 = new SharedArrayBuffer(16);
const i32a2 = new Int32Array(sab2);
const result2 = Atomics.waitAsync(i32a2, 0, 0);
result2.value.then(
(value) => { postMessage("result2 " + value); },
() => { postMessage("unexpected"); });
const notify_return_value = Atomics.notify(i32a2, 0);
postMessage("notify return value " + notify_return_value);
};
}
const expected_messages = [
"notify return value 1",
"result2 ok",
"result timed-out"
];
runTestWithWorker(workerCode, expected_messages);

View File

@ -0,0 +1,30 @@
// Copyright 2020 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: --allow-natives-syntax --expose-gc
(function test() {
const sab = new SharedArrayBuffer(16);
const i32a = new Int32Array(sab);
let resolved = false;
(function() {
const result = Atomics.waitAsync(i32a, 0, 0);
result.value.then(
(value) => { assertEquals("ok", value); resolved = true; },
() => { assertUnreachable(); });
})();
// Make sure result gets gc()d.
gc();
const notify_return_value = Atomics.notify(i32a, 0, 1);
assertEquals(1, notify_return_value);
assertEquals(0, %AtomicsNumWaitersForTesting(i32a, 0));
assertEquals(1, %AtomicsNumUnresolvedAsyncPromisesForTesting(i32a, 0));
setTimeout(()=> {
assertTrue(resolved);
assertEquals(0, %AtomicsNumUnresolvedAsyncPromisesForTesting(i32a, 0));
}, 0);
})();

View File

@ -0,0 +1,25 @@
// Copyright 2020 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.
d8.file.execute("test/mjsunit/harmony/atomics-waitasync-helpers.js");
function workerCode() {
onmessage = function() {
const sab = new SharedArrayBuffer(16);
const i32a = new Int32Array(sab);
// Create a waiter with a timeout.
const result = Atomics.waitAsync(i32a, 0, 0, 1);
result.value.then(
(value) => { postMessage("result " + value); },
() => { postMessage("unexpected"); });
};
}
const expected_messages = [
"result timed-out"
];
runTestWithWorker(workerCode, expected_messages);

View File

@ -0,0 +1,65 @@
// Copyright 2020 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.
const N = 10;
function workerCode(N) {
const sab = new SharedArrayBuffer(16);
const i32a = new Int32Array(sab);
const location = 0;
const expected_value = 0;
function start() {
// Create N async waiters; the even ones without timeout and the odd ones
// with timeout.
for (let i = 0; i < N; ++i) {
let result;
if (i % 2 == 0) {
result = Atomics.waitAsync(i32a, location, expected_value);
} else {
result = Atomics.waitAsync(i32a, location, expected_value, i);
}
result.value.then(
(value) => { postMessage(value + " " + i); },
() => { postMessage("unexpected"); });
}
}
function wakeUpRemainingWaiters() {
// Wake up all waiters
let notify_return_value = Atomics.notify(i32a, location);
postMessage("notify return value " + notify_return_value);
}
onmessage = function({data:param}) {
if (param == "start") {
start();
} else if (param == "wakeUpRemainingWaiters") {
wakeUpRemainingWaiters();
}
};
}
const w = new Worker(workerCode, {type: 'function', arguments: [N]});
w.postMessage("start");
// Verify that all timed out waiters timed out in timeout order.
let waiter_no = 1;
for (let i = 0; i < N / 2; ++i) {
const m = w.getMessage();
assertEquals("timed-out " + waiter_no, m);
waiter_no += 2;
}
w.postMessage("wakeUpRemainingWaiters");
const m = w.getMessage();
assertEquals("notify return value " + N / 2, m);
// Verify that the waiters woke up in FIFO order.
waiter_no = 0;
for (let i = 0; i < N / 2; ++i) {
const m = w.getMessage();
assertEquals("ok " + waiter_no, m);
waiter_no += 2;
}
w.terminate();

View File

@ -0,0 +1,39 @@
// Copyright 2020 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: --allow-natives-syntax
(function test() {
const sab = new SharedArrayBuffer(16);
const i32a = new Int32Array(sab);
const N = 10;
let log = [];
// Create N async waiters.
for (let i = 0; i < N; ++i) {
const result = Atomics.waitAsync(i32a, 0, 0);
assertEquals(true, result.async);
result.value.then(
(value) => { assertEquals("ok", value); log.push(i); },
() => { assertUnreachable(); });
}
assertEquals(N, %AtomicsNumWaitersForTesting(i32a, 0));
assertEquals(0, %AtomicsNumUnresolvedAsyncPromisesForTesting(i32a, 0));
// Wake up all waiters.
let notify_return_value = Atomics.notify(i32a, 0);
assertEquals(N, notify_return_value);
assertEquals(0, %AtomicsNumWaitersForTesting(i32a, 0));
assertEquals(N, %AtomicsNumUnresolvedAsyncPromisesForTesting(i32a, 0));
function continuation() {
assertEquals(N, log.length);
for (let i = 0; i < N; ++i) {
assertEquals(i, log[i]);
}
}
setTimeout(continuation, 0);
})();

View File

@ -0,0 +1,55 @@
// Copyright 2020 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: --allow-natives-syntax
(function test() {
const sab = new SharedArrayBuffer(16);
const i32a = new Int32Array(sab);
// Create 2 async waiters.
const result1 = Atomics.waitAsync(i32a, 0, 0);
const result2 = Atomics.waitAsync(i32a, 0, 0);
assertEquals(true, result1.async);
assertEquals(true, result2.async);
assertEquals(2, %AtomicsNumWaitersForTesting(i32a, 0));
assertEquals(0, %AtomicsNumUnresolvedAsyncPromisesForTesting(i32a, 0));
let log = [];
result1.value.then(
(value) => { assertEquals("ok", value); log.push(1); },
() => { assertUnreachable(); });
result2.value.then(
(value) => { assertEquals("ok", value); log.push(2); },
() => { assertUnreachable(); });
// Wake up one waiter.
const notify_return_value = Atomics.notify(i32a, 0, 1);
assertEquals(1, notify_return_value);
assertEquals(1, %AtomicsNumWaitersForTesting(i32a, 0));
assertEquals(1, %AtomicsNumUnresolvedAsyncPromisesForTesting(i32a, 0));
function continuation1() {
assertEquals(1, %AtomicsNumWaitersForTesting(i32a, 0));
assertEquals(0, %AtomicsNumUnresolvedAsyncPromisesForTesting(i32a, 0));
assertEquals([1], log);
// Wake up one waiter.
const notify_return_value = Atomics.notify(i32a, 0, 1);
assertEquals(1, notify_return_value);
assertEquals(0, %AtomicsNumWaitersForTesting(i32a, 0));
assertEquals(1, %AtomicsNumUnresolvedAsyncPromisesForTesting(i32a, 0));
setTimeout(continuation2, 0);
}
function continuation2() {
assertEquals(0, %AtomicsNumWaitersForTesting(i32a, 0));
assertEquals(0, %AtomicsNumUnresolvedAsyncPromisesForTesting(i32a, 0));
assertEquals([1, 2], log);
}
setTimeout(continuation1, 0);
})();

View File

@ -0,0 +1,30 @@
// Copyright 2020 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: --allow-natives-syntax
(function test() {
const sab = new SharedArrayBuffer(16);
const i32a = new Int32Array(sab);
const result = Atomics.waitAsync(i32a, 0, 0);
assertEquals(true, result.async);
assertTrue(result.value instanceof Promise);
assertEquals(1, %AtomicsNumWaitersForTesting(i32a, 0));
assertEquals(0, %AtomicsNumUnresolvedAsyncPromisesForTesting(i32a, 0));
let resolved = false;
result.value.then(
(value) => { assertEquals("ok", value); resolved = true; },
() => { assertUnreachable(); });
const notify_return_value = Atomics.notify(i32a, 0, 1);
assertEquals(1, notify_return_value);
assertEquals(0, %AtomicsNumWaitersForTesting(i32a, 0));
assertEquals(1, %AtomicsNumUnresolvedAsyncPromisesForTesting(i32a, 0));
setTimeout(()=> {
assertTrue(resolved);
assertEquals(0, %AtomicsNumUnresolvedAsyncPromisesForTesting(i32a, 0));
}, 0);
})();

View File

@ -0,0 +1,15 @@
// Copyright 2020 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.
function runTestWithWorker(worker_code, expected_messages) {
const w = new Worker(worker_code, {type: 'function'});
w.postMessage('start');
let i = 0;
while (i < expected_messages.length) {
const m = w.getMessage();
assertEquals(expected_messages[i], m);
++i;
}
w.terminate();
}

View File

@ -0,0 +1,34 @@
// Copyright 2020 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: --allow-natives-syntax
(function test() {
const sab = new SharedArrayBuffer(16);
const i32a = new Int32Array(sab);
const location = 0;
(function createWorker() {
function workerCode(location) {
onmessage = function({data:msg}) {
if (msg.sab) {
const i32a = new Int32Array(msg.sab);
// Start 2 async waits in the same location.
const result1 = Atomics.waitAsync(i32a, location, 0);
const result2 = Atomics.waitAsync(i32a, location, 0);
postMessage('worker waiting');
}
}
}
const w = new Worker(workerCode, {type: 'function', arguments: [location]});
w.postMessage({sab: sab});
const m = w.getMessage();
assertEquals('worker waiting', m);
w.terminateAndWait();
})();
const notify_return_value = Atomics.notify(i32a, location, 2);
// No waiters got notified, since they got cleaned up before it.
assertEquals(0, notify_return_value);
})();

View File

@ -0,0 +1,40 @@
// Copyright 2020 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: --allow-natives-syntax
(function test() {
const sab = new SharedArrayBuffer(16);
const i32a = new Int32Array(sab);
const location = 0;
(function createWorker() {
function workerCode(location) {
onmessage = function({data:msg}) {
if (msg.sab) {
const i32a = new Int32Array(msg.sab);
Atomics.waitAsync(i32a, location, 0);
postMessage('worker waiting');
}
}
}
// Create 2 workers which wait on the same location.
let workers = [];
const worker_count = 2;
for (let i = 0; i < worker_count; ++i) {
workers[i] = new Worker(workerCode,
{type: 'function', arguments: [location]});
workers[i].postMessage({sab: sab});
const m = workers[i].getMessage();
assertEquals('worker waiting', m);
}
for (let i = 0; i < worker_count; ++i) {
workers[i].terminateAndWait();
}
})();
const notify_return_value = Atomics.notify(i32a, location, 2);
// No waiters got notified, since they got cleaned up before it.
assertEquals(0, notify_return_value);
})();

View File

@ -0,0 +1,31 @@
// Copyright 2020 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: --allow-natives-syntax --expose-gc
(function test() {
const sab = new SharedArrayBuffer(16);
const i32a = new Int32Array(sab);
(function createWorker() {
function workerCode() {
onmessage = function({data:msg}) {
if (msg.sab) {
const i32a = new Int32Array(msg.sab);
const result = Atomics.waitAsync(i32a, 0, 0);
postMessage('worker waiting');
}
}
};
const w = new Worker(workerCode, {type: 'function'});
w.postMessage({sab: sab});
const m = w.getMessage();
assertEquals('worker waiting', m);
w.terminate();
})();
gc();
Atomics.notify(i32a, 0, 1);
})();

View File

@ -0,0 +1,31 @@
// Copyright 2020 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: --allow-natives-syntax --expose-gc
(function test() {
const sab = new SharedArrayBuffer(16);
const i32a = new Int32Array(sab);
(function createWorker() {
function workerCode() {
onmessage = function({data:msg}) {
if (msg.sab) {
const i32a = new Int32Array(msg.sab);
const result = Atomics.waitAsync(i32a, 0, 0, 100000);
postMessage('worker waiting');
}
}
}
const w = new Worker(workerCode, {type: 'function'});
w.postMessage({sab: sab});
const m = w.getMessage();
assertEquals('worker waiting', m);
w.terminate();
})();
gc();
Atomics.notify(i32a, 0, 1);
})();

View File

@ -0,0 +1,31 @@
// Copyright 2020 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: --allow-natives-syntax
(function testOutOfBounds() {
const sab = new SharedArrayBuffer(16);
const i32a = new Int32Array(sab);
assertThrows(() => {
Atomics.waitAsync(i32a, 20, 0, 1000);
}, RangeError);
})();
(function testValueNotEquals() {
const sab = new SharedArrayBuffer(16);
const i32a = new Int32Array(sab);
const result = Atomics.waitAsync(i32a, 0, 1, 1000);
assertEquals(false, result.async);
assertEquals("not-equal", result.value);
})();
(function testZeroTimeout() {
const sab = new SharedArrayBuffer(16);
const i32a = new Int32Array(sab);
const result = Atomics.waitAsync(i32a, 0, 0, 0);
assertEquals(false, result.async);
assertEquals("timed-out", result.value);
})();

629
deps/v8/test/mjsunit/harmony/atomics.js vendored Normal file
View File

@ -0,0 +1,629 @@
// Copyright 2014 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: --js-staging
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;
}
}
function makeConstructorObject(constr, min, max, toRange) {
var o = {constr: constr, min: min, max: max};
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),
];
(function TestBadArray() {
var ab = new ArrayBuffer(16);
var sab = new SharedArrayBuffer(128);
var sf16a = new Float16Array(sab);
var sf32a = new Float32Array(sab);
var sf64a = new Float64Array(sab);
var u8ca = new Uint8ClampedArray(sab);
// Atomic ops required integer typed arrays
var badArrayTypes = [
undefined, 1, 'hi', 3.4, ab, sab, sf16a, sf32a, sf64a, u8ca
];
badArrayTypes.forEach(function(o) {
assertThrows(function() { Atomics.compareExchange(o, 0, 0, 0); },
TypeError);
assertThrows(function() { Atomics.load(o, 0); }, TypeError);
assertThrows(function() { Atomics.store(o, 0, 0); }, TypeError);
assertThrows(function() { Atomics.add(o, 0, 0); }, TypeError);
assertThrows(function() { Atomics.sub(o, 0, 0); }, TypeError);
assertThrows(function() { Atomics.and(o, 0, 0); }, TypeError);
assertThrows(function() { Atomics.or(o, 0, 0); }, TypeError);
assertThrows(function() { Atomics.xor(o, 0, 0); }, TypeError);
assertThrows(function() { Atomics.exchange(o, 0, 0); }, TypeError);
});
})();
(function TestBadIndex() {
var sab = new SharedArrayBuffer(8);
var si32a = new Int32Array(sab);
var si32a2 = new Int32Array(sab, 4);
// Indexes that are out of bounds when coerced via ToIndex should throw
// RangeError.
[-Infinity, Infinity].forEach(function(i) {
assertThrows(function() { Atomics.compareExchange(si32a, i, 0); },
RangeError);
assertThrows(function() { Atomics.load(si32a, i, 0); }, RangeError);
assertThrows(function() { Atomics.store(si32a, i, 0); }, RangeError);
assertThrows(function() { Atomics.add(si32a, i, 0); }, RangeError);
assertThrows(function() { Atomics.sub(si32a, i, 0); }, RangeError);
assertThrows(function() { Atomics.and(si32a, i, 0); }, RangeError);
assertThrows(function() { Atomics.or(si32a, i, 0); }, RangeError);
assertThrows(function() { Atomics.xor(si32a, i, 0); }, RangeError);
assertThrows(function() { Atomics.exchange(si32a, i, 0); }, RangeError);
}, RangeError);
// Out-of-bounds indexes should throw RangeError.
[-1, 2, 100].forEach(function(i) {
assertThrows(function() { Atomics.compareExchange(si32a, i, 0, 0); },
RangeError);
assertThrows(function() { Atomics.load(si32a, i); }, RangeError);
assertThrows(function() { Atomics.store(si32a, i, 0); }, RangeError);
assertThrows(function() { Atomics.add(si32a, i, 0); }, RangeError);
assertThrows(function() { Atomics.sub(si32a, i, 0); }, RangeError);
assertThrows(function() { Atomics.and(si32a, i, 0); }, RangeError);
assertThrows(function() { Atomics.or(si32a, i, 0); }, RangeError);
assertThrows(function() { Atomics.xor(si32a, i, 0); }, RangeError);
assertThrows(function() { Atomics.exchange(si32a, i, 0); }, RangeError);
}, RangeError);
// Out-of-bounds indexes for array with offset should throw RangeError.
[-1, 1, 100].forEach(function(i) {
assertThrows(function() { Atomics.compareExchange(si32a2, i, 0, 0); });
assertThrows(function() { Atomics.load(si32a2, i); }, RangeError);
assertThrows(function() { Atomics.store(si32a2, i, 0); }, RangeError);
assertThrows(function() { Atomics.add(si32a2, i, 0); }, RangeError);
assertThrows(function() { Atomics.sub(si32a2, i, 0); }, RangeError);
assertThrows(function() { Atomics.and(si32a2, i, 0); }, RangeError);
assertThrows(function() { Atomics.or(si32a2, i, 0); }, RangeError);
assertThrows(function() { Atomics.xor(si32a2, i, 0); }, RangeError);
assertThrows(function() { Atomics.exchange(si32a2, i, 0); }, RangeError);
});
// Monkey-patch length and make sure these functions still throw.
Object.defineProperty(si32a, 'length', {get: function() { return 1000; }});
[2, 100].forEach(function(i) {
assertThrows(function() { Atomics.compareExchange(si32a, i, 0, 0); });
assertThrows(function() { Atomics.load(si32a, i); });
assertThrows(function() { Atomics.store(si32a, i, 0); });
assertThrows(function() { Atomics.add(si32a, i, 0); });
assertThrows(function() { Atomics.sub(si32a, i, 0); });
assertThrows(function() { Atomics.and(si32a, i, 0); });
assertThrows(function() { Atomics.or(si32a, i, 0); });
assertThrows(function() { Atomics.xor(si32a, i, 0); });
assertThrows(function() { Atomics.exchange(si32a, i, 0); });
});
})();
(function TestGoodIndex() {
var sab = new SharedArrayBuffer(64);
var si32a = new Int32Array(sab);
var si32a2 = new Int32Array(sab, 32);
var testOp = function(op, ia, index, expectedIndex, name) {
for (var i = 0; i < ia.length; ++i)
ia[i] = i * 2;
ia[expectedIndex] = 0;
var result = op(ia, index, 0, 0);
assertEquals(0, result, name);
assertEquals(0, ia[expectedIndex], name);
for (var i = 0; i < ia.length; ++i) {
if (i == expectedIndex) continue;
assertEquals(i * 2, ia[i], name);
}
};
// These values all map to index 0
[-0, 0, 0.0, null, false, NaN, {}, '0.2', 'hi', undefined].forEach(
function(i) {
var name = String(i);
[si32a, si32a2].forEach(function(array) {
testOp(Atomics.compareExchange, array, i, 0, name);
testOp(Atomics.load, array, i, 0, name);
testOp(Atomics.store, array, i, 0, name);
testOp(Atomics.add, array, i, 0, name);
testOp(Atomics.sub, array, i, 0, name);
testOp(Atomics.and, array, i, 0, name);
testOp(Atomics.or, array, i, 0, name);
testOp(Atomics.xor, array, i, 0, name);
testOp(Atomics.exchange, array, i, 0, name);
});
});
// These values all map to index 3
var valueOf = {valueOf: function(){ return 3;}};
var toString = {toString: function(){ return '3';}};
[3, 3.0, '3', '3.0', valueOf, toString].forEach(function(i) {
var name = String(i);
[si32a, si32a2].forEach(function(array) {
testOp(Atomics.compareExchange, array, i, 3, name);
testOp(Atomics.load, array, i, 3, name);
testOp(Atomics.store, array, i, 3, name);
testOp(Atomics.add, array, i, 3, name);
testOp(Atomics.sub, array, i, 3, name);
testOp(Atomics.and, array, i, 3, name);
testOp(Atomics.or, array, i, 3, name);
testOp(Atomics.xor, array, i, 3, name);
testOp(Atomics.exchange, array, i, 3, name);
});
});
})();
function clearArray(sab) {
var ui8 = new Uint8Array(sab);
for (var i = 0; i < sab.byteLength; ++i) {
ui8[i] = 0;
}
}
(function TestCompareExchange() {
IntegerTypedArrayConstructors.forEach(function(t) {
var sab = new SharedArrayBuffer(10 * t.constr.BYTES_PER_ELEMENT);
var sta = new t.constr(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(_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(_i(50), Atomics.compareExchange(array, i, _i(0), _i(100)),
name);
assertEquals(_i(50), array[i], name);
}
})
});
})();
(function TestLoad() {
IntegerTypedArrayConstructors.forEach(function(t) {
var sab = new SharedArrayBuffer(10 * t.constr.BYTES_PER_ELEMENT);
var sta = new t.constr(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] = _i(0);
assertEquals(_i(0), Atomics.load(array, i), name);
array[i] = _i(50);
assertEquals(_i(50), Atomics.load(array, i), name);
}
})
});
// Test Smi range
(function () {
var sab = new SharedArrayBuffer(4);
var i32 = new Int32Array(sab);
var u32 = new Uint32Array(sab);
function testLoad(signedValue, unsignedValue) {
u32[0] = unsignedValue;
assertEquals(unsignedValue, Atomics.load(u32, 0));
assertEquals(signedValue, Atomics.load(i32, 0));
}
testLoad(0x3fffffff, 0x3fffffff); // 2**30-1 (always smi)
testLoad(0x40000000, 0x40000000); // 2**30 (smi if signed and 32-bits)
testLoad(0x80000000, -0x80000000); // 2**31 (smi if signed and 32-bits)
testLoad(0xffffffff, -1); // 2**31 (smi if signed)
});
})();
(function TestStore() {
IntegerTypedArrayConstructors.forEach(function(t) {
var sab = new SharedArrayBuffer(10 * t.constr.BYTES_PER_ELEMENT);
var sta = new t.constr(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(_i(50), Atomics.store(array, i, _i(50)), name);
assertEquals(_i(50), array[i], name);
assertEquals(_i(100), Atomics.store(array, i, _i(100)), name);
assertEquals(_i(100), array[i], name);
}
})
});
})();
(function TestAdd() {
IntegerTypedArrayConstructors.forEach(function(t) {
var sab = new SharedArrayBuffer(10 * t.constr.BYTES_PER_ELEMENT);
var sta = new t.constr(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(_i(0), Atomics.add(array, i, _i(50)), name);
assertEquals(_i(50), array[i], name);
assertEquals(_i(50), Atomics.add(array, i, _i(70)), name);
assertEquals(_i(120), array[i], name);
}
})
});
})();
(function TestSub() {
IntegerTypedArrayConstructors.forEach(function(t) {
var sab = new SharedArrayBuffer(10 * t.constr.BYTES_PER_ELEMENT);
var sta = new t.constr(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] = _i(120);
assertEquals(_i(120), Atomics.sub(array, i, _i(50)), name);
assertEquals(_i(70), array[i], name);
assertEquals(_i(70), Atomics.sub(array, i, _i(70)), name);
assertEquals(_i(0), array[i], name);
}
})
});
})();
(function TestAnd() {
IntegerTypedArrayConstructors.forEach(function(t) {
var sab = new SharedArrayBuffer(10 * t.constr.BYTES_PER_ELEMENT);
var sta = new t.constr(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] = _i(0x3f);
assertEquals(_i(0x3f), Atomics.and(array, i, _i(0x30)), name);
assertEquals(_i(0x30), array[i], name);
assertEquals(_i(0x30), Atomics.and(array, i, _i(0x20)), name);
assertEquals(_i(0x20), array[i], name);
}
})
});
})();
(function TestOr() {
IntegerTypedArrayConstructors.forEach(function(t) {
var sab = new SharedArrayBuffer(10 * t.constr.BYTES_PER_ELEMENT);
var sta = new t.constr(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] = _i(0x30);
assertEquals(_i(0x30), Atomics.or(array, i, _i(0x1c)), name);
assertEquals(_i(0x3c), array[i], name);
assertEquals(_i(0x3c), Atomics.or(array, i, _i(0x09)), name);
assertEquals(_i(0x3d), array[i], name);
}
})
});
})();
(function TestXor() {
IntegerTypedArrayConstructors.forEach(function(t) {
var sab = new SharedArrayBuffer(10 * t.constr.BYTES_PER_ELEMENT);
var sta = new t.constr(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] = _i(0x30);
assertEquals(_i(0x30), Atomics.xor(array, i, _i(0x1c)), name);
assertEquals(_i(0x2c), array[i], name);
assertEquals(_i(0x2c), Atomics.xor(array, i, _i(0x09)), name);
assertEquals(_i(0x25), array[i], name);
}
})
});
})();
(function TestExchange() {
IntegerTypedArrayConstructors.forEach(function(t) {
var sab = new SharedArrayBuffer(10 * t.constr.BYTES_PER_ELEMENT);
var sta = new t.constr(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] = _i(0x30);
assertEquals(_i(0x30), Atomics.exchange(array, i, _i(0x1c)), name);
assertEquals(_i(0x1c), array[i], name);
assertEquals(_i(0x1c), Atomics.exchange(array, i, _i(0x09)), name);
assertEquals(_i(0x09), array[i], name);
}
})
});
})();
(function TestIsLockFree() {
// Various invalid cases.
var valueOf = {valueOf: function(){ return 3;}};
var toString = {toString: function(){ return '3';}};
var invalid = [3.14, 'foo', Infinity, NaN, false, undefined, valueOf,
toString];
invalid.forEach(function(v) {
assertEquals(false, Atomics.isLockFree(v), JSON.stringify(v));
});
// For all platforms we support, 1, 2 and 4 bytes should be lock-free.
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 _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] = _i(50);
assertEquals(_i(50), Atomics.compareExchange(sta, 0, v, v), name);
// Store
assertEquals(_v(), Atomics.store(sta, 0, v), name);
assertEquals(_v(), sta[0], name);
// Add
sta[0] = _i(120);
assertEquals(_i(120), Atomics.add(sta, 0, v), name);
assertEquals(_i(120) + _v(), sta[0], name);
// Sub
sta[0] = _i(70);
assertEquals(_i(70), Atomics.sub(sta, 0, v), name);
assertEquals(_i(70) - _v(), sta[0]);
// And
sta[0] = _i(0x20);
assertEquals(_i(0x20), Atomics.and(sta, 0, v), name);
assertEquals(_i(0x20) & _v(), sta[0]);
// Or
sta[0] = _i(0x3d);
assertEquals(_i(0x3d), Atomics.or(sta, 0, v), name);
assertEquals(_i(0x3d) | _v(), sta[0]);
// Xor
sta[0] = _i(0x25);
assertEquals(_i(0x25), Atomics.xor(sta, 0, v), name);
assertEquals(_i(0x25) ^ _v(), sta[0]);
// Exchange
sta[0] = _i(0x09);
assertEquals(_i(0x09), Atomics.exchange(sta, 0, v), name);
assertEquals(_v(), sta[0]);
});
});
})();
(function TestWrapping() {
IntegerTypedArrayConstructors.forEach(function(t) {
var sab = new SharedArrayBuffer(10 * t.constr.BYTES_PER_ELEMENT);
var sta = new t.constr(sab);
var name = Object.prototype.toString.call(sta);
let _i = (i) => { return MaybeIntToBigInt(sta, i); }
var range = t.max - t.min + _i(1);
var offset;
var operand;
var val, newVal;
var valWrapped, newValWrapped;
for (offset = -range; offset <= range; offset += range) {
// CompareExchange
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 - _i(1);
newValWrapped = t.toRange(newVal);
assertEquals(val, Atomics.compareExchange(sta, 0, val, newVal), name);
assertEquals(newValWrapped, sta[0], name);
// Store
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 - _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 + _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 - _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 - _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 + _i(1);
valWrapped = t.toRange(val - operand);
assertEquals(val, Atomics.sub(sta, 0, operand), name);
assertEquals(valWrapped, sta[0], name);
// There's no way to wrap results with logical operators, just test that
// using an out-of-range value is properly wrapped/clamped when written
// to memory.
// And
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 = _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 = _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 = _i(0x12);
operand = _i(0x22) + offset;
valWrapped = t.toRange(operand);
assertEquals(val, Atomics.exchange(sta, 0, operand), name);
assertEquals(valWrapped, sta[0], name);
}
});
})();
(function TestValidateIndexBeforeValue() {
var testOp = function(op, sta, name) {
var valueof_has_been_called = 0;
var value = {valueOf: function() { valueof_has_been_called = 1; return 0;}};
var index = -1;
// The index should be checked before calling ToInteger on the value, so
// valueof_has_been_called should not be modified.
sta[0] = MaybeIntToBigInt(sta, 0);
assertThrows(function() { op(sta, index, value, value); }, RangeError);
assertEquals(0, valueof_has_been_called);
};
IntegerTypedArrayConstructors.forEach(function(t) {
var sab = new SharedArrayBuffer(10 * t.constr.BYTES_PER_ELEMENT);
var sta = new t.constr(sab);
var name = Object.prototype.toString.call(sta);
testOp(Atomics.compareExchange, sta, name);
testOp(Atomics.load, sta, name);
testOp(Atomics.store, sta, name);
testOp(Atomics.add, sta, name);
testOp(Atomics.sub, sta, name);
testOp(Atomics.and, sta, name);
testOp(Atomics.or, sta, name);
testOp(Atomics.xor, sta, name);
testOp(Atomics.exchange, sta, name);
});
})();

View File

@ -0,0 +1,29 @@
// Copyright 2025 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: --js-staging
let order = [];
async function TestSymbolAsyncDisposeAndSymbolDisposeGetOrder() {
var resource = {
get [Symbol.asyncDispose]() {
order.push('Symbol.asyncDispose');
return null;
},
get [Symbol.dispose]() {
order.push('Symbol.dispose');
return function() { };
}
};
await using x = resource;
}
async function RunTest() {
await TestSymbolAsyncDisposeAndSymbolDisposeGetOrder();
assertSame('Symbol.asyncDispose,Symbol.dispose', order.join(','));
}
RunTest();

View File

@ -0,0 +1,11 @@
// Copyright 2025 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: --js-staging
async function f() {
await using x = null;
assertSame(null, x);
}
f();

View File

@ -0,0 +1,48 @@
// Copyright 2025 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: --js-staging
async function TestThrowingSuppressedError() {
class MyError extends Error {}
const error1 = new MyError();
const error2 = new MyError();
const error3 = new MyError();
try {
await using x = {
async[Symbol.asyncDispose]() {
throw error1;
}
};
await using y = {
[Symbol.dispose]() {
throw error2;
}
};
throw error3;
} catch (e) {
assertTrue(
e instanceof SuppressedError,
'Expected an SuppressedError to have been thrown');
assertEquals(
e.error, error1,
'Expected the outermost suppressing error to have been \'error1\'');
assertTrue(
e.suppressed instanceof SuppressedError,
'Expected the outermost suppressed error to have been a SuppressedError');
assertEquals(
e.suppressed.error, error2,
'Expected the innermost suppressing error to have been \'error2\'');
assertEquals(
e.suppressed.suppressed, error3,
'Expected the innermost suppressed error to have been \'error3\'');
}
}
async function RunTest() {
await TestThrowingSuppressedError();
}
RunTest();

View File

@ -0,0 +1,37 @@
// Copyright 2024 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: --js-staging
let values = [];
(async () => {
for (let i = 0; i < 10; ++i) {
values.push(i);
await 0;
}
})();
async function TestCountTicks() {
await using x = {
value: 1,
[Symbol.asyncDispose]() {
values.push(42);
}
};
await using y = {
value: 1,
[Symbol.asyncDispose]() {
values.push(43);
}
};
values.push(44);
}
async function RunTest() {
await TestCountTicks();
assertSame('0,44,43,1,42,2,3', values.join(','));
}
RunTest();

View File

@ -0,0 +1,39 @@
// Copyright 2024 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: --js-staging
let values = [];
(async () => {
for (let i = 0; i < 10; ++i) {
values.push(i);
await 0;
}
})();
async function TestCountTicks() {
using x = {
value: 1,
[Symbol.dispose]() {
values.push(42);
}
};
await using y = null;
await using z = {
value: 1,
[Symbol.asyncDispose]() {
values.push(43);
}
};
await using w = undefined;
values.push(44);
}
async function RunTest() {
await TestCountTicks();
assertSame('0,44,43,1,42,2', values.join(','));
}
RunTest();

View File

@ -0,0 +1,33 @@
// Copyright 2024 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: --js-staging
let values = [];
(async () => {
for (let i = 0; i < 10; ++i) {
values.push(i);
await 0;
}
})();
async function TestCountTicks() {
using x = {
value: 1,
[Symbol.dispose]() {
values.push(42);
}
};
await using y = null;
await using z = undefined;
values.push(44);
}
async function RunTest() {
await TestCountTicks();
assertSame('0,44,1,42,2', values.join(','));
}
RunTest();

View File

@ -0,0 +1,66 @@
// Copyright 2025 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: --expose-externalize-string --js-base-64
(function TestBase64FromHexWithLongInputs() {
var arr_32 = Uint8Array.fromHex('666f6F6261726172666f6f62617261ff');
assertSame(
'102,111,111,98,97,114,97,114,102,111,111,98,97,114,97,255',
arr_32.join(','));
var arr_48 =
Uint8Array.fromHex('666f6f6261726172666f6f62617261ff666f6f6261726172');
assertSame(
'102,111,111,98,97,114,97,114,102,111,111,98,97,114,97,255,102,111,111,98,97,114,97,114',
arr_48.join(','));
var arr_64 = Uint8Array.fromHex(
'666f6f6261726172666f6f62617261ff666f6f62617261ff666f6f6261726172');
assertSame(
'102,111,111,98,97,114,97,114,102,111,111,98,97,114,97,255,102,111,111,98,97,114,97,255,102,111,111,98,97,114,97,114',
arr_64.join(','));
assertThrows(
() => Uint8Array.fromHex('666f6f6261726172666f6f62617261a^'),
SyntaxError);
assertThrows(
() => Uint8Array.fromHex(
'666f6f6261726172666f6f62617261ff666f6f62617261a^'),
SyntaxError);
assertThrows(
() => Uint8Array.fromHex(
'666f6f6261726172666f6f62617261ff666f6f62617261ff666f6f62617261a^'),
SyntaxError);
var two_byte_32 =
createExternalizableTwoByteString('666f6f6261726172666f6f62617261ff');
var arr_two_byte_32 = Uint8Array.fromHex(two_byte_32);
assertSame(
'102,111,111,98,97,114,97,114,102,111,111,98,97,114,97,255',
arr_two_byte_32.join(','));
var two_byte_48 = createExternalizableTwoByteString(
'666f6f6261726172666f6f62617261ff666f6f6261726172');
var arr_two_byte_48 = Uint8Array.fromHex(two_byte_48);
assertSame(
'102,111,111,98,97,114,97,114,102,111,111,98,97,114,97,255,102,111,111,98,97,114,97,114',
arr_two_byte_48.join(','));
var two_byte_64 = createExternalizableTwoByteString(
'666f6f6261726172666f6f62617261ff666f6f62617261ff666f6f6261726172');
var arr_two_byte_64 = Uint8Array.fromHex(two_byte_64);
assertSame(
'102,111,111,98,97,114,97,114,102,111,111,98,97,114,97,255,102,111,111,98,97,114,97,255,102,111,111,98,97,114,97,114',
arr_two_byte_64.join(','));
for (let i = 0; i < 0xFF; i++) {
if ((i >= 0x30 && i <= 0x39 /* 0-9 */) ||
(i >= 0x41 && i <= 0x46 /* A-F */) ||
(i >= 0x61 && i <= 0x66 /* a-f */))
continue;
const str = String.fromCharCode.apply(String, Array(32).fill(i));
assertThrows(() => Uint8Array.fromHex(str), SyntaxError);
}
})();

View File

@ -0,0 +1,13 @@
// Copyright 2025 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: --expose-externalize-string --js-base-64
(function TestBase64FromHexWithTwByteStrings() {
var twoByteString = createExternalizableTwoByteString('666f6f626172');
var arr = Uint8Array.fromHex(twoByteString);
assertSame('102,111,111,98,97,114', arr.join(','));
assertThrows(() => Uint8Array.fromHex('☉‿⊙'), SyntaxError);
})();

View File

@ -0,0 +1,39 @@
// Copyright 2025 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: --js-base-64
(function TestBase64PrototypeToHexWithLongInputs() {
assertEquals(
(new Uint8Array([102, 111, 111, 98, 97, 114, 111, 111])).toHex(),
'666f6f6261726f6f');
assertEquals(
(new Uint8Array([102, 111, 111, 98, 97, 114, 111, 111, 111, 111]))
.toHex(),
'666f6f6261726f6f6f6f');
assertEquals(
(new Uint8Array([
102, 111, 111, 98, 97, 114, 111, 111, 102, 111, 111, 98, 97, 114, 111,
111
])).toHex(),
'666f6f6261726f6f666f6f6261726f6f');
assertEquals(
(new Uint8Array([
102, 111, 111, 98, 97, 114, 111, 111, 102, 111, 111, 98, 97, 114, 111,
111, 111, 111
])).toHex(),
'666f6f6261726f6f666f6f6261726f6f6f6f');
assertEquals(
(new Uint8Array([
102, 111, 111, 98, 97, 114, 111, 111, 102, 111, 111, 98,
97, 114, 111, 111, 102, 111, 111, 98, 97, 114, 111, 111
])).toHex(),
'666f6f6261726f6f666f6f6261726f6f666f6f6261726f6f');
assertEquals(
(new Uint8Array([
102, 111, 111, 98, 97, 114, 111, 111, 102, 111, 111, 98, 97,
114, 111, 111, 102, 111, 111, 98, 97, 114, 111, 111, 111, 111
])).toHex(),
'666f6f6261726f6f666f6f6261726f6f666f6f6261726f6f6f6f');
})();

View File

@ -0,0 +1,105 @@
// Copyright 2017 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.
// Generated by tools/bigint-tester.py.
var data = [{
a: -0xc4043e2c4cc49e4d6870103ce7c2ff2d512bf4b1b67553ba410db514ee0af8888ad6cfn,
b: 0x2aae86de73ff479133a657a40d26e8dcf192019c7421836615ec34978bad93n,
r: -0xc4043e2c2216176ef470c8abb41ca78944050bd4c4e3521dccec31aed81ec3f0ff293cn
}, {
a: -0xee0933b25c8c0ef09fa385ffa1d3ca76855b560e186d27fa9f6ce105cb8517a4aecd5n,
b: -0x2ffc3a7babad313ede574774cb55cd40ab3b2n,
r: -0xee0933b25c8c0ef09fa385ffa1d3ca76b5579089c41a59397dc4287a96dae4e55a087n
}, {
a: -0xdbb3e8fac212affdeda8959829838af77e43172n,
b: 0x2315999da3ac2ab89d2076cbe6e2e03082352e92c274680117ce7012dn,
r: 0x2315999da3ac2ab89c44c2e2ec20cd80844785fd2a4ae47620502cfbbn
}, {
a: -0x5ad9780b309c24919defb1b331ebba4en,
b: 0xbe8dd806b3da0f79e7f6ad2fb566536cc78c1471c236891ce0n,
r: 0xbe8dd806b3da0f79e79bd3b7aa35b74835ee24c00f049d6292n
}, {
a: -0xade45eac6aaaf2c8097d7a3efecba4e80dd7aac4f692cfe841d113e68096c0218d521an,
b: -0x73c4119b366e22edd0797b5883a13e3bfc4124a559903ce785e0c833a8306b41cfn,
r: -0xade4d2707c4629362c6b4ab87a2428894c13a7061b3829787eb899c748ca6851f893e9n
}, {
a: -0x6e9ab93d5cff3b3f31a55aa2f43fc321bff6978189e00fa4e64cn,
b: 0xec1caec29eb55312a313e50e20178873a350f1f89cbc971n,
r: -0x6e9aaa7b92131153dc743071b5eee120476f5d4c7ac085d91cdbn
}, {
a: -0x9a61c05bd53b74b731b8f8687e64d1ed1340404b5137ce39n,
b: -0x1e6793ea0fa51b2354b48n,
r: -0x9a61c05bd53b74b731b8f8687e66b86651e13a9d036d1981n
}, {
a: -0x7c5a08517038f7dn,
b: 0x1d89f2n,
r: -0x7c5a08516e6058bn
}, {
a: -0xc4fd1b5aae2cfdc7b3ea6a74b7926a9a1ca3513bd08341e0c770080ban,
b: 0x76c79770202f9d9c6d2e244n,
r: -0xc4fd1b5aae2cfdc7b3ea6a74b7926a9a1c2c89a4606312432b02d9e76n
}, {
a: 0xda114ddab6bfed910cc05c64f72961107beb98c3271n,
b: 0x98c52c393c6660663248fcbaa300b8n,
r: 0xda114ddab6bff71d5f83f02b5d2fc4350bb742f3329n
}, {
a: -0x46311d926dfd26f0850ea3497fcd0d95a5dabab0361f219a601dc3dbe35d0n,
b: -0xf340af7b84e4eced2ca613e1ef4bb6aec4b8f01bc3n,
r: -0x46311d926dfd26f0851dd75477855be474ad8511743e1655cb0a0f6ae5193n
}, {
a: 0xb2b4d9c0c73258a8092n,
b: 0xf4d1c3d2861cc0bfaea456c03b0f548a32effc1c3e1593935a6b0n,
r: 0xf4d1c3d2861cc0bfaea456c03b0f548a33a2b0f5fedcc5ec02742n
}, {
a: -0x56604879bdaaff7409cd59cfbafe73a74c284bfaeb991b6e11171bc08cf68bean,
b: 0xf4016a6e94c0f256af54fca00d6c909a620c6ea950c73cade3724174c12888n,
r: -0x556c470f4f163e81b31e04d31af10716b1c63f8c424854316333a97f18356362n
}, {
a: -0x7a238c856c50aee41d1a2a1446a77f1567n,
b: 0x58n,
r: -0x7a238c856c50aee41d1a2a1446a77f150fn
}, {
a: 0xcdaf8c242e5da7265cc715871c3n,
b: -0x63604dd2b8df176c627ce3b018b2e74448746123d5578e66e9c0n,
r: -0x63604dd2b8df176c627ce3b00bd7ee82058e86b16f8b1d0e77fdn
}, {
a: 0xfa254e9c8d182d2bd90d8ff2b25d4e9819900b62b9ef60f3744ddc55cd362den,
b: -0x1fef80ff5d53dd0adaa75e8f0d16429851de115822n,
r: 0xfa254e9c8d182d2bd90d8df3ba4d58c2dbbf5db84406702210245737ec20abcn
}, {
a: 0x3e85cn,
b: 0x687c558b2c1308c1a133d647ff7en,
r: 0x687c558b2c1308c1a133d64be7dan
}, {
a: 0x9011db3dd56dbf2ef06154cbd48a67f6038483cff59f49011e57n,
b: 0xc033be10adcb6a7a5a697a7ef95ac3680611ff7ef690231314d338an,
r: 0xc03cbf2e61a8c1564d58809446180c0e857237c7338f7d07a4e51e1n
}, {
a: -0xefac02ab40df0f00a1b97a4n,
b: 0xc3b5e53656cd891e179ec3fb8a8d192f9bab5cfd76c014400n,
r: 0xc3b5e53656cd891e179ec3fb899d6d2cf06a7dee761e5ac5cn
}, {
a: -0x7f9d48b408a5bb3827bc0149ecd538a2b2a7d4e1e0a4e9c36ee05f8be3a5b3n,
b: 0xd83d8cb2fb784703498cf0d61ff097ca42635664058cb85ea39f5931c37a1n,
r: -0x72196fe8d8ee36c7f323323c8ad62f260e819f7ba04c1e3d84a669f8c76e12n
}];
var error_count = 0;
for (var i = 0; i < data.length; i++) {
var d = data[i];
var r = d.a + d.b;
if (d.r !== r) {
print("Input A: " + d.a.toString(16));
print("Input B: " + d.b.toString(16));
print("Result: " + r.toString(16));
print("Expected: " + d.r);
print("Op: +");
error_count++;
}
}
if (error_count !== 0) {
print("Finished with " + error_count + " errors.")
quit(1);
}

View File

@ -0,0 +1,105 @@
// Copyright 2017 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.
// Generated by tools/bigint-tester.py.
var data = [{
a: 0x9252b94f220ded0c18706998886397699c5a25527575dn,
b: -0x286817ba2e8fd8n,
r: 0x9252b94f220ded0c1870699888639769185a045015008n
}, {
a: 0x15a28152354fe421bbe4649d4d22d536ac34f9ba962n,
b: 0x8n,
r: 0n
}, {
a: 0xd09791bf7ae6703fae8d654104f54fcd957bbf028540b8e7c0f859fdcc1b7abd617en,
b: 0x24b473d03n,
r: 0x24a052102n
}, {
a: 0x2f73fbd05e9f7f70beba3dc7cd883732149a3d02a422f90f336n,
b: 0x4490583f8n,
r: 0x9008330n
}, {
a: 0xd6ea27844b3d356774e73de10d393ab9cadb81848e3b4a34d1f7440d3n,
b: 0x1639eeee731f3ba09234b5e15ec92f8bfb5cea28a0e89c59ed1c45b5f04n,
r: 0x10ea26000b39200234a5214009290ab948ca008088184824104504000n
}, {
a: -0x131f5e2c196269fd140c8727a9a02170e0dddb6aec109a89bcn,
b: 0x401ec4eae8b756f2b222f6f565fb6acecce3c524e9b453n,
r: 0x12c488800242f230005655448b0a0204810124613440n
}, {
a: -0x5bcba128bf7b949780a4bd02782a63ae79f646a33b8672f3f692ab98n,
b: -0xa81dd8ff624072fce3a00eb0bd5700e5666c3beb7d59701c42489n,
r: -0x5bcba1fdbfffb497afeebf02fb2bf7fe7ff666e3bfb7f7f7f7d6afa0n
}, {
a: 0xc997546528786548270061bcn,
b: 0x75023f046c04f9095f64d3b8c75ab21950an,
r: 0x499014640838044023000108n
}, {
a: 0x5ad0abd6e43ef787248af2607fb29b9c3f7a1e7b106269ff3bn,
b: -0xd483c8630392db4b620e0f6n,
r: 0x5ad0abd6e43ef787248af2607fb29380394a06520040491f0an
}, {
a: -0x9ed448bdb4794e4c0485db9ebe6cad0b0n,
b: -0x549a70753c9afn,
r: -0x9ed448bdb4794e4c0485df9efe7dbd9b0n
}, {
a: -0x3a3fe42647633612082372714484767efc9673ce964b76f9f53a63d5n,
b: 0x99615e5edd0506cbb5512fb56ee2dd1238bn,
r: 0x986116189800068881100b0000608c1000bn
}, {
a: -0xac1b8238c08f5n,
b: -0xb9439dfbbc70e12b3a1fc7ccbfebeacd9bb321d83d3an,
r: -0xb9439dfbbc70e12b3a1fc7ccbfebeacfdbbb23dc3dfen
}, {
a: 0x120580503n,
b: 0x90e13d34618496af407fabefabdd23892f488n,
r: 0x20100400n
}, {
a: 0xaa51cn,
b: 0x2122a9c43b2531d5n,
r: 0x2114n
}, {
a: 0xaf43eb353c1547dc6ad79768e9a6n,
b: 0x55c80f89d8fe82dbf69eca557dd0479b6a449db77e38b2241ec81aa7d4042766dd3e63n,
r: 0x28022014081007d4000706482822n
}, {
a: 0xbd38b2d88212ceea6fbe3890769e46236n,
b: 0xeb22e568873e9bfdb5d2ddbc03n,
r: 0x88202468863a83890540c42002n
}, {
a: 0x24cd8c9634eddf319c57b54dffb49ce4974528f03b2c732d052ad496n,
b: -0x4079cfn,
r: 0x24cd8c9634eddf319c57b54dffb49ce4974528f03b2c732d052a8410n
}, {
a: -0x61f263476a1212fce55cf7d437f4364b73a1815a641n,
b: -0x19226cb79772cca166043a29d1f0fe1df5n,
r: -0x61f263476b9236fffd7fffde37f477ebffbf8ffbff5n
}, {
a: -0x44309b08a65bc7dc1e53d598d82ccdaa852941d7c851d907a6acn,
b: 0xdd93dc17d38658ee30453d5f27en,
r: 0x5d1304178102408230402d05054n
}, {
a: 0x1e3eea4668e7a6c3bfa87d3f7a419bd18an,
b: -0x592d83940f884f9n,
r: 0x1e3eea4668e7a6c3bfa86d274201035102n
}];
var error_count = 0;
for (var i = 0; i < data.length; i++) {
var d = data[i];
var r = d.a & d.b;
if (d.r !== r) {
print("Input A: " + d.a.toString(16));
print("Input B: " + d.b.toString(16));
print("Result: " + r.toString(16));
print("Expected: " + d.r);
print("Op: &");
error_count++;
}
}
if (error_count !== 0) {
print("Finished with " + error_count + " errors.")
quit(1);
}

View File

@ -0,0 +1,304 @@
// Copyright 2017 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.
// BigInt.asIntN
{
assertEquals(2, BigInt.asIntN.length);
}{
assertEquals(-1n, BigInt.asIntN(3, 15n));
assertEquals(-2n, BigInt.asIntN(3, 14n));
assertEquals(-3n, BigInt.asIntN(3, 13n));
assertEquals(-4n, BigInt.asIntN(3, 12n));
assertEquals(3n, BigInt.asIntN(3, 11n));
assertEquals(2n, BigInt.asIntN(3, 10n));
assertEquals(1n, BigInt.asIntN(3, 9n));
assertEquals(0n, BigInt.asIntN(3, 8n));
assertEquals(-1n, BigInt.asIntN(3, 7n));
assertEquals(-2n, BigInt.asIntN(3, 6n));
assertEquals(-3n, BigInt.asIntN(3, 5n));
assertEquals(-4n, BigInt.asIntN(3, 4n));
assertEquals(3n, BigInt.asIntN(3, 3n));
assertEquals(2n, BigInt.asIntN(3, 2n));
assertEquals(1n, BigInt.asIntN(3, 1n));
assertEquals(0n, BigInt.asIntN(3, 0n));
assertEquals(-1n, BigInt.asIntN(3, -1n));
assertEquals(-2n, BigInt.asIntN(3, -2n));
assertEquals(-3n, BigInt.asIntN(3, -3n));
assertEquals(-4n, BigInt.asIntN(3, -4n));
assertEquals(3n, BigInt.asIntN(3, -5n));
assertEquals(2n, BigInt.asIntN(3, -6n));
assertEquals(1n, BigInt.asIntN(3, -7n));
assertEquals(0n, BigInt.asIntN(3, -8n));
assertEquals(-1n, BigInt.asIntN(3, -9n));
assertEquals(-2n, BigInt.asIntN(3, -10n));
assertEquals(-3n, BigInt.asIntN(3, -11n));
assertEquals(-4n, BigInt.asIntN(3, -12n));
assertEquals(3n, BigInt.asIntN(3, -13n));
assertEquals(2n, BigInt.asIntN(3, -14n));
assertEquals(1n, BigInt.asIntN(3, -15n));
}{
assertEquals(254n, BigInt.asIntN(10, 254n));
assertEquals(255n, BigInt.asIntN(10, 255n));
assertEquals(256n, BigInt.asIntN(10, 256n));
assertEquals(257n, BigInt.asIntN(10, 257n));
assertEquals(510n, BigInt.asIntN(10, 510n));
assertEquals(511n, BigInt.asIntN(10, 511n));
assertEquals(-512n, BigInt.asIntN(10, 512n));
assertEquals(-511n, BigInt.asIntN(10, 513n));
assertEquals(-2n, BigInt.asIntN(10, 1022n));
assertEquals(-1n, BigInt.asIntN(10, 1023n));
assertEquals(0n, BigInt.asIntN(10, 1024n));
assertEquals(1n, BigInt.asIntN(10, 1025n));
}{
assertEquals(-254n, BigInt.asIntN(10, -254n));
assertEquals(-255n, BigInt.asIntN(10, -255n));
assertEquals(-256n, BigInt.asIntN(10, -256n));
assertEquals(-257n, BigInt.asIntN(10, -257n));
assertEquals(-510n, BigInt.asIntN(10, -510n));
assertEquals(-511n, BigInt.asIntN(10, -511n));
assertEquals(-512n, BigInt.asIntN(10, -512n));
assertEquals(511n, BigInt.asIntN(10, -513n));
assertEquals(2n, BigInt.asIntN(10, -1022n));
assertEquals(1n, BigInt.asIntN(10, -1023n));
assertEquals(0n, BigInt.asIntN(10, -1024n));
assertEquals(-1n, BigInt.asIntN(10, -1025n));
}{
assertEquals(0n, BigInt.asIntN(0, 0n));
assertEquals(0n, BigInt.asIntN(1, 0n));
assertEquals(0n, BigInt.asIntN(16, 0n));
assertEquals(0n, BigInt.asIntN(31, 0n));
assertEquals(0n, BigInt.asIntN(32, 0n));
assertEquals(0n, BigInt.asIntN(33, 0n));
assertEquals(0n, BigInt.asIntN(63, 0n));
assertEquals(0n, BigInt.asIntN(64, 0n));
assertEquals(0n, BigInt.asIntN(65, 0n));
assertEquals(0n, BigInt.asIntN(127, 0n));
assertEquals(0n, BigInt.asIntN(128, 0n));
assertEquals(0n, BigInt.asIntN(129, 0n));
}{
assertEquals(0n, BigInt.asIntN(0, 42n));
assertEquals(0n, BigInt.asIntN(1, 42n));
assertEquals(42n, BigInt.asIntN(16, 42n));
assertEquals(42n, BigInt.asIntN(31, 42n));
assertEquals(42n, BigInt.asIntN(32, 42n));
assertEquals(42n, BigInt.asIntN(33, 42n));
assertEquals(42n, BigInt.asIntN(63, 42n));
assertEquals(42n, BigInt.asIntN(64, 42n));
assertEquals(42n, BigInt.asIntN(65, 42n));
assertEquals(42n, BigInt.asIntN(127, 42n));
assertEquals(42n, BigInt.asIntN(128, 42n));
assertEquals(42n, BigInt.asIntN(129, 42n));
}{
assertEquals(0n, BigInt.asIntN(0, -42n));
assertEquals(0n, BigInt.asIntN(1, -42n));
assertEquals(-42n, BigInt.asIntN(16, -42n));
assertEquals(-42n, BigInt.asIntN(31, -42n));
assertEquals(-42n, BigInt.asIntN(32, -42n));
assertEquals(-42n, BigInt.asIntN(33, -42n));
assertEquals(-42n, BigInt.asIntN(63, -42n));
assertEquals(-42n, BigInt.asIntN(64, -42n));
assertEquals(-42n, BigInt.asIntN(65, -42n));
assertEquals(-42n, BigInt.asIntN(127, -42n));
assertEquals(-42n, BigInt.asIntN(128, -42n));
assertEquals(-42n, BigInt.asIntN(129, -42n));
}{
assertEquals(0n, BigInt.asIntN(0, 4294967295n));
assertEquals(-1n, BigInt.asIntN(1, 4294967295n));
assertEquals(-1n, BigInt.asIntN(16, 4294967295n));
assertEquals(-1n, BigInt.asIntN(31, 4294967295n));
assertEquals(-1n, BigInt.asIntN(32, 4294967295n));
assertEquals(4294967295n, BigInt.asIntN(33, 4294967295n));
assertEquals(4294967295n, BigInt.asIntN(63, 4294967295n));
assertEquals(4294967295n, BigInt.asIntN(64, 4294967295n));
assertEquals(4294967295n, BigInt.asIntN(65, 4294967295n));
assertEquals(4294967295n, BigInt.asIntN(127, 4294967295n));
assertEquals(4294967295n, BigInt.asIntN(128, 4294967295n));
assertEquals(4294967295n, BigInt.asIntN(129, 4294967295n));
}{
assertEquals(0n, BigInt.asIntN(0, -4294967295n));
assertEquals(-1n, BigInt.asIntN(1, -4294967295n));
assertEquals(1n, BigInt.asIntN(16, -4294967295n));
assertEquals(1n, BigInt.asIntN(31, -4294967295n));
assertEquals(1n, BigInt.asIntN(32, -4294967295n));
assertEquals(-4294967295n, BigInt.asIntN(33, -4294967295n));
assertEquals(-4294967295n, BigInt.asIntN(63, -4294967295n));
assertEquals(-4294967295n, BigInt.asIntN(64,-4294967295n));
assertEquals(-4294967295n, BigInt.asIntN(65, -4294967295n));
assertEquals(-4294967295n, BigInt.asIntN(127, -4294967295n));
assertEquals(-4294967295n, BigInt.asIntN(128, -4294967295n));
assertEquals(-4294967295n, BigInt.asIntN(129, -4294967295n));
}{
assertEquals(42n, BigInt.asIntN(2**32, 42n));
assertEquals(4294967295n, BigInt.asIntN(2**32, 4294967295n));
assertEquals(4294967296n, BigInt.asIntN(2**32, 4294967296n));
assertEquals(4294967297n, BigInt.asIntN(2**32, 4294967297n));
}{
assertThrows(() => BigInt.asIntN(2n, 12n), TypeError);
assertThrows(() => BigInt.asIntN(-1, 0n), RangeError);
assertThrows(() => BigInt.asIntN(2**53, 0n), RangeError);
assertEquals(0n, BigInt.asIntN({}, 12n));
assertEquals(0n, BigInt.asIntN(2.9999, 12n));
assertEquals(-4n, BigInt.asIntN(3.1234, 12n));
}{
assertThrows(() => BigInt.asIntN(3, 12), TypeError);
assertEquals(-4n, BigInt.asIntN(3, "12"));
assertEquals(0x123456789abcdefn,
BigInt.asIntN(64, 0xabcdef0123456789abcdefn));
}{
// Regression test for crbug.com/v8/8426.
assertEquals(-0x8000000000000000n,
BigInt.asIntN(64, -0x8000000000000000n));
}
// BigInt.asUintN
{
assertEquals(2, BigInt.asUintN.length);
}{
assertEquals(7n, BigInt.asUintN(3, 15n));
assertEquals(6n, BigInt.asUintN(3, 14n));
assertEquals(5n, BigInt.asUintN(3, 13n));
assertEquals(4n, BigInt.asUintN(3, 12n));
assertEquals(3n, BigInt.asUintN(3, 11n));
assertEquals(2n, BigInt.asUintN(3, 10n));
assertEquals(1n, BigInt.asUintN(3, 9n));
assertEquals(0n, BigInt.asUintN(3, 8n));
assertEquals(7n, BigInt.asUintN(3, 7n));
assertEquals(6n, BigInt.asUintN(3, 6n));
assertEquals(5n, BigInt.asUintN(3, 5n));
assertEquals(4n, BigInt.asUintN(3, 4n));
assertEquals(3n, BigInt.asUintN(3, 3n));
assertEquals(2n, BigInt.asUintN(3, 2n));
assertEquals(1n, BigInt.asUintN(3, 1n));
assertEquals(0n, BigInt.asUintN(3, 0n));
assertEquals(7n, BigInt.asUintN(3, -1n));
assertEquals(6n, BigInt.asUintN(3, -2n));
assertEquals(5n, BigInt.asUintN(3, -3n));
assertEquals(4n, BigInt.asUintN(3, -4n));
assertEquals(3n, BigInt.asUintN(3, -5n));
assertEquals(2n, BigInt.asUintN(3, -6n));
assertEquals(1n, BigInt.asUintN(3, -7n));
assertEquals(0n, BigInt.asUintN(3, -8n));
assertEquals(7n, BigInt.asUintN(3, -9n));
assertEquals(6n, BigInt.asUintN(3, -10n));
assertEquals(5n, BigInt.asUintN(3, -11n));
assertEquals(4n, BigInt.asUintN(3, -12n));
assertEquals(3n, BigInt.asUintN(3, -13n));
assertEquals(2n, BigInt.asUintN(3, -14n));
assertEquals(1n, BigInt.asUintN(3, -15n));
}{
assertEquals(254n, BigInt.asUintN(10, 254n));
assertEquals(255n, BigInt.asUintN(10, 255n));
assertEquals(256n, BigInt.asUintN(10, 256n));
assertEquals(257n, BigInt.asUintN(10, 257n));
assertEquals(510n, BigInt.asUintN(10, 510n));
assertEquals(511n, BigInt.asUintN(10, 511n));
assertEquals(512n, BigInt.asUintN(10, 512n));
assertEquals(513n, BigInt.asUintN(10, 513n));
assertEquals(1022n, BigInt.asUintN(10, 1022n));
assertEquals(1023n, BigInt.asUintN(10, 1023n));
assertEquals(0n, BigInt.asUintN(10, 1024n));
assertEquals(1n, BigInt.asUintN(10, 1025n));
}{
assertEquals(1024n - 254n, BigInt.asUintN(10, -254n));
assertEquals(1024n - 255n, BigInt.asUintN(10, -255n));
assertEquals(1024n - 256n, BigInt.asUintN(10, -256n));
assertEquals(1024n - 257n, BigInt.asUintN(10, -257n));
assertEquals(1024n - 510n, BigInt.asUintN(10, -510n));
assertEquals(1024n - 511n, BigInt.asUintN(10, -511n));
assertEquals(1024n - 512n, BigInt.asUintN(10, -512n));
assertEquals(1024n - 513n, BigInt.asUintN(10, -513n));
assertEquals(1024n - 1022n, BigInt.asUintN(10, -1022n));
assertEquals(1024n - 1023n, BigInt.asUintN(10, -1023n));
assertEquals(0n, BigInt.asUintN(10, -1024n));
assertEquals(1023n, BigInt.asUintN(10, -1025n));
}{
assertEquals(0n, BigInt.asUintN(0, 0n));
assertEquals(0n, BigInt.asUintN(1, 0n));
assertEquals(0n, BigInt.asUintN(16, 0n));
assertEquals(0n, BigInt.asUintN(31, 0n));
assertEquals(0n, BigInt.asUintN(32, 0n));
assertEquals(0n, BigInt.asUintN(33, 0n));
assertEquals(0n, BigInt.asUintN(63, 0n));
assertEquals(0n, BigInt.asUintN(64, 0n));
assertEquals(0n, BigInt.asUintN(65, 0n));
assertEquals(0n, BigInt.asUintN(127, 0n));
assertEquals(0n, BigInt.asUintN(128, 0n));
assertEquals(0n, BigInt.asUintN(129, 0n));
}{
assertEquals(0n, BigInt.asUintN(0, 42n));
assertEquals(0n, BigInt.asUintN(1, 42n));
assertEquals(42n, BigInt.asUintN(16, 42n));
assertEquals(42n, BigInt.asUintN(31, 42n));
assertEquals(42n, BigInt.asUintN(32, 42n));
assertEquals(42n, BigInt.asUintN(33, 42n));
assertEquals(42n, BigInt.asUintN(63, 42n));
assertEquals(42n, BigInt.asUintN(64, 42n));
assertEquals(42n, BigInt.asUintN(65, 42n));
assertEquals(42n, BigInt.asUintN(127, 42n));
assertEquals(42n, BigInt.asUintN(128, 42n));
assertEquals(42n, BigInt.asUintN(129, 42n));
}{
assertEquals(0n, BigInt.asUintN(0, -42n));
assertEquals(0n, BigInt.asUintN(1, -42n));
assertEquals(65536n - 42n, BigInt.asUintN(16, -42n));
assertEquals(2147483648n - 42n, BigInt.asUintN(31, -42n));
assertEquals(4294967296n - 42n, BigInt.asUintN(32, -42n));
assertEquals(8589934592n - 42n, BigInt.asUintN(33, -42n));
assertEquals(9223372036854775808n - 42n, BigInt.asUintN(63, -42n));
assertEquals(18446744073709551616n - 42n, BigInt.asUintN(64, -42n));
assertEquals(36893488147419103232n - 42n, BigInt.asUintN(65, -42n));
assertEquals(2n**127n - 42n, BigInt.asUintN(127, -42n));
assertEquals(2n**128n - 42n, BigInt.asUintN(128, -42n));
assertEquals(2n**129n - 42n, BigInt.asUintN(129, -42n));
}{
assertEquals(0n, BigInt.asUintN(0, 4294967295n));
assertEquals(1n, BigInt.asUintN(1, 4294967295n));
assertEquals(65535n, BigInt.asUintN(16, 4294967295n));
assertEquals(2147483647n, BigInt.asUintN(31, 4294967295n));
assertEquals(4294967295n, BigInt.asUintN(32, 4294967295n));
assertEquals(4294967295n, BigInt.asUintN(33, 4294967295n));
assertEquals(4294967295n, BigInt.asUintN(63, 4294967295n));
assertEquals(4294967295n, BigInt.asUintN(64, 4294967295n));
assertEquals(4294967295n, BigInt.asUintN(65, 4294967295n));
assertEquals(4294967295n, BigInt.asUintN(127, 4294967295n));
assertEquals(4294967295n, BigInt.asUintN(128, 4294967295n));
assertEquals(4294967295n, BigInt.asUintN(129, 4294967295n));
}{
assertEquals(0n, BigInt.asUintN(0, -4294967295n));
assertEquals(1n, BigInt.asUintN(1, -4294967295n));
assertEquals(1n, BigInt.asUintN(16, -4294967295n));
assertEquals(1n, BigInt.asUintN(31, -4294967295n));
assertEquals(1n, BigInt.asUintN(32, -4294967295n));
assertEquals(8589934592n - 4294967295n, BigInt.asUintN(33, -4294967295n));
assertEquals(9223372036854775808n - 4294967295n,
BigInt.asUintN(63, -4294967295n));
assertEquals(18446744073709551616n - 4294967295n,
BigInt.asUintN(64,-4294967295n));
assertEquals(36893488147419103232n - 4294967295n,
BigInt.asUintN(65, -4294967295n));
assertEquals(2n**127n - 4294967295n, BigInt.asUintN(127, -4294967295n));
assertEquals(2n**128n - 4294967295n, BigInt.asUintN(128, -4294967295n));
assertEquals(2n**129n - 4294967295n, BigInt.asUintN(129, -4294967295n));
}{
assertEquals(42n, BigInt.asUintN(2**32, 42n));
assertEquals(4294967295n, BigInt.asUintN(2**32, 4294967295n));
assertEquals(4294967296n, BigInt.asUintN(2**32, 4294967296n));
assertEquals(4294967297n, BigInt.asUintN(2**32, 4294967297n));
}{
assertEquals(0x7234567812345678n, BigInt.asUintN(63, 0xf234567812345678n));
}{
assertThrows(() => BigInt.asUintN(2n, 12n), TypeError);
assertThrows(() => BigInt.asUintN(-1, 0n), RangeError);
assertThrows(() => BigInt.asUintN(2**53, 0n), RangeError);
assertEquals(0n, BigInt.asUintN({}, 12n));
assertEquals(0n, BigInt.asUintN(2.9999, 12n));
assertEquals(4n, BigInt.asUintN(3.1234, 12n));
}{
assertThrows(() => BigInt.asUintN(3, 12), TypeError);
assertEquals(4n, BigInt.asUintN(3, "12"));
}{
// crbug.com/936506
assertEquals(1n, BigInt.asUintN(15, 0x100000001n));
assertEquals(1n, BigInt.asUintN(15, 0x10000000000000001n));
}

View File

@ -0,0 +1,595 @@
// Copyright 2017 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: --allow-natives-syntax
'use strict'
const minus_one = BigInt(-1);
const zero = BigInt(0);
const another_zero = BigInt(0);
const one = BigInt(1);
const another_one = BigInt(1);
const two = BigInt(2);
const three = BigInt(3);
const six = BigInt(6);
// BigInt
{
assertSame(BigInt, BigInt.prototype.constructor)
}{
assertThrows(() => new BigInt, TypeError);
assertThrows(() => new BigInt(), TypeError);
assertThrows(() => new BigInt(0), TypeError);
assertThrows(() => new BigInt(0n), TypeError);
assertThrows(() => new BigInt("0"), TypeError);
}{
class C extends BigInt { constructor() { throw 42 } };
assertThrowsEquals(() => new C, 42);
}
// ToBigInt, NumberToBigInt, BigInt
{
assertThrows(() => BigInt(undefined), TypeError);
assertThrows(() => BigInt(null), TypeError);
assertThrows(() => BigInt({}), SyntaxError);
assertThrows(() => BigInt("foo"), SyntaxError);
assertThrows(() => BigInt("1j"), SyntaxError);
assertThrows(() => BigInt("0b1ju"), SyntaxError);
assertThrows(() => BigInt("0o1jun"), SyntaxError);
assertThrows(() => BigInt("0x1junk"), SyntaxError);
}{
assertSame(BigInt(true), 1n);
assertSame(BigInt(false), 0n);
assertSame(BigInt(""), 0n);
assertSame(BigInt(" 42"), 42n);
assertSame(BigInt("0b101010"), 42n);
assertSame(BigInt(" 0b101011"), 43n);
assertSame(BigInt("0x2a "), 42n);
assertSame(BigInt(" 0x2b"), 43n);
assertSame(BigInt("0o52"), 42n);
assertSame(BigInt(" 0o53\n"), 43n);
assertSame(BigInt(-0), 0n);
assertSame(BigInt(42), 42n);
assertSame(BigInt(42n), 42n);
assertSame(BigInt(Object(42n)), 42n);
assertSame(BigInt(2**53 - 1), 9007199254740991n);
assertSame(BigInt(2**53), 9007199254740992n);
assertSame(BigInt(2**1000), 2n ** 1000n);
assertSame(BigInt(3.0755851989071915e29), 307558519890719151276406341632n);
assertSame(BigInt(-1e50), -0x446c3b15f992680000000000000000000000000000n);
assertSame(BigInt(Object(2**53 - 1)), 9007199254740991n);
assertSame(BigInt([]), 0n);
}{
assertThrows(() => BigInt(NaN), RangeError);
assertThrows(() => BigInt(-Infinity), RangeError);
assertThrows(() => BigInt(+Infinity), RangeError);
assertThrows(() => BigInt(4.00000001), RangeError);
assertThrows(() => BigInt(Object(4.00000001)), RangeError);
}
// BigInt.prototype[Symbol.toStringTag]
{
const toStringTag = Object.getOwnPropertyDescriptor(
BigInt.prototype, Symbol.toStringTag);
assertTrue(toStringTag.configurable);
assertFalse(toStringTag.enumerable);
assertFalse(toStringTag.writable);
assertEquals("BigInt", toStringTag.value);
}
// Object.prototype.toString
{
const toString = Object.prototype.toString;
assertEquals("[object BigInt]", toString.call(42n));
assertEquals("[object BigInt]", toString.call(Object(42n)));
delete BigInt.prototype[Symbol.toStringTag];
assertEquals("[object Object]", toString.call(42n));
assertEquals("[object Object]", toString.call(Object(42n)));
BigInt.prototype[Symbol.toStringTag] = "foo";
assertEquals("[object foo]", toString.call(42n));
assertEquals("[object foo]", toString.call(Object(42n)));
}
// typeof
{
assertEquals(typeof zero, "bigint");
assertEquals(typeof one, "bigint");
}{
assertEquals(%Typeof(zero), "bigint");
assertEquals(%Typeof(one), "bigint");
}{
assertTrue(typeof 1n === "bigint");
assertFalse(typeof 1n === "BigInt");
assertFalse(typeof 1 === "bigint");
}
// ToString
{
assertEquals(String(zero), "0");
assertEquals(String(one), "1");
}
// .toString(radix)
{
// Single-digit BigInts: random-generated inputs close to kMaxInt.
// Expectations computed with the following Python program:
// def Format(x, base):
// s = ""
// while x > 0:
// s = "0123456789abcdefghijklmnopqrstuvwxyz"[x % base] + s
// x = x / base
// return s
assertEquals("10100110000100101000011100101", BigInt(0x14c250e5).toString(2));
assertEquals("-110110100010011111001011111", BigInt(-0x6d13e5f).toString(2));
assertEquals("1001222020000100000", BigInt(0x18c72873).toString(3));
assertEquals("-1212101122110102020", BigInt(-0x2b19aebe).toString(3));
assertEquals("120303133110120", BigInt(0x18cdf518).toString(4));
assertEquals("-113203101020122", BigInt(-0x178d121a).toString(4));
assertEquals("1323302233400", BigInt(0x18de6256).toString(5));
assertEquals("-2301033210212", BigInt(-0x25f7f454).toString(5));
assertEquals("131050115130", BigInt(0x211f0d5e).toString(6));
assertEquals("-104353333321", BigInt(-0x186bbe91).toString(6));
assertEquals("25466260221", BigInt(0x2f69f47e).toString(7));
assertEquals("-31051540346", BigInt(-0x352c7efa).toString(7));
assertEquals("5004630525", BigInt(0x28133155).toString(8));
assertEquals("-7633240703", BigInt(-0x3e6d41c3).toString(8));
assertEquals("705082365", BigInt(0x121f4264).toString(9));
assertEquals("-780654431", BigInt(-0x1443b36e).toString(9));
assertEquals("297019028", BigInt(0x11b42694).toString(10));
assertEquals("-721151126", BigInt(-0x2afbe496).toString(10));
assertEquals("312914074", BigInt(0x27ca6879).toString(11));
assertEquals("-198025592", BigInt(-0x1813d3a7).toString(11));
assertEquals("191370997", BigInt(0x2d14f083).toString(12));
assertEquals("-1b8aab4a2", BigInt(-0x32b52efa).toString(12));
assertEquals("7818062c", BigInt(0x1c84a48c).toString(13));
assertEquals("-7529695b", BigInt(-0x1badffee).toString(13));
assertEquals("6bc929c4", BigInt(0x2b0a91d0).toString(14));
assertEquals("-63042008", BigInt(-0x270dff78).toString(14));
assertEquals("5e8b8dec", BigInt(0x3cd27d7f).toString(15));
assertEquals("-4005433d", BigInt(-0x28c0821a).toString(15));
assertEquals("10b35ca3", BigInt(0x10b35ca3).toString(16));
assertEquals("-23d4d9d6", BigInt(-0x23d4d9d6).toString(16));
assertEquals("28c3d5e3", BigInt(0x3d75d48c).toString(17));
assertEquals("-10c06328", BigInt(-0x1979b7f0).toString(17));
assertEquals("eb8d349", BigInt(0x1dacf0a5).toString(18));
assertEquals("-1217015h", BigInt(-0x28b3c23f).toString(18));
assertEquals("1018520b", BigInt(0x357da01a).toString(19));
assertEquals("-9c64e33", BigInt(-0x1b0e9571).toString(19));
assertEquals("d7bf9ab", BigInt(0x3309daa3).toString(20));
assertEquals("-58h0h9h", BigInt(-0x14c30c55).toString(20));
assertEquals("64igi9h", BigInt(0x1fdd329c).toString(21));
assertEquals("-45cbc4a", BigInt(-0x15cf9682).toString(21));
assertEquals("7bi7d1h", BigInt(0x32f0dfe3).toString(22));
assertEquals("-61j743l", BigInt(-0x291ff61f).toString(22));
assertEquals("5g5gg25", BigInt(0x325a10bd).toString(23));
assertEquals("-3359flb", BigInt(-0x1bb653c9).toString(23));
assertEquals("392f5ec", BigInt(0x267ed69c).toString(24));
assertEquals("-2ab3icb", BigInt(-0x1bbf7bab).toString(24));
assertEquals("3jb2afo", BigInt(0x36f93c24).toString(25));
assertEquals("-30bcheh", BigInt(-0x2bec76fa).toString(25));
assertEquals("3845agk", BigInt(0x3d04bf64).toString(26));
assertEquals("-1gpjl3g", BigInt(-0x1e720b1a).toString(26));
assertEquals("20bpaf0", BigInt(0x2e8ff627).toString(27));
assertEquals("-292i3c2", BigInt(-0x35f751fe).toString(27));
assertEquals("266113k", BigInt(0x3fd26738).toString(28));
assertEquals("-1eh16bo", BigInt(-0x2bb5726c).toString(28));
assertEquals("19gj7qa", BigInt(0x2f28e8d8).toString(29));
assertEquals("-13a0apf", BigInt(-0x278b4588).toString(29));
assertEquals("iasrb8", BigInt(0x1a99b3be).toString(30));
assertEquals("-frlhoc", BigInt(-0x17106f48).toString(30));
assertEquals("bfe4p2", BigInt(0x139f1ea3).toString(31));
assertEquals("-ioal1a", BigInt(-0x200e49fa).toString(31));
assertEquals("m0v0kf", BigInt(0x2c0f828f).toString(32));
assertEquals("-g4bab5", BigInt(-0x2045a965).toString(32));
assertEquals("9i1kit", BigInt(0x16450a9f).toString(33));
assertEquals("-fqb0e7", BigInt(-0x24d9e889).toString(33));
assertEquals("gb9r6m", BigInt(0x2c3acf46).toString(34));
assertEquals("-jcaemv", BigInt(-0x346f72b3).toString(34));
assertEquals("cw4mbk", BigInt(0x2870cdcb).toString(35));
assertEquals("-hw4eki", BigInt(-0x3817c29b).toString(35));
assertEquals("alzwgj", BigInt(0x263e2c13).toString(36));
assertEquals("-bo4ukz", BigInt(-0x2a0f97d3).toString(36));
// Multi-digit BigInts.
// Test parseInt/toString round trip on a list of randomly generated
// string representations of numbers in various bases.
// Userland polyfill while we wait for BigInt.fromString (see:
// https://mathiasbynens.github.io/proposal-number-fromstring/ ).
// This intentionally only implements what the tests below need.
function ParseBigInt(str, radix) {
const alphabet = "0123456789abcdefghijklmnopqrstuvwxyz";
var result = 0n;
var base = BigInt(radix);
var index = 0;
var negative = false;
if (str[0] === "-") {
negative = true;
index++;
}
for (; index < str.length; index++) {
var digit = alphabet.indexOf(str[index]);
assertTrue(digit >= 0 && digit < radix);
result = result * base + BigInt(digit);
}
if (negative) result = -result;
return result;
}
var positive = [0, 0, // Skip base 0 and 1.
"1100110001100010110011110110010010001011100111100101111000111101100001000",
"1001200022210010220101120212021002011002201122200002211102120120021011020",
"1111113020012203332320220022231110130001001320122012131311333110012023232",
"4214313040222110434114402342013144321401424143322013320403411012033300312",
"5025302003542512450341430541203424555035430434034243510233043041501130015",
"6231052230016515343200525230300322104013130605414211331345043144525012021",
"1146340505617030644211355340006353546230356336306352536433054143503442135",
"7262360724624787621528668212168232276348417717770383567066203032200270570",
"7573792356581293501680046955899735043496925151216904903504319328753434194",
"4a627927557579898720a42647639128174a8689889766a219342133671449069a2235011",
"1a574a5848289924996342a32893380690322330393633b587ba5a15b7b82080222400464",
"5163304c74c387b7a443c92466688595b671a3329b42083b1499b0c10a74a9298a06c3a5a",
"4b63c834356a03c80946133284a709cbbc2a75022757207dc31c14abd4c160dc122327c17",
"d8d59cbb4ca2860de7c002eee4ab3c215b90069200d20dbdc0111cb1e1bab97e8c7609670",
"22d4b69398a7f848e6ae36798811cd1a63d90f340d8607f3ce5566c97c18468787eb2b9fd",
"1176gf69afd32cc105fa70c705927a384dbdb1g8d952f28028g31ebdc9e32a89f16e825ee",
"5d64b74f4d70632h4ee07h7c1e2da9125c42g2727f4b6d95e5cec6ga49566hh731ab5f544",
"7ff8cg7f05dd72916a09a4761ii7b0ibcg68ba39b10436f14efg76ge817317badcbi4gffc",
"6d7c4hci6cd72e4ja26j354i12i71gb0cbj12gi145j91h02hde3b72c65geb7ff9bi9d0c2b",
"c96997f50abe425d13a53kk4af631kg7db208ka5j5bfg8ca5f9c0bjf69j5kgg4jb5h7hi86",
"3g5fd800d9ib9j0i8all5jgb23dh9483ab6le5ad9g4kja8a0b3j5jbjfge7k5fffg2kbheee",
"9j1119d1cd61kmdm7kma105cki313f678fc3h25f4664281bbmg3fk97kfbh7d48j89j178ch",
"d2933cdc9jfe4hl3794kb3e13dg2lihad968ib9jg19dgf1fi482b27ji0d10c6kfkdge5764",
"bf6o0njkm1ij5in5nh7h94584bd80el02b07el5ojk9k9g0gn906do70gbbnckl048c0kdmao",
"8gb7jnge9p9cdgigo394oa33gfaenc3gnb53eceg4b8511gkkm88b0dod85e5bggpc861d7d5",
"qbbnqhkpleb4o8ndaddpc34h5b2iljn3jgnjdn5k57bi3n9i09hjle9hqgqdpgbnk499mak56",
"akg7e2976arn8i2m53gif0dp59bmfd7mk9erlg2qm3fc76da9glf397eh4ooij9il0nfl9gac",
"mehpbfrj5ah2ef3p2hl637gjp1pm5grqn4037pm1qfgfpr9cfljfc145hljehjjb48bb1n6en",
"rg6ik3agnb3p6t2rtja9h4il76i8fkqlt6gplap3fq6pfr7bbcfcp5ffncf3nm4kamap39hse",
"bk8rp9r9r8pltdqpb7euc6s9rcm33969pcq6uk3mtfoktt86di8589oacbam5tn29b9b6dq3j",
"npth8juld44rss3e57iigjg65po3d1h02heo4r103jmg3ocv89buqtgiov35k39rdf8j9t4ca",
"vrmqlwrrrd0uml1womae49jpa9tadh44fw7mucgk06l0uk4uqwuo37t6kwn7wwrm3a6oq081s",
"n5cft6gvufqd8iksquu2amghokk17gbtpguidc290af634p7k7rhmfu7bf1s62ej4megoa1j4",
"3v3gcrmlfc2tl0tefgkiogj41f6y2tmj9w5bxke8y03xqf49ox8gh9wbrhycrkluicqajtnur",
"z2m7b0sy2tzergtkqts5yj0dkrlfkxls81ijgxgfequizpntcwggv2d4rdzcncd0kj9mrmnrb",
];
var negative = [0, 0, // Skip base 0 and 1.
"-100010011110111010111111110001100100111010101000001011010010101100101000",
"-110012122000122102021210112200001000122011010120101201001122000002022102",
"-203210320111001002200122200001312300221100221321010300023323201113122333",
"-133042441230110320040323303341320302144241224443231311022240124413104131",
"-311325230504055004330150145105331121322231155401110315251422505233103112",
"-643153641664240231336166403516403454646560261062114326443664602606315326",
"-200057252627665476551635525303641543165622340301637556323453513664337277",
"-826688166214270516331644053744613530235020517172322840763172114078364165",
"-743042397390679269240157150971957535458122650450558451124173993544604852",
"-73528688500003573942a56a504a2996a1384129563098512a63196697975038692aaa63",
"-616576a2948a9029316290168b71137b027851639a0283150b125b664b74b767a3597805",
"-b875467540719b371b7a36047a7886872a5399c4c630c37149bc3182917a7a7c124475bb",
"-3860411b61d35977721bc81bd715c386c9b70a752940913d265505d8c7c5dd2624b591d7",
"-bad5dd79b083ee0da9a6296664e72c246d827762357116ae7076a22bb369acbc3a201d03",
"-f9b37352aff265124303942a463917a252ff1a2ff4a33777f490b4c103bdcd1a655dbe2c",
"-805fg8c74125214g383a8d8g573c49fa7c4035fbc6db61g5gb5g6beb8f90dae4a9a5g7cc",
"-70aae113459d3h5084b1gg209g3695d20e78d01gcbb71bh1bd4gdge31haf5hc02dghf14e",
"-c55a57haf47b7ih2gh6ea93098ig02b42icga6ead254e0aeeic7g53h5fd6637ge03b2e20",
"-e32f7204624ie596j731g72136cejc25ebbgb0140i4997fcdf477f021d86ci4e10db543a",
"-i7f32c817i3cac1c24c7786k6ig185f47cj1471ki6bb7agiae838027gjge9g59if9f88g6",
"-i30aha2030a9605c270h92e1ca3i02j996hl918gh52fbhb7i16ik1i919ieak3cj384kb61",
"-58jmem8e59li67aellid2083dabh4kh51ci1jg7c6a3k4l1hdgfkdha0fglfm4805kida5b9",
"-cl9iecjg9ak087cad4151lll44296heae2349g70fbjj37998m2ddn6427fgcl2aknhgn1a1",
"-alfjfhho4gf8bi4j2bi3743mhg2aache4c6jcinkmf5ddm7kf9gg350hlja16ealbdlk201j",
"-bhh1146ho3o2m3b839c565hbgjnhjh96oofbmdl7gn8h4f94kli94hkk180o79pc4d2l0721",
"-p00gknh7e05k6a3apg6i9lb46f4a9qeeiq1778ak8il5dcponk5gl2fiednb4pmo1agmoqph",
"-4j8lo4d4p508fnd2hkfb76e8ri81k6hq0op3pr14ca0cn96pccplk7rbahc9cdkdce1q16dn",
"-ednlo3ogf2i8annrel9rm323bpf00meed3oi47n0qrdgnd2n3il4bnsc9s2jd7loh44im8ra",
"-bjjg6fsbpcc2tc1o09m9r6fd6eoq5480har62a5offn9thcfahbno9kf9magl2akl0jgncj9",
"-sonuhat2h60glpbpej9jjado2s5l86122d26tudoc1d6aic2oitu793gk0mlac3dk1dufp1q",
"-i9pbvm53ubh8jqifuarauch8cbgk9cjsl6rlioka1phs1lskg1oosll23hjoli2subgr1rto",
"-w1ncn5t60b5dv669ekwnvk8n2g7djrsl8cdkwun8o3m5divc3jhnkp2381rhj70gc71a6wff",
"-buiq8v33p5ex44ps4s45enj6lrluivm19lcowkvntu72u0xguw13bxgxxe7mdlwt1a4qksae",
"-woiycfmea6i12r2yai49mf4lbd7w2jdoebiogfhnh1i4rwgox57obci8qbsfpb4w07nu19m5",
"-tbttuip1r6ioca6g6dw354o4m78qep9yh03nojx47yq29fqime6zstwllb74501qct8eskxn",
];
for (var base = 2; base <= 36; base++) {
var input = positive[base];
assertEquals(input, ParseBigInt(input, base).toString(base));
input = negative[base];
assertEquals(input, ParseBigInt(input, base).toString(base));
}
}
// .valueOf
{
assertEquals(Object(zero).valueOf(), another_zero);
assertThrows(() => { return BigInt.prototype.valueOf.call("string"); },
TypeError);
assertEquals(-42n, Object(-42n).valueOf());
}
// ToBoolean
{
assertTrue(!zero);
assertFalse(!!zero);
assertTrue(!!!zero);
assertFalse(!one);
assertTrue(!!one);
assertFalse(!!!one);
// This is a hack to test Object::BooleanValue.
assertTrue(%CreateIterResultObject(42, one).done);
assertFalse(%CreateIterResultObject(42, zero).done);
}
// ToNumber
{
assertThrows(() => isNaN(zero), TypeError);
assertThrows(() => isNaN(one), TypeError);
assertThrows(() => +zero, TypeError);
assertThrows(() => +one, TypeError);
}
{
let Zero = {valueOf() { return zero }};
let One = {valueOf() { return one }};
assertThrows(() => isNaN(Zero), TypeError);
assertThrows(() => isNaN(One), TypeError);
assertThrows(() => +Zero, TypeError);
assertThrows(() => +One, TypeError);
}{
let Zero = {valueOf() { return Object(NaN) }, toString() { return zero }};
let One = {valueOf() { return one }, toString() { return NaN }};
assertThrows(() => isNaN(Zero), TypeError);
assertThrows(() => isNaN(One), TypeError);
assertThrows(() => +Zero, TypeError);
assertThrows(() => +One, TypeError);
}
// ToObject
{
const ToObject = x => (new Function("", "return this")).call(x);
function test(x) {
const X = ToObject(x);
assertEquals(typeof x, "bigint");
assertEquals(typeof X, 'object');
assertEquals(X.constructor, BigInt);
assertTrue(X == x);
}
test(0n);
test(-1n);
test(1n);
test(2343423423423423423424234234234235234524353453452345324523452345234534n);
}{
function test(x) {
const X = Object(x);
assertEquals(typeof x, "bigint");
assertEquals(typeof X, 'object');
assertEquals(X.constructor, BigInt);
assertTrue(X == x);
}
test(0n);
test(-1n);
test(1n);
test(2343423423423423423424234234234235234524353453452345324523452345234534n);
}
// Literals
{
// Invalid literals.
assertThrows("00n", SyntaxError);
assertThrows("01n", SyntaxError);
assertThrows("0bn", SyntaxError);
assertThrows("0on", SyntaxError);
assertThrows("0xn", SyntaxError);
assertThrows("1.n", SyntaxError);
assertThrows("1.0n", SyntaxError);
assertThrows("1e25n", SyntaxError);
// Various radixes.
assertTrue(12345n === BigInt(12345));
assertTrue(0xabcden === BigInt(0xabcde));
assertTrue(0xAbCdEn === BigInt(0xabcde));
assertTrue(0o54321n === BigInt(0o54321));
assertTrue(0b1010101n === BigInt(0b1010101));
}
// Binary ops.
{
let One = {valueOf() { return one }};
assertTrue(one + two === three);
assertTrue(One + two === three);
assertTrue(two + One === three);
assertEquals("hello1", "hello" + one);
assertEquals("2hello", two + "hello");
assertThrows("one + 2", TypeError);
assertThrows("2 + one", TypeError);
assertThrows("one + 0.5", TypeError);
assertThrows("0.5 + one", TypeError);
assertThrows("one + null", TypeError);
assertThrows("null + one", TypeError);
assertTrue(three - two === one);
assertThrows("two - 1", TypeError);
assertThrows("2 - one", TypeError);
assertThrows("two - 0.5", TypeError);
assertThrows("2.5 - one", TypeError);
assertTrue(two * three === six);
assertTrue(two * One === two);
assertTrue(One * two === two);
assertThrows("two * 1", TypeError);
assertThrows("1 * two", TypeError);
assertThrows("two * 1.5", TypeError);
assertThrows("1.5 * two", TypeError);
assertTrue(six / three === two);
assertThrows("six / 3", TypeError);
assertThrows("3 / three", TypeError);
assertThrows("six / 0.5", TypeError);
assertThrows("0.5 / six", TypeError);
assertThrows("zero / zero", RangeError);
assertThrows("zero / 0", TypeError);
assertTrue(three % two === one);
assertThrows("three % 2", TypeError);
assertThrows("3 % two", TypeError);
assertThrows("three % 2.5", TypeError);
assertThrows("3.5 % two", TypeError);
assertThrows("three % zero", RangeError);
assertThrows("three % 0", TypeError);
}
// Bitwise binary ops.
{
let One = {valueOf() { return one }};
assertTrue((three & one) === one);
assertTrue((BigInt(-2) & zero) === zero);
assertTrue((three & One) === one);
assertTrue((One & three) === one);
assertThrows("three & 1", TypeError);
assertThrows("1 & three", TypeError);
assertThrows("three & true", TypeError);
assertThrows("true & three", TypeError);
assertThrows("three & {valueOf: function() { return 1; }}", TypeError);
assertThrows("({valueOf: function() { return 1; }}) & three", TypeError);
assertTrue((two | one) === three);
assertThrows("two | 0", TypeError);
assertThrows("0 | two", TypeError);
assertThrows("two | undefined", TypeError);
assertThrows("undefined | two", TypeError);
assertTrue((three ^ one) === two);
assertThrows("three ^ 1", TypeError);
assertThrows("1 ^ three", TypeError);
assertThrows("three ^ 2.5", TypeError);
assertThrows("2.5 ^ three", TypeError);
}
// Shift ops.
{
assertTrue(one << one === two);
assertThrows("one << 1", TypeError);
assertThrows("1 << one", TypeError);
assertThrows("one << true", TypeError);
assertThrows("true << one", TypeError);
assertTrue(three >> one === one);
assertThrows("three >> 1", TypeError);
assertThrows("0xbeef >> one", TypeError);
assertThrows("three >> 1.5", TypeError);
assertThrows("23.45 >> three", TypeError);
assertThrows("three >>> one", TypeError);
assertThrows("three >>> 1", TypeError);
assertThrows("0xbeef >>> one", TypeError);
assertThrows("three >>> {valueOf: function() { return 1; }}", TypeError);
assertThrows("({valueOf: function() { return 1; }}) >>> one", TypeError);
}
// Unary ops.
{
let One = {valueOf() { return one }};
assertTrue(~minus_one === zero);
assertTrue(-minus_one === one);
assertTrue(-One === minus_one);
assertTrue(~~two === two);
assertTrue(-(-two) === two);
assertTrue(~One === BigInt(-2));
let a = minus_one;
assertTrue(a++ === minus_one);
assertTrue(a === zero);
assertTrue(a++ === zero);
assertTrue(a === one);
assertTrue(++a === two);
assertTrue(a === two);
assertTrue(--a === one);
assertTrue(a === one);
assertTrue(a-- === one);
assertTrue(a === zero);
assertTrue(a-- === zero);
assertTrue(a === minus_one);
a = {valueOf() { return minus_one }};
assertTrue(a++ === minus_one);
assertTrue(a++ === zero);
assertTrue(a === one);
a = {valueOf() { return one }};
assertTrue(a-- === one);
assertTrue(a-- === zero);
assertTrue(a === minus_one);
}
// ToPropertyKey
{
let obj = {};
assertEquals(obj[0n], undefined);
assertEquals(obj[0n] = 42, 42);
assertEquals(obj[0n], 42);
assertEquals(obj[0], 42);
obj[0]++;
assertEquals(obj[1n - 1n], 43);
assertEquals(Reflect.get(obj, -0n), 43);
assertEquals(obj[{toString() {return 0n}}], 43);
assertEquals(Reflect.ownKeys(obj), ["0"]);
}{
let obj = {};
const unsafe = 9007199254740993n;
assertEquals(obj[unsafe] = 23, 23);
assertEquals(obj[unsafe], 23);
assertEquals(Reflect.ownKeys(obj), ["9007199254740993"]);
assertEquals(obj[9007199254740993], undefined);
delete obj[unsafe];
assertEquals(Reflect.ownKeys(obj), []);
}{
let arr = [];
assertFalse(4n in arr);
arr[4n] = 42;
assertTrue(4n in arr);
let enumkeys = 0;
for (const key in arr) {
enumkeys++;
assertSame(key, "4");
}
assertEquals(enumkeys, 1);
}{
let str = "blubb";
assertEquals(str[2n], "u");
assertThrows(() => str.slice(2n), TypeError);
}{
let obj = {};
let key = 0;
function set_key(x) { obj[key] = x }
set_key("aaa");
set_key("bbb");
key = 0n;
set_key("ccc");
assertEquals(obj[key], "ccc");
function get_key() { return obj[key] }
assertEquals(get_key(), "ccc");
assertEquals(get_key(), "ccc");
key = 0;
assertEquals(get_key(), "ccc");
}{
assertSame(%ToName(0n), "0");
assertSame(%ToName(-0n), "0");
const unsafe = 9007199254740993n;
assertSame(%ToName(unsafe), "9007199254740993");
}

View File

@ -0,0 +1,501 @@
// Copyright 2017 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: --allow-natives-syntax
'use strict'
const minus_one = BigInt(-1);
const zero = BigInt(0);
const another_zero = BigInt(0);
const one = BigInt(1);
const another_one = BigInt(1);
const two = BigInt(2);
const three = BigInt(3);
const six = BigInt(6);
// Strict equality
{
assertTrue(zero === zero);
assertFalse(zero !== zero);
assertTrue(zero === another_zero);
assertFalse(zero !== another_zero);
assertFalse(zero === one);
assertTrue(zero !== one);
assertTrue(one !== zero);
assertFalse(one === zero);
assertFalse(zero === 0);
assertTrue(zero !== 0);
assertFalse(0 === zero);
assertTrue(0 !== zero);
}{
assertTrue(%StrictEqual(zero, zero));
assertFalse(%StrictNotEqual(zero, zero));
assertTrue(%StrictEqual(zero, another_zero));
assertFalse(%StrictNotEqual(zero, another_zero));
assertFalse(%StrictEqual(zero, one));
assertTrue(%StrictNotEqual(zero, one));
assertTrue(%StrictNotEqual(one, zero));
assertFalse(%StrictEqual(one, zero));
assertFalse(%StrictEqual(zero, 0));
assertTrue(%StrictNotEqual(zero, 0));
assertFalse(%StrictEqual(0, zero));
assertTrue(%StrictNotEqual(0, zero));
}
// Abstract equality
{
assertTrue(%Equal(zero, zero));
assertTrue(%Equal(zero, another_zero));
assertFalse(%Equal(zero, one));
assertFalse(%Equal(one, zero));
assertTrue(%Equal(zero, +0));
assertTrue(%Equal(zero, -0));
assertTrue(%Equal(+0, zero));
assertTrue(%Equal(-0, zero));
assertTrue(%Equal(zero, false));
assertTrue(%Equal(one, true));
assertFalse(%Equal(zero, true));
assertFalse(%Equal(one, false));
assertTrue(%Equal(false, zero));
assertTrue(%Equal(true, one));
assertFalse(%Equal(true, zero));
assertFalse(%Equal(false, one));
assertTrue(%Equal(one, 1));
assertTrue(%Equal(one, Number(1)));
assertTrue(%Equal(1, one));
assertTrue(%Equal(Number(1), one));
assertTrue(%Equal(minus_one, -1));
assertTrue(%Equal(minus_one, Number(-1)));
assertTrue(%Equal(-1, minus_one));
assertTrue(%Equal(Number(-1), minus_one));
assertFalse(%Equal(one, -1));
assertFalse(%Equal(one, Number(-1)));
assertFalse(%Equal(-1, one));
assertFalse(%Equal(Number(-1), one));
assertFalse(%Equal(one, 1.0000000000001));
assertFalse(%Equal(1.0000000000001, one));
assertTrue(%Equal(zero, ""));
assertTrue(%Equal("", zero));
assertTrue(%Equal(one, "1"));
assertTrue(%Equal("1", one));
assertFalse(%Equal(one, "a"));
assertFalse(%Equal("a", one));
assertTrue(%Equal(one, {valueOf() { return true }}));
assertTrue(%Equal({valueOf() { return true }}, one));
assertFalse(%Equal(two, {valueOf() { return true }}));
assertFalse(%Equal({valueOf() { return true }}, two));
assertFalse(%Equal(Symbol(), zero));
assertFalse(%Equal(zero, Symbol()));
}{
assertTrue(zero == zero);
assertTrue(zero == another_zero);
assertFalse(zero == one);
assertFalse(one == zero);
assertTrue(zero == +0);
assertTrue(zero == -0);
assertTrue(+0 == zero);
assertTrue(-0 == zero);
assertTrue(zero == false);
assertTrue(one == true);
assertFalse(zero == true);
assertFalse(one == false);
assertTrue(false == zero);
assertTrue(true == one);
assertFalse(true == zero);
assertFalse(false == one);
assertTrue(one == 1);
assertTrue(one == Number(1));
assertTrue(1 == one);
assertTrue(Number(1) == one);
assertTrue(minus_one == -1);
assertTrue(minus_one == Number(-1));
assertTrue(-1 == minus_one);
assertTrue(Number(-1) == minus_one);
assertFalse(one == -1);
assertFalse(one == Number(-1));
assertFalse(-1 == one);
assertFalse(Number(-1) == one);
assertFalse(one == 1.0000000000001);
assertFalse(1.0000000000001 == one);
assertTrue(zero == "");
assertTrue("" == zero);
assertTrue(zero == " \t\r\n");
assertTrue(one == "1");
assertTrue("1" == one);
assertFalse(" \t\r\n" == one);
assertFalse(one == "a");
assertFalse("a" == one);
assertTrue(zero == "00000000000000" + "0");
assertTrue(one == {valueOf() { return true }});
assertTrue({valueOf() { return true }} == one);
assertFalse(two == {valueOf() { return true }});
assertFalse({valueOf() { return true }} == two);
assertFalse(Symbol() == zero);
assertFalse(zero == Symbol());
assertTrue(one == "0b1");
assertTrue(" 0b1" == one);
assertTrue(one == "0o1");
assertTrue("0o1 " == one);
assertTrue(one == "\n0x1");
assertTrue("0x1" == one);
assertFalse(one == "1j");
assertFalse(one == "0b1ju");
assertFalse(one == "0o1jun");
assertFalse(one == "0x1junk");
}{
assertFalse(%NotEqual(zero, zero));
assertFalse(%NotEqual(zero, another_zero));
assertTrue(%NotEqual(zero, one));
assertTrue(%NotEqual(one, zero));
assertFalse(%NotEqual(zero, +0));
assertFalse(%NotEqual(zero, -0));
assertFalse(%NotEqual(+0, zero));
assertFalse(%NotEqual(-0, zero));
assertFalse(%NotEqual(zero, false));
assertFalse(%NotEqual(one, true));
assertTrue(%NotEqual(zero, true));
assertTrue(%NotEqual(one, false));
assertFalse(%NotEqual(false, zero));
assertFalse(%NotEqual(true, one));
assertTrue(%NotEqual(true, zero));
assertTrue(%NotEqual(false, one));
assertFalse(%NotEqual(one, 1));
assertFalse(%NotEqual(one, Number(1)));
assertFalse(%NotEqual(1, one));
assertFalse(%NotEqual(Number(1), one));
assertFalse(%NotEqual(minus_one, -1));
assertFalse(%NotEqual(minus_one, Number(-1)));
assertFalse(%NotEqual(-1, minus_one));
assertFalse(%NotEqual(Number(-1), minus_one));
assertTrue(%NotEqual(one, -1));
assertTrue(%NotEqual(one, Number(-1)));
assertTrue(%NotEqual(-1, one));
assertTrue(%NotEqual(Number(-1), one));
assertTrue(%NotEqual(one, 1.0000000000001));
assertTrue(%NotEqual(1.0000000000001, one));
assertFalse(%NotEqual(zero, ""));
assertFalse(%NotEqual("", zero));
assertFalse(%NotEqual(one, "1"));
assertFalse(%NotEqual("1", one));
assertTrue(%NotEqual(one, "a"));
assertTrue(%NotEqual("a", one));
assertFalse(%NotEqual(one, {valueOf() { return true }}));
assertFalse(%NotEqual({valueOf() { return true }}, one));
assertTrue(%NotEqual(two, {valueOf() { return true }}));
assertTrue(%NotEqual({valueOf() { return true }}, two));
assertTrue(%NotEqual(Symbol(), zero));
assertTrue(%NotEqual(zero, Symbol()));
}{
assertFalse(zero != zero);
assertFalse(zero != another_zero);
assertTrue(zero != one);
assertTrue(one != zero);
assertFalse(zero != +0);
assertFalse(zero != -0);
assertFalse(+0 != zero);
assertFalse(-0 != zero);
assertFalse(zero != false);
assertFalse(one != true);
assertTrue(zero != true);
assertTrue(one != false);
assertFalse(false != zero);
assertFalse(true != one);
assertTrue(true != zero);
assertTrue(false != one);
assertFalse(one != 1);
assertFalse(one != Number(1));
assertFalse(1 != one);
assertFalse(Number(1) != one);
assertFalse(minus_one != -1);
assertFalse(minus_one != Number(-1));
assertFalse(-1 != minus_one);
assertFalse(Number(-1) != minus_one);
assertTrue(one != -1);
assertTrue(one != Number(-1));
assertTrue(-1 != one);
assertTrue(Number(-1) != one);
assertTrue(one != 1.0000000000001);
assertTrue(1.0000000000001 != one);
assertFalse(zero != "");
assertFalse("" != zero);
assertFalse(one != "1");
assertFalse("1" != one);
assertTrue(one != "a");
assertTrue("a" != one);
assertFalse(one != {valueOf() { return true }});
assertFalse({valueOf() { return true }} != one);
assertTrue(two != {valueOf() { return true }});
assertTrue({valueOf() { return true }} != two);
assertTrue(Symbol() != zero);
assertTrue(zero != Symbol());
}
// SameValue
{
assertTrue(Object.is(zero, zero));
assertTrue(Object.is(zero, another_zero));
assertTrue(Object.is(one, one));
assertTrue(Object.is(one, another_one));
assertFalse(Object.is(zero, +0));
assertFalse(Object.is(zero, -0));
assertFalse(Object.is(+0, zero));
assertFalse(Object.is(-0, zero));
assertFalse(Object.is(zero, one));
assertFalse(Object.is(one, minus_one));
}{
const obj = Object.defineProperty({}, 'foo',
{value: zero, writable: false, configurable: false});
assertTrue(Reflect.defineProperty(obj, 'foo', {value: zero}));
assertTrue(Reflect.defineProperty(obj, 'foo', {value: another_zero}));
assertFalse(Reflect.defineProperty(obj, 'foo', {value: one}));
}
// SameValueZero
{
assertTrue([zero].includes(zero));
assertTrue([zero].includes(another_zero));
assertFalse([zero].includes(+0));
assertFalse([zero].includes(-0));
assertFalse([+0].includes(zero));
assertFalse([-0].includes(zero));
assertTrue([one].includes(one));
assertTrue([one].includes(another_one));
assertFalse([one].includes(1));
assertFalse([1].includes(one));
}{
assertTrue(new Set([zero]).has(zero));
assertTrue(new Set([zero]).has(another_zero));
assertFalse(new Set([zero]).has(+0));
assertFalse(new Set([zero]).has(-0));
assertFalse(new Set([+0]).has(zero));
assertFalse(new Set([-0]).has(zero));
assertTrue(new Set([one]).has(one));
assertTrue(new Set([one]).has(another_one));
}{
assertTrue(new Map([[zero, 42]]).has(zero));
assertTrue(new Map([[zero, 42]]).has(another_zero));
assertFalse(new Map([[zero, 42]]).has(+0));
assertFalse(new Map([[zero, 42]]).has(-0));
assertFalse(new Map([[+0, 42]]).has(zero));
assertFalse(new Map([[-0, 42]]).has(zero));
assertTrue(new Map([[one, 42]]).has(one));
assertTrue(new Map([[one, 42]]).has(another_one));
}
// Abstract comparison
{
let undef = Symbol();
assertTrue(%Equal(zero, zero));
assertTrue(%GreaterThanOrEqual(zero, zero));
assertTrue(%LessThan(zero, one));
assertTrue(%GreaterThan(one, zero));
assertTrue(%LessThan(minus_one, one));
assertTrue(%GreaterThan(one, minus_one));
assertTrue(%Equal(zero, -0));
assertTrue(%LessThanOrEqual(zero, -0));
assertTrue(%GreaterThanOrEqual(zero, -0));
assertTrue(%Equal(-0, zero));
assertTrue(%LessThanOrEqual(-0, zero));
assertTrue(%GreaterThanOrEqual(-0, zero));
assertTrue(%Equal(zero, 0));
assertTrue(%Equal(0, zero));
assertTrue(%LessThan(minus_one, 1));
assertTrue(%GreaterThan(1, minus_one));
assertFalse(%LessThan(six, NaN));
assertFalse(%GreaterThan(six, NaN));
assertFalse(%Equal(six, NaN));
assertFalse(%LessThan(NaN, six));
assertFalse(%GreaterThan(NaN, six));
assertFalse(%Equal(NaN, six));
assertTrue(%LessThan(six, Infinity));
assertTrue(%GreaterThan(Infinity, six));
assertTrue(%GreaterThan(six, -Infinity));
assertTrue(%LessThan(-Infinity, six));
assertTrue(%GreaterThan(six, 5.99999999));
assertTrue(%LessThan(5.99999999, six));
assertTrue(%Equal(zero, ""));
assertTrue(%LessThanOrEqual(zero, ""));
assertTrue(%GreaterThanOrEqual(zero, ""));
assertTrue(%Equal("", zero));
assertTrue(%LessThanOrEqual("", zero));
assertTrue(%GreaterThanOrEqual("", zero));
assertTrue(%Equal(minus_one, "\t-1 "));
assertTrue(%LessThanOrEqual(minus_one, "\t-1 "));
assertTrue(%GreaterThanOrEqual(minus_one, "\t-1 "));
assertTrue(%Equal("\t-1 ", minus_one));
assertTrue(%LessThanOrEqual("\t-1 ", minus_one));
assertTrue(%GreaterThanOrEqual("\t-1 ", minus_one));
assertFalse(%LessThan(minus_one, "-0x1"));
assertFalse(%GreaterThan(minus_one, "-0x1"));
assertFalse(%Equal(minus_one, "-0x1"));
assertFalse(%LessThan("-0x1", minus_one));
assertFalse(%GreaterThan("-0x1", minus_one));
assertFalse(%Equal("-0x1", minus_one));
const unsafe = "9007199254740993"; // 2**53 + 1
assertFalse(%GreaterThan(eval(unsafe + "n"), unsafe));
assertFalse(%LessThan(unsafe, eval(unsafe + "n")));
assertThrows(() => %LessThan(six, Symbol(6)), TypeError);
assertThrows(() => %LessThan(Symbol(6), six), TypeError);
var value_five_string_six = {
valueOf() { return Object(5); },
toString() { return 6; }
};
assertTrue(%LessThanOrEqual(six, value_five_string_six));
assertTrue(%GreaterThanOrEqual(six, value_five_string_six));
assertTrue(%LessThanOrEqual(value_five_string_six, six));
assertTrue(%GreaterThanOrEqual(value_five_string_six, six));
}{
assertFalse(zero < zero);
assertTrue(zero <= zero);
assertTrue(zero < one);
assertTrue(zero <= one);
assertFalse(one < zero);
assertFalse(one <= zero);
assertTrue(minus_one < one);
assertTrue(minus_one <= one);
assertFalse(one < minus_one);
assertFalse(one <= minus_one);
assertFalse(zero < -0);
assertTrue(zero <= -0);
assertFalse(-0 < zero);
assertTrue(-0 <= zero);
assertFalse(zero < 0);
assertTrue(zero <= 0);
assertFalse(0 < zero);
assertTrue(0 <= zero);
assertTrue(minus_one < 1);
assertTrue(minus_one <= 1);
assertFalse(1 < minus_one);
assertFalse(1 <= minus_one);
assertFalse(six < NaN);
assertFalse(six <= NaN);
assertFalse(NaN < six);
assertFalse(NaN <= six);
assertTrue(six < Infinity);
assertTrue(six <= Infinity);
assertFalse(Infinity < six);
assertFalse(Infinity <= six);
assertFalse(six < -Infinity);
assertFalse(six <= -Infinity);
assertTrue(-Infinity < six);
assertTrue(-Infinity <= six);
assertFalse(six < 5.99999999);
assertFalse(six <= 5.99999999);
assertTrue(5.99999999 < six);
assertTrue(5.99999999 <= six);
assertFalse(zero < "");
assertTrue(zero <= "");
assertFalse("" < zero);
assertTrue("" <= zero);
assertFalse(minus_one < "\t-1 ");
assertTrue(minus_one <= "\t-1 ");
assertFalse("\t-1 " < minus_one);
assertTrue("\t-1 " <= minus_one);
assertFalse(minus_one < "-0x1");
assertFalse(minus_one <= "-0x1");
assertFalse("-0x1" < minus_one);
assertFalse("-0x1" <= minus_one);
const unsafe = "9007199254740993"; // 2**53 + 1
assertFalse(eval(unsafe + "n") < unsafe);
assertTrue(eval(unsafe + "n") <= unsafe);
assertFalse(unsafe < eval(unsafe + "n"));
assertTrue(unsafe <= eval(unsafe + "n"));
assertThrows(() => six < Symbol(6), TypeError);
assertThrows(() => six <= Symbol(6), TypeError);
assertThrows(() => Symbol(6) < six, TypeError);
assertThrows(() => Symbol(6) <= six, TypeError);
assertFalse(six < {valueOf() {return Object(5)}, toString() {return 6}});
assertTrue(six <= {valueOf() {return Object(5)}, toString() {return 6}});
assertFalse({valueOf() {return Object(5)}, toString() {return 6}} < six);
assertTrue({valueOf() {return Object(5)}, toString() {return 6}} <= six);
}

View File

@ -0,0 +1,86 @@
// Copyright 2018 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.
var buffer = new ArrayBuffer(64);
var dataview = new DataView(buffer, 8, 24);
var bytes = new Uint8Array(buffer);
var b1 = 0xff1234567890abcdefn;
var b1_64 = BigInt.asUintN(64, b1);
dataview.setBigInt64(8, b1);
assertEquals(0x12, bytes[16]);
assertEquals(0x34, bytes[17]);
assertEquals(0x56, bytes[18]);
assertEquals(0x78, bytes[19]);
assertEquals(0x90, bytes[20]);
assertEquals(0xab, bytes[21]);
assertEquals(0xcd, bytes[22]);
assertEquals(0xef, bytes[23]);
assertEquals(b1_64, dataview.getBigInt64(8));
dataview.setBigInt64(8, b1, true); // Little-endian.
assertEquals(0xef, bytes[16]);
assertEquals(0xcd, bytes[17]);
assertEquals(0xab, bytes[18]);
assertEquals(0x90, bytes[19]);
assertEquals(0x78, bytes[20]);
assertEquals(0x56, bytes[21]);
assertEquals(0x34, bytes[22]);
assertEquals(0x12, bytes[23]);
assertEquals(b1_64, dataview.getBigInt64(8, true));
dataview.setBigUint64(8, b1);
assertEquals(0x12, bytes[16]);
assertEquals(0x34, bytes[17]);
assertEquals(0x56, bytes[18]);
assertEquals(0x78, bytes[19]);
assertEquals(0x90, bytes[20]);
assertEquals(0xab, bytes[21]);
assertEquals(0xcd, bytes[22]);
assertEquals(0xef, bytes[23]);
assertEquals(b1_64, dataview.getBigUint64(8));
dataview.setBigUint64(8, b1, true); // Little-endian.
assertEquals(0xef, bytes[16]);
assertEquals(0xcd, bytes[17]);
assertEquals(0xab, bytes[18]);
assertEquals(0x90, bytes[19]);
assertEquals(0x78, bytes[20]);
assertEquals(0x56, bytes[21]);
assertEquals(0x34, bytes[22]);
assertEquals(0x12, bytes[23]);
assertEquals(b1_64, dataview.getBigUint64(8, true));
var b2 = -0x76543210fedcba98n;
dataview.setBigInt64(8, b2, true);
assertEquals(0x68, bytes[16]);
assertEquals(0x45, bytes[17]);
assertEquals(0x23, bytes[18]);
assertEquals(0x01, bytes[19]);
assertEquals(0xef, bytes[20]);
assertEquals(0xcd, bytes[21]);
assertEquals(0xab, bytes[22]);
assertEquals(0x89, bytes[23]);
assertEquals(b2, dataview.getBigInt64(8, true));
assertEquals(0x89abcdef01234568n, dataview.getBigUint64(8, true));
var b3 = -0x8000000000000000n; // The int64_t minimum value.
dataview.setBigInt64(8, b3);
assertEquals(b3, dataview.getBigInt64(8));
assertEquals(-b3, dataview.getBigUint64(8));
var b4 = 0x8000000000000000n;
dataview.setBigInt64(8, b4);
assertEquals(-b4, dataview.getBigInt64(8));
assertEquals(b4, dataview.getBigUint64(8));
assertThrows(() => dataview.setBigInt64(0, 1), TypeError);
assertThrows(() => dataview.setBigUint64(0, 1), TypeError);
assertThrows(() => dataview.setInt32(0, 1n), TypeError);
assertThrows(() => dataview.setUint32(0, 1n), TypeError);
// None of the stores wrote out of bounds.
for (var i = 0; i < 16; i++) assertEquals(0, bytes[i]);
for (var i = 24; i < 64; i++) assertEquals(0, bytes[i]);

View File

@ -0,0 +1,83 @@
// Copyright 2017 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.
// Generated by tools/bigint-tester.py.
var data = [{
a: 0x26ffcdbd233a53e7ca4612f2b02e1f2c1d885c3177e7n,
r: 0x26ffcdbd233a53e7ca4612f2b02e1f2c1d885c3177e6n
}, {
a: 0xf2a29a35193377a223ef0d6d98db95eeb24a4165f288fd2b4an,
r: 0xf2a29a35193377a223ef0d6d98db95eeb24a4165f288fd2b49n
}, {
a: 0x454d22e29e6104n,
r: 0x454d22e29e6103n
}, {
a: -0xb00874640d30e6fce6bf79508378ed17e44dacb48a4200bce536cec462b3c2n,
r: -0xb00874640d30e6fce6bf79508378ed17e44dacb48a4200bce536cec462b3c3n
}, {
a: 0x4c151a24d765249c2bab4a1915b24b80ae437417c5n,
r: 0x4c151a24d765249c2bab4a1915b24b80ae437417c4n
}, {
a: -0xcbd476b1f9ca08ff820941n,
r: -0xcbd476b1f9ca08ff820942n
}, {
a: -0xe848e5830fa1035322b39c2cdd031109ca8n,
r: -0xe848e5830fa1035322b39c2cdd031109ca9n
}, {
a: -0x4d58c5e190f0ebac5bb36ca4d214069f69726c63a5n,
r: -0x4d58c5e190f0ebac5bb36ca4d214069f69726c63a6n
}, {
a: 0x9b396n,
r: 0x9b395n
}, {
a: 0x593921fe8b9d4906cn,
r: 0x593921fe8b9d4906bn
}, {
a: -0xe127928c7cecd6e9ca94d98e858f9c76a0fccac62203aac7710cef1f9e352n,
r: -0xe127928c7cecd6e9ca94d98e858f9c76a0fccac62203aac7710cef1f9e353n
}, {
a: 0xeb14cd952d06eb6fc613016f73b7339cbdd010n,
r: 0xeb14cd952d06eb6fc613016f73b7339cbdd00fn
}, {
a: -0xfdeab6a3dbd603137f680413fecc9e1c80n,
r: -0xfdeab6a3dbd603137f680413fecc9e1c81n
}, {
a: -0x7e9abbdfad170df2129dae8e15088a02b9ba99276a351a05n,
r: -0x7e9abbdfad170df2129dae8e15088a02b9ba99276a351a06n
}, {
a: 0x7b98f57n,
r: 0x7b98f56n
}, {
a: -0x919751deb470faa60d7c5c995c8bed72f9542d710fbbf1341n,
r: -0x919751deb470faa60d7c5c995c8bed72f9542d710fbbf1342n
}, {
a: -0xc5541d89b118a88afdd187228440427c8a24f9d9bn,
r: -0xc5541d89b118a88afdd187228440427c8a24f9d9cn
}, {
a: -0xe6c88a170595fn,
r: -0xe6c88a1705960n
}, {
a: -0xa1ffbfa388c332804dc4dc973n,
r: -0xa1ffbfa388c332804dc4dc974n
}, {
a: 0x67b768ce0c415127a77402861d1901dd7f60a8624ebea6ecafe03adc3cen,
r: 0x67b768ce0c415127a77402861d1901dd7f60a8624ebea6ecafe03adc3cdn
}];
var error_count = 0;
for (var i = 0; i < data.length; i++) {
var d = data[i];
var r = --d.a;
if (d.r !== r) {
print("Input: " + d.a.toString(16));
print("Result: " + r.toString(16));
print("Expected: " + d.r);
error_count++;
}
}
if (error_count !== 0) {
print("Finished with " + error_count + " errors.")
quit(1);
}

View File

@ -0,0 +1,11 @@
// Copyright 2021 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.
// Regression test for crbug.com/1233397.
let y_power = 13311n * 64n; // Large enough to choose the Barrett algorithm.
// A couple of digits and a couple of intra-digit bits larger.
let x_power = y_power + 50n * 64n + 30n;
let x = 2n ** x_power;
let y = 2n ** y_power;
let q = x / y;

View File

@ -0,0 +1,105 @@
// Copyright 2017 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.
// Generated by tools/bigint-tester.py.
var data = [{
a: -0x1e0f357314bac34227333c0c2086430dae88cb538f161174888591n,
b: 0x390n,
r: -0x8700f00dd65d4009ab90c5d3a887e9c8ad110a72ca7e0f84a40n
}, {
a: 0x9b7a0098fd2d495b4b2c76ff5888ae2a0359cfec6b029e6f3ee9b014802n,
b: 0xbn,
r: 0xe225d252e49ef6563ecc4fff0c69b782ed99e89db2ec895bfe6b2ea974n
}, {
a: 0x6821a6dad136b9f64096337b45d6d947cf0f0b55501e33e66fbc4ef9776n,
b: 0xan,
r: 0xa69c3e2ae8578ff06756b8c53c8af53fb1b1abbbb363863d7f93b18f25n
}, {
a: 0xf42f96f0c7f5a9c656a66122a9bcc57aa386bdb9a834e4174d45795ae408dae14e085cn,
b: -0x5e0d81a1107ef9a38b4f24b4n,
r: -0x298a4d479eac8c186fd61939024b420080b6ae6500c70c1n
}, {
a: 0xbaf7baed984dda3c20f23201f366257c601f7fbcaf51d8b738a68fd92b4n,
b: 0xd24a1eafcn,
r: 0xe39bd4d870d72880e6ad88ec17bcca6bd0eaacfbbd28ba7458n
}, {
a: -0xa658d0683d450bfec3de3fe4253f4348dd8e9a5b1002f6c24ff0en,
b: -0xeffb9a6fa690e0be59aba488b7a7c5a85a65a018242n,
r: 0xb1730d7206n
}, {
a: 0x5a65f7b2dace4550099f4009192caa513468ef4da7e2fd81n,
b: 0xf144f8bfad42d9beaf7b82a46561n,
r: 0x5feae36e8e4932adcb21n
}, {
a: -0x87271b0cbb63eba5e3d70f6af1aa6ec60c0a7884fb8d657b03en,
b: -0xb67f8c18099ce8fa0c0f4ce2852b5590f7a8037d326b0n,
r: 0xbd9602n
}, {
a: 0xd4bc42a434dba1427d387f0858aaf39c6281ffc0f10b8b0996cb3bfn,
b: -0x4198d1fec9b48e38d42f2e295abc39c2a6866527efn,
r: -0x33e39b6878d955n
}, {
a: 0x6a6f0c97d974dfd20337ca611dbdc96433964a206d54n,
b: 0x16c7c6f9e0e4e24d521e463fecb394e2936f3104590n,
r: 0x4an
}, {
a: -0xd09af7515272d81a64307afaed8854c8e2996d8e01d4864n,
b: 0x7521dfcbdf4cfbbf8d3859bf67618c91dc6915718303dbn,
r: -0x1cn
}, {
a: 0xf0da5f24832a2b651aac5dff62b22475212c26e123ff78c34560f35e9bcn,
b: -0xf9n,
r: -0xf79fbd51bf65f518c82563b974e4632b505ebe13adbfb6c297859a98cn
}, {
a: 0x76f4f5b5de8a263514554d62273e51f40342d5df692ae17625ead5b5fen,
b: -0xa5e697c57fb65858604e0a060737e7d9d1en,
r: -0xb78fb2167de210959e57cd3n
}, {
a: -0xa714d4d9d747fa5258f80f3887f4dda8a11423050046282n,
b: -0xaa3b218ab92e21920a707487fdbn,
r: 0xfb437487ba8580181ca3n
}, {
a: -0x165f3c659ac4157cb3af081b3fc42c0c788e2df501596c2b8n,
b: -0xfaa86d6eca3n,
r: 0x16d94bce4865cf842d17a399d8b4467f3f369fn
}, {
a: 0x268d93a21aab44c52f961b1c97c002f427eb8b11e0707e3879c3a348f8e2b1c40c122n,
b: 0x70ccda2e2bba53b124c877bb4edbdbd387742cfe59d9bn,
r: 0x577effaeb2338647e38edb43n
}, {
a: 0x3a13493c9e8d3d986a2a56c0aa811be408e1560f30ae155n,
b: -0x62a1a35fd7e184be45a1d0ba67888f0d982afb7a90an,
r: -0x96bcn
}, {
a: -0x2a3f3f90ea280bf64e7e460f004ea4fb2553637cb7c844f349f045ffdbn,
b: -0xf2af2581bddfd9bfc1158c86211c4f4b169c0b1n,
r: 0x2c90ab8577b8d0ee86en
}, {
a: 0x8fd5f992d4d767c8a360ad32142fa9e9d87bc0036d1d6bb7aa7471dd7f38bn,
b: 0xe70n,
r: 0x9f6709805e05fd8b3c433e470387f06391b6948459e4c2bc072747e2a0n
}, {
a: 0x52c0e08ba0a22a00498058dfeeaab2b21909e81e30c48652699n,
b: 0x1d516c96827an,
r: 0x2d2967f58654a5d30934348b225bf2b6e2a3123dn
}];
var error_count = 0;
for (var i = 0; i < data.length; i++) {
var d = data[i];
var r = d.a / d.b;
if (d.r !== r) {
print("Input A: " + d.a.toString(16));
print("Input B: " + d.b.toString(16));
print("Result: " + r.toString(16));
print("Expected: " + d.r);
print("Op: /");
error_count++;
}
}
if (error_count !== 0) {
print("Finished with " + error_count + " errors.")
quit(1);
}

View File

@ -0,0 +1,56 @@
// Copyright 2017 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: --allow-natives-syntax
assertEquals(1n, (-1n) ** 0n);
assertEquals(-1n, (-1n) ** 1n);
assertEquals(1n, (-1n) ** 2n);
assertEquals(-1n, (-1n) ** 3n);
assertEquals(1n, (-1n) ** 4n);
// Multi-digit exponents.
assertEquals(1n, (-1n) ** (2n ** 80n));
assertEquals(-1n, (-1n) ** ((2n ** 80n) + 1n));
assertEquals(1n, 0n ** 0n);
assertEquals(0n, 0n ** 1n);
assertEquals(0n, 0n ** 23n);
assertEquals(1n, 1n ** 0n);
assertEquals(1n, 1n ** 1n);
assertEquals(1n, 99n ** 0n);
assertEquals(2n, 2n ** 1n);
assertEquals(4n, 2n ** 2n);
assertEquals(8n, 2n ** 3n);
assertEquals(16n, 2n ** 4n);
assertEquals(151115727451828646838272n, 2n ** 77n);
assertEquals(3n, 3n ** 1n);
assertEquals(9n, 3n ** 2n);
assertEquals(27n, 3n ** 3n);
assertEquals(81n, 3n ** 4n);
assertEquals(243n, 3n ** 5n);
assertEquals(30903154382632612361920641803529n, 3n ** 66n);
assertEquals(1n, (-2n) ** 0n);
assertEquals(-2n, (-2n) ** 1n);
assertEquals(4n, (-2n) ** 2n);
assertEquals(-8n, (-2n) ** 3n);
assertEquals(16n, (-2n) ** 4n);
assertEquals(-32n, (-2n) ** 5n);
assertEquals(1n, (-3n) ** 0n);
assertEquals(-3n, (-3n) ** 1n);
assertEquals(9n, (-3n) ** 2n);
assertEquals(-27n, (-3n) ** 3n);
assertEquals(81n, (-3n) ** 4n);
assertEquals(-243n, (-3n) ** 5n);
assertThrows(() => 3n ** -2n, RangeError); // Negative exponent.
assertThrows(() => 2n ** (1024n ** 4n), RangeError); // Too big.
// Mixed types
assertThrows(() => 1n ** 1, TypeError);
assertThrows(() => 1 ** 1n, TypeError);

View File

@ -0,0 +1,83 @@
// Copyright 2017 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.
// Generated by tools/bigint-tester.py.
var data = [{
a: 0xb3df90n,
r: 0xb3df91n
}, {
a: 0xaacd53fc9545eb394304a3c69caba730230a6527730an,
r: 0xaacd53fc9545eb394304a3c69caba730230a6527730bn
}, {
a: 0x32efa4ba1c29098be7df8fa0f3c74a183612ecn,
r: 0x32efa4ba1c29098be7df8fa0f3c74a183612edn
}, {
a: -0xcabed06f63ad50406b96187208cf9ec6faf46413ce83e280c31ben,
r: -0xcabed06f63ad50406b96187208cf9ec6faf46413ce83e280c31bdn
}, {
a: -0x8a40ce58f753466f4008faa0814e76d9b594908df0e42cf6ad4a781e60ce2n,
r: -0x8a40ce58f753466f4008faa0814e76d9b594908df0e42cf6ad4a781e60ce1n
}, {
a: -0x848c8fc23bc93801n,
r: -0x848c8fc23bc93800n
}, {
a: -0x13a8316c5af3f3b06aab6642e717a7bdn,
r: -0x13a8316c5af3f3b06aab6642e717a7bcn
}, {
a: -0x5f5e517cf7efe577cd689c36d1beb3d9df4cfdc3fcb55ed9e9d8fan,
r: -0x5f5e517cf7efe577cd689c36d1beb3d9df4cfdc3fcb55ed9e9d8f9n
}, {
a: 0n,
r: 0x1n
}, {
a: 0x107d5ec8048c4d715e213ec74f9f04006d3f2d90dd95d17c3e82f7a4ccn,
r: 0x107d5ec8048c4d715e213ec74f9f04006d3f2d90dd95d17c3e82f7a4cdn
}, {
a: 0xb8e09fc6037a75bbfn,
r: 0xb8e09fc6037a75bc0n
}, {
a: 0x515d1b999660074184n,
r: 0x515d1b999660074185n
}, {
a: 0xe12def67dc33628638612b8137d0fa425ea2dn,
r: 0xe12def67dc33628638612b8137d0fa425ea2en
}, {
a: 0x96a9n,
r: 0x96aan
}, {
a: -0x9df122a299a5e65b275028n,
r: -0x9df122a299a5e65b275027n
}, {
a: 0x20dd05bfb5ed6ebfb05da9a7488800b8895fbfe6d709eecb6071cda73e13n,
r: 0x20dd05bfb5ed6ebfb05da9a7488800b8895fbfe6d709eecb6071cda73e14n
}, {
a: 0xb38294d2e5523534c56dd6ef38ba744b29e3a3bb6f863f1aeaen,
r: 0xb38294d2e5523534c56dd6ef38ba744b29e3a3bb6f863f1aeafn
}, {
a: -0x6b58de4ba9b2699ea6777dc1adc0b2486n,
r: -0x6b58de4ba9b2699ea6777dc1adc0b2485n
}, {
a: 0xf40028a48894df5d81131046477a22e55cbead5n,
r: 0xf40028a48894df5d81131046477a22e55cbead6n
}, {
a: -0x44cbe6c7f5e7e879d3cb2eaffc4af0a43affc094218031a1f123746549dd7b8cdcbdn,
r: -0x44cbe6c7f5e7e879d3cb2eaffc4af0a43affc094218031a1f123746549dd7b8cdcbcn
}];
var error_count = 0;
for (var i = 0; i < data.length; i++) {
var d = data[i];
var r = ++d.a;
if (d.r !== r) {
print("Input: " + d.a.toString(16));
print("Result: " + r.toString(16));
print("Expected: " + d.r);
error_count++;
}
}
if (error_count !== 0) {
print("Finished with " + error_count + " errors.")
quit(1);
}

View File

@ -0,0 +1,81 @@
// Copyright 2017 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: --allow-natives-syntax
'use strict'
// Without .toJSON method.
assertEquals(undefined, BigInt.prototype.toJSON);
assertThrows(() => JSON.stringify(42n), TypeError);
assertThrows(() => JSON.stringify(Object(42n)), TypeError);
// With .toJSON method that returns a string.
BigInt.prototype.toJSON = function() {
assertEquals("bigint", typeof this);
return String(this);
}
assertEquals("\"42\"", JSON.stringify(42n));
BigInt.prototype.toJSON = function() {
assertEquals("object", typeof this);
return String(this);
}
assertEquals("\"42\"", JSON.stringify(Object(42n)));
// With .toJSON method that returns a BigInt primitive.
BigInt.prototype.toJSON = function() {return this};
assertThrows(() => JSON.stringify(42n), TypeError);
assertThrows(() => JSON.stringify(Object(42n)), TypeError);
// With .toJSON method that returns a BigInt object.
BigInt.prototype.toJSON = function() {return Object(this)};
assertThrows(() => JSON.stringify(42n), TypeError);
assertThrows(() => JSON.stringify(Object(42n)), TypeError);
// Without .toJSON method but with a replacer returning a string.
delete BigInt.prototype.toJSON;
let replacer;
replacer = function(k, v) {
assertEquals("bigint", typeof v);
assertTrue(42n == v);
return "43";
}
assertEquals("\"43\"", JSON.stringify(42n, replacer));
replacer = function(k, v) {
assertEquals("object", typeof v);
assertTrue(42n == v);
return "43";
}
assertEquals("\"43\"", JSON.stringify(Object(42n), replacer));
// Without .toJSON method but with a replacer returning a BigInt primitive.
assertEquals(undefined, BigInt.prototype.toJSON);
replacer = () => 43n;
assertThrows(() => JSON.stringify(42n, replacer), TypeError);
assertThrows(() => JSON.stringify(Object(42n), replacer), TypeError);
// Without .toJSON method but with a replacer returning a BigInt object.
assertEquals(undefined, BigInt.prototype.toJSON);
replacer = () => Object(43n);
assertThrows(() => JSON.stringify(42n, replacer), TypeError);
assertThrows(() => JSON.stringify(Object(42n), replacer), TypeError);

View File

@ -0,0 +1,8 @@
// Copyright 2018 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.
// Create BigInt in large object space for which MakeImmutable reduces the
// length.
const x = 2n ** (2n ** 22n);
assertEquals(1n, x - (x - 1n));

View File

@ -0,0 +1,8 @@
// Copyright 2021 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.
let quotient = 0x1234567890abcdef12345678n; // Bigger than one digit_t.
let dividend = quotient * 10n;
let result = dividend % quotient;
assertEquals(0n, result);

View File

@ -0,0 +1,105 @@
// Copyright 2017 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.
// Generated by tools/bigint-tester.py.
var data = [{
a: 0xaed3c714bb42a73d708bcf1dc9a9deebadc913ef42bac6a6178a60n,
b: -0xf3d6bd1c059b79n,
r: 0x2a4f893c8ece3n
}, {
a: -0x8a6d8cb8e32aba50e08fd50aecbda6821e1863bf9a2n,
b: 0xe19ab8530bce542ec6b4c848fc383a2b688f07976dd523dabn,
r: -0x8a6d8cb8e32aba50e08fd50aecbda6821e1863bf9a2n
}, {
a: 0x7cd19a308b217ddd9dcda69ebe37767f09a483cb87060314aeade6f6c619d27c3n,
b: 0xae30b5c754e0an,
r: 0x619154797565dn
}, {
a: -0xaa90d777e849974d7ebebd2ed76dce635e36713e9e0c97cen,
b: 0xcc2bc7239bf83ecafc74b25750981df258n,
r: -0xa32d47bc250c5a41d147a862099778685en
}, {
a: 0x7386178fe1159c4ca3c4e5caa6eda4413926047efd22007931c22ab54bn,
b: 0xc05100caa704bca144n,
r: 0x55ead7f83d4a795753n
}, {
a: -0xa48867cf46692351a59bc89c0ddc9a6d2cd9f72578c0bab72d8389n,
b: 0x77c2eec6cc0bef33dd4756b223c35a0f2b528f8648a7n,
r: -0x184a6eed8fcd32399c59605c7255b5614b388be24b44n
}, {
a: 0xac7681c26f78191107c9cde47f984fc7ffb7bffd0a055fc14n,
b: -0xe2d91d1a0e1edc3f806a24c36f7ca0a8a9b44b66c9n,
r: 0xdf0b3460335089fca0b1da676b3d1e9caf15afd3den
}, {
a: -0x3035011f4adba0c032ddc2fc884ff7663b45cb3baebec0fn,
b: 0xcc27f9a21470911a61aae50ae118ebcf85ea4dn,
r: -0xc5ea1db5af95ccdce2844b13b82659be1ac2adn
}, {
a: -0x2dbe79c42b1e8db7aea4ca9cfaf1350528b096e23f69ea322cn,
b: -0x82f7e4f2ee432485n,
r: -0x824bddbaf61ce383n
}, {
a: 0xc5c7fbeb60fdb9f8e8347ebf9fe303e3223394b2db93ce2n,
b: 0xcd988b4cb278a39fd3ae58c16616855f01fab0fb0n,
r: 0xc3b5157e680c8ca66df1bd640c6ad1601bd612b02n
}, {
a: 0x73dd1e27450edb450fe4bd70494a8ad85a8ad9691bc40bf500a1n,
b: 0xc8fb467f71be8a6b965d21857ecfdn,
r: 0x646e6d9fa1e2eb2933b2e5a837d37n
}, {
a: -0xecb217583ec4240399bfa34560b45f1fd08efd0ebb56b2dn,
b: 0xeba34abn,
r: -0xc2d347bn
}, {
a: 0x29c8a9854802b9317b90683eb82609b3aa695598807fea0482a56567n,
b: -0xabe5e55b228f8n,
r: 0x52303615b525fn
}, {
a: 0x7b532ee90b3945dbed20180632f46c90d0edb558e39456103f50e5a74ff1dn,
b: 0x17n,
r: 0x6n
}, {
a: -0x6f1dbf8dedea796a2423fad9688d71340963da3a4f005f13e9cd4aa03b96c864552cn,
b: -0x408a4f36ec4a1b74642fb0a4559en,
r: -0x33c06c53e6e47ca87f36447f1b0n
}, {
a: -0xe77508ff49bc76c78678676ca1edc82eb167f3b07d3208d89d26582ef74d60n,
b: -0xf005fb1a8b29035c72980abe4a0715c90n,
r: -0x159e8c7616079663b4e12765a05cc6d40n
}, {
a: 0x626749ef019017f53b2c686f26594e6d3c5f247cf0ed7024cca277n,
b: 0x5bd931ea8c6939115ad69f6ce3c6bbc300320n,
r: 0x3a4b041c36d0a45ef932745eab473943b1a97n
}, {
a: -0x960dde134b881d3366d659c7d8c3eb6346f50c08c6f78en,
b: -0xc9e7fa60f6ce1997012f5a6164138447fa248754985905dc6n,
r: -0x960dde134b881d3366d659c7d8c3eb6346f50c08c6f78en
}, {
a: 0x702dc0033e09e9e58ec3fc96f861587ad13cea1ed7b7eb301n,
b: 0x71f0c97687b4f3318be2fe54b90273n,
r: 0x4e1859254ac1d42f7c812decef00a3n
}, {
a: 0x39376649769a0abb26133deee934330ef21a2f90ea89476569630021af6023235n,
b: -0x4aaaec4085f65ccc9d547beb122160afcbb3n,
r: 0x3027d5ebb37c5aa438f11dfcafa3b003b91bn
}];
var error_count = 0;
for (var i = 0; i < data.length; i++) {
var d = data[i];
var r = d.a % d.b;
if (d.r !== r) {
print("Input A: " + d.a.toString(16));
print("Input B: " + d.b.toString(16));
print("Result: " + r.toString(16));
print("Expected: " + d.r);
print("Op: %");
error_count++;
}
}
if (error_count !== 0) {
print("Finished with " + error_count + " errors.")
quit(1);
}

View File

@ -0,0 +1,10 @@
// Copyright 2021 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.
// Regression test for crbug.com/1223724
const kBits = 500 * 64;
const a = BigInt.asUintN(kBits, -1n);
const b = a * a;
const expected = (a << BigInt(kBits)) - a;
assertEquals(expected, b);

View File

@ -0,0 +1,105 @@
// Copyright 2017 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.
// Generated by tools/bigint-tester.py.
var data = [{
a: 0x2bf1f236c2df29f7c99be052dfe1b69ae158d777fea487af889f6259f472c0n,
b: -0xae0090dfn,
r: -0x1dde8b7f987479d7b308e2b8a122703d417f921fd4ab04fcac81439ace4f445c7bf540n
}, {
a: -0x71cd629b6682b5b1c50f9436ded88468bcn,
b: -0xb24ce1d11726048158fb42c02e9361973193n,
r: 0x4f42fbebca0bc1746d114996d9c9cceb4065c347da31dc0efa88db41f1f724aef81ff4n
}, {
a: 0xef7c15fb2256338bd0650fa51c28551108ccb9828850f1b415d0c8f1a47fc0e2f86n,
b: 0xc17n,
r: 0xb4f552dbf2c20292f5475d025276b9c70f16316c91e0a9a2833bf2d616bc484f808d0an
}, {
a: 0xcc8a5a56c623d9f9be2103bc237976f26n,
b: 0x13a02fec7cfd49c5a081c06bbbaac5c70dc3an,
r: 0xfae417740ef1963ad78aa4252159d986593845690f4f5fe759f6d913d79810473d69cn
}, {
a: -0x519n,
b: 0x7de5551df3ec2619a89139153663a79f8bdb47047423c8070d7cfddc26d43af8ee9n,
r: -0x281c60ee5b06ece38cc4c4bfd2242017c4ff0cd05b40a66abf3c22a1741efe09ef81c1n
}, {
a: 0x6fb9ba0d0n,
b: -0x86b45ffb80fbf2b61abc14b28855780f83e187fd6ae26e09d28d6f05260e1n,
r: -0x3ac9efdd4e930fcbf654819060b858f182f7768db6bc72deb8d734d2ea10fa02b656d0n
}, {
a: -0xde2e7a0883a63d69d2120108f92943e4a34b63e8468c12b38a0519a6498n,
b: -0xb1857781fefn,
r: 0x9a11f83db6da31f78a2415d3891f79a0f6aafc69553fb458a2bc3ae2e2f65cb09251e8n
}, {
a: -0x2c90284ebdb5237ba7c9562f596ef9a21254a3n,
b: -0xb55feab8b45cc1bcdcfc5585c9114de0n,
r: 0x1f929eda8d33ec2ded8d76382a4cb731f805d28e827521a27154b6618a6f87ed5215a0n
}, {
a: 0x11ffe68d26ca29eac43b64n,
b: -0xe3311b278fec1fb3f8f59acfd9147c773197fc54c66b25bdn,
r: -0xff95d530fd53e61744d86d09f9ab5401b1efb2133af5c47ffeca31aca22a4da414cd4n
}, {
a: 0xbda74de44eeb2995a4185325014863n,
b: 0xf99164c7248a0372d72d82cbf65fdb345c84bca6n,
r: 0xb8e3712f119fefa47168950100b33aa1ec4e61a970d0eec2d2dd4b925cc4dfd709a432n
}, {
a: 0x47fc0bb6d761e12a1f7cf2a14f4cc777486b22516ca339641fn,
b: -0xd2fa2494ae242494f307n,
r: -0x3b531808ad9095f9f904dba47ef4a0aef54f736cc2836accb7b1b70f07ee862e8729d9n
}, {
a: 0x91d09f35203fcf69974d347ab718912cn,
b: 0xfc2d9a00611e4e1767b67db898b951e5d2bbb9n,
r: 0x8fa3561bff2cc00a780a71e5b16d6092296514d401c88fc54e04a91062775cb4e40cccn
}, {
a: 0x5a5b1ede360dafcac08c92f4b809e401502df5ab8569303a2n,
b: -0xb64d963b1ac4eb46ddd65n,
r: -0x40582a6083cd0feb5b33ac138feaf9250b5084e561807e56a8415c810a1bf9861d48ean
}, {
a: 0xf68275dc25d6af7dde130n,
b: 0xfe330b766e44f479e342e3315812e977d4d5e39bffe42111dn,
r: 0xf4c697f78dc7c9b3207b50cf2cf3035aa065e96c37c0be3345f71f34096f057e76b270n
}, {
a: 0x77009ed053f71n,
b: -0x647aecfc2af4079a586fbba99070c3f51d5465d9a4fd8c12cdab10854n,
r: -0x2eb5627edb1072a65a1db2d243d0bf2eeb5c3ff6ad61ec1063e9ee40b783bd06d55914n
}, {
a: 0xccfa15bb6125b01bece5a919ab5e9128e784d63e50b5990ba8047a7effn,
b: 0x1a366ac48cdan,
r: 0x14fcf8728aa3dc5ef26b077dfc012d592c3a0cdfc3331942f921f037eea5af9eff9926n
}, {
a: 0x4fc54a59f2n,
b: -0x93bbcbd684987407c4ec4a3cbdc7c4821c33ca20ca8449b0055905e9a8ffn,
r: -0x2e08ce533fdc7bb8a3a2280cfb116c85837b74606ed25f8daad623baa4ac7de758680en
}, {
a: -0xcf21626f318089a85738f7e9cdcf0a477f4d880ce58679n,
b: -0xc7ca8704a49fdb8f9567c68cn,
r: 0xa1a6d11a77d8e1b723bfa0242407a454274145c31bb6ede29bb0e3883b08951b36202cn
}, {
a: 0x20c3cb19e51d4e2ac2c89f26e052bef8n,
b: -0xab2a148297108425ebd2fd17d897f647e0792fn,
r: -0x15e82b69a0eaed04cd140c6aed3b1f5bc0fc5de7ceddcb2d77615767b19dd82c744788n
}, {
a: -0xcc4f48f45d8165569348fb995370n,
b: 0x140cc111df0a06e32335478ded744eb3a737a53409n,
r: -0x10005f808c07a1d91faac090aad06804b491919a9d2ed58f6caa52448ad97bd486aef0n
}];
var error_count = 0;
for (var i = 0; i < data.length; i++) {
var d = data[i];
var r = d.a * d.b;
if (d.r !== r) {
print("Input A: " + d.a.toString(16));
print("Input B: " + d.b.toString(16));
print("Result: " + r.toString(16));
print("Expected: " + d.r);
print("Op: *");
error_count++;
}
}
if (error_count !== 0) {
print("Finished with " + error_count + " errors.")
quit(1);
}

View File

@ -0,0 +1,83 @@
// Copyright 2017 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.
// Generated by tools/bigint-tester.py.
var data = [{
a: 0xcn,
r: -0xcn
}, {
a: -0x5a3d0f6cdb7987a2d262838c05359f786a484d052529n,
r: 0x5a3d0f6cdb7987a2d262838c05359f786a484d052529n
}, {
a: -0x98d8c6cbfd67b6b652b7a4670478f6706e06a3n,
r: 0x98d8c6cbfd67b6b652b7a4670478f6706e06a3n
}, {
a: -0xe66ac692ff012bd0f4ca38804628f71ff411aede09c59597n,
r: 0xe66ac692ff012bd0f4ca38804628f71ff411aede09c59597n
}, {
a: -0x97e1e0c13c0c0c420aca92268ea802047c30570335de0000dn,
r: 0x97e1e0c13c0c0c420aca92268ea802047c30570335de0000dn
}, {
a: 0x6b2eddc3b212913abed4f5c84e3eee64d6463224dff8n,
r: -0x6b2eddc3b212913abed4f5c84e3eee64d6463224dff8n
}, {
a: -0xfcd42a712dd928deb51ab2d151fa6bee0f4dd2fa6n,
r: 0xfcd42a712dd928deb51ab2d151fa6bee0f4dd2fa6n
}, {
a: -0x75ba8e0e92a05ff552f2dc3afb39a4dn,
r: 0x75ba8e0e92a05ff552f2dc3afb39a4dn
}, {
a: 0x4570376e541836fab5190e08an,
r: -0x4570376e541836fab5190e08an
}, {
a: 0x15aca33cfb06n,
r: -0x15aca33cfb06n
}, {
a: 0x7ec0027910c44b791bf193c6f25487a9435n,
r: -0x7ec0027910c44b791bf193c6f25487a9435n
}, {
a: -0x31f0d92f358618e6b29a2899bd988533838d33839fb37n,
r: 0x31f0d92f358618e6b29a2899bd988533838d33839fb37n
}, {
a: 0xb4f84118d797244c982f1n,
r: -0xb4f84118d797244c982f1n
}, {
a: 0x626n,
r: -0x626n
}, {
a: 0x9f35c8968457d07608699df5894c0542f35b73b0b5ce8423aan,
r: -0x9f35c8968457d07608699df5894c0542f35b73b0b5ce8423aan
}, {
a: -0xb5be1f7937895adc457f051d1f4bc74d556b432dn,
r: 0xb5be1f7937895adc457f051d1f4bc74d556b432dn
}, {
a: 0xcacb413b3cab5a5f5086511728d1afbaa82ca41e69805daf47503e2n,
r: -0xcacb413b3cab5a5f5086511728d1afbaa82ca41e69805daf47503e2n
}, {
a: -0x77ef7cbb15cee20a519a1n,
r: 0x77ef7cbb15cee20a519a1n
}, {
a: -0x71ac9bfe7f5f70038c7fn,
r: 0x71ac9bfe7f5f70038c7fn
}, {
a: -0x500a02b8fd66ee1067022c02c7241acdc42b947bfb933aa95a8d6n,
r: 0x500a02b8fd66ee1067022c02c7241acdc42b947bfb933aa95a8d6n
}];
var error_count = 0;
for (var i = 0; i < data.length; i++) {
var d = data[i];
var r = -d.a;
if (d.r !== r) {
print("Input: " + d.a.toString(16));
print("Result: " + r.toString(16));
print("Expected: " + d.r);
error_count++;
}
}
if (error_count !== 0) {
print("Finished with " + error_count + " errors.")
quit(1);
}

View File

@ -0,0 +1,83 @@
// Copyright 2017 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.
// Generated by tools/bigint-tester.py.
var data = [{
a: 0x9f0305cd75e4n,
r: -0x9f0305cd75e5n
}, {
a: -0xe8e9c8312f553c9n,
r: 0xe8e9c8312f553c8n
}, {
a: -0x1a29f0783a66534da3c024ad1cc854073f886888fen,
r: 0x1a29f0783a66534da3c024ad1cc854073f886888fdn
}, {
a: -0xfc2cc19496c1ced95be832ca5246d41c526b9fa28b88bcd39813aa336n,
r: 0xfc2cc19496c1ced95be832ca5246d41c526b9fa28b88bcd39813aa335n
}, {
a: 0x13ebn,
r: -0x13ecn
}, {
a: 0x4c12d642b2a132f0c927ec7504b530fb45d5e249163ffdc59feb3de31881n,
r: -0x4c12d642b2a132f0c927ec7504b530fb45d5e249163ffdc59feb3de31882n
}, {
a: 0x49637a624cb8782002e3e0874ad76215e188cee948c7ce7b0f66e1d0n,
r: -0x49637a624cb8782002e3e0874ad76215e188cee948c7ce7b0f66e1d1n
}, {
a: -0x81cbae84e6753b885ada46c0bf72368c083fed622fn,
r: 0x81cbae84e6753b885ada46c0bf72368c083fed622en
}, {
a: -0xcdf793acfdd08b6n,
r: 0xcdf793acfdd08b5n
}, {
a: 0x88n,
r: -0x89n
}, {
a: -0x1fn,
r: 0x1en
}, {
a: 0x5c3278e76266b9e93d63eb4f2aa53716220aa1n,
r: -0x5c3278e76266b9e93d63eb4f2aa53716220aa2n
}, {
a: -0x9f4fe05n,
r: 0x9f4fe04n
}, {
a: 0xdn,
r: -0xen
}, {
a: -0x74a9d63d02bd1393b311211e35c8b2d11e2367ffffb812683365f02d98n,
r: 0x74a9d63d02bd1393b311211e35c8b2d11e2367ffffb812683365f02d97n
}, {
a: 0x8a2831ae3e1b6b21a7b3d7ee921a0c0edf29b272d654f647169a5a6141d3aaf41439n,
r: -0x8a2831ae3e1b6b21a7b3d7ee921a0c0edf29b272d654f647169a5a6141d3aaf4143an
}, {
a: 0xa2ef28270a7e668e190bc303537f5a8ba3f0d59bcn,
r: -0xa2ef28270a7e668e190bc303537f5a8ba3f0d59bdn
}, {
a: -0x4f8bd11ee4ef38682a0c94en,
r: 0x4f8bd11ee4ef38682a0c94dn
}, {
a: 0x5436d0721d1282755068add3b5ab5424cb455fad50811a9afff0be5n,
r: -0x5436d0721d1282755068add3b5ab5424cb455fad50811a9afff0be6n
}, {
a: 0x5db6907c92529f517d24a6ff7303de42cb9059ae2adc0c22n,
r: -0x5db6907c92529f517d24a6ff7303de42cb9059ae2adc0c23n
}];
var error_count = 0;
for (var i = 0; i < data.length; i++) {
var d = data[i];
var r = ~d.a;
if (d.r !== r) {
print("Input: " + d.a.toString(16));
print("Result: " + r.toString(16));
print("Expected: " + d.r);
error_count++;
}
}
if (error_count !== 0) {
print("Finished with " + error_count + " errors.")
quit(1);
}

View File

@ -0,0 +1,105 @@
// Copyright 2017 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.
// Generated by tools/bigint-tester.py.
var data = [{
a: 0x77a87n,
b: 0xde08e7433fb9584911b8cb4bc7eed802299b4489fc635974d063847da4e8b461df5dn,
r: 0xde08e7433fb9584911b8cb4bc7eed802299b4489fc635974d063847da4e8b467ffdfn
}, {
a: -0x1d3ff6f353f2d035ed7b4b8e5e4ae1c8d162n,
b: -0xcf829b11c2f996f388b22cd03aeb75ec434f3be8fde6466n,
r: -0x192f308302c00024a55a4004520a81c84062n
}, {
a: 0x6dbbc93af9a9c222187dn,
b: -0xfaa906348dc49859c34bc7c6n,
r: -0xfaa9020404c400500149c781n
}, {
a: 0xf8n,
b: 0x4388532n,
r: 0x43885fan
}, {
a: -0x3ee35e1823b91414618f05995e11594920539921e9440n,
b: -0x58c5811ee19db01b7d9824c49682af55956119cfbc9868287ef138da08ee3n,
r: -0x3c80040002800414010101891c1048082051180008423n
}, {
a: -0xa2a70c5da9a7e98f242e82d518n,
b: 0n,
r: -0xa2a70c5da9a7e98f242e82d518n
}, {
a: 0x7868475f450ff2b15a03eccb4d26ce8711383f615cn,
b: 0x1c62774e1db239cb461c4190b54de4d872f9484cf82ed1258cc14580cf29f608n,
r: 0x1c62774e1db239cb461c41f8fd4fffdd7ffbf95efbeedb6daecfc791ff3ff75cn
}, {
a: 0x865d033028551a71f6f9f8d7b36cf9819n,
b: -0x68e30391d9831a4ea3e65b2e433f55ba398n,
r: -0x68610290c9830a4482000206000c1102387n
}, {
a: -0x817a0dacbafbaf40ef819fc62a8efc4b4960n,
b: -0x5af313e32a5386e29cb5d2b34d54f04da389f33d52444f177671e41n,
r: -0x12a04840a008a008f019504008074430841n
}, {
a: -0xef8c9475210c0a31aa12c34db6e7737609c75b78a54cn,
b: -0xba91b4ec3a5390db84febaeaddb8209155413e2e02fb0n,
r: -0xa9080441210808300a02820d9282011400034260250cn
}, {
a: -0xf4e707078d14001959f4n,
b: 0n,
r: -0xf4e707078d14001959f4n
}, {
a: 0x601f0n,
b: 0x246fbfn,
r: 0x266fffn
}, {
a: -0x9ccd3d1b6d4bcde8643ad641d395980bn,
b: -0x379e57728185fd098383a23c7f56dn,
r: -0x13901650808484018100003859009n
}, {
a: 0xcc4b3ba719bd1b37f254f36a72ee375ad22abn,
b: -0xb0c220750f2dad9de91ffb8a7bbf8ffefen,
r: -0x4000640e0c8098a0095880188a02dc55n
}, {
a: 0xa230c33b718cd563f9c1577f4f8da160851902341ba1a6e6bdcbec413d98a18n,
b: 0xc2f4e2db2df59ccc34690479ebe64df967n,
r: 0xa230c33b718cd563f9c1577f4f8dad6fcf3db2ff5bede7e6bdcffeff7ddfb7fn
}, {
a: -0x5fbac9a8f47n,
b: 0xf1bfe6f97e8f516685372b06ea89659c3df4ab3f6779e5c0b41e1b570fn,
r: -0x54ba0808841n
}, {
a: -0x7fd2d4a4c60ba795e2fcn,
b: 0x33dcea557cc5156dacb9ad7b252598172f92d8cf7d38e69f0a0n,
r: -0xd02d02000082194025cn
}, {
a: -0x3833089d7cf4e0181247572037a90cc2506342a2191137345e3a0e10n,
b: 0xededf5c7e54cd86afc6d838205c8a78cac7a0e410792a21cf3e4e38dd8ca2dd80n,
r: -0x283208103824c01802450720300908c2004142200111072052180210n
}, {
a: -0x188818a47abbfe64357ccd1a33fb5cb875f86n,
b: -0x14faf1811ee737d048c025f7a1fe156f7e90d23a699d040609e631836500df2e30cdn,
r: -0x108808202299d040201c411832500cb061085n
}, {
a: 0xf60c0260022920bdbd1c837778657936956c15b4cb1n,
b: 0xa10df3b397c24n,
r: 0xf60c0260022920bdbd1c8377786579b79dffb7b7cb5n
}];
var error_count = 0;
for (var i = 0; i < data.length; i++) {
var d = data[i];
var r = d.a | d.b;
if (d.r !== r) {
print("Input A: " + d.a.toString(16));
print("Input B: " + d.b.toString(16));
print("Result: " + r.toString(16));
print("Expected: " + d.r);
print("Op: |");
error_count++;
}
}
if (error_count !== 0) {
print("Finished with " + error_count + " errors.")
quit(1);
}

View File

@ -0,0 +1,32 @@
// Copyright 2017 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.
var { 9007199254740991n: it } = { 9007199254740991n: 1 };
assertEquals(it, 1);
var { 999999999999999999n: it } = { 999999999999999999n: 1 }; // greater than max safe integer
assertEquals(it, 1);
var obj = { 0xfffffffffffffffffffffn: 1};
assertEquals(1, obj["19342813113834066795298815"]);
var obj2 = {0o777777777777777777777777777n: 1};
assertEquals(1, obj2["2417851639229258349412351"]);
var obj3 = { 0x4n: 'hi' };
assertEquals('hi', obj3[4]);
assertEquals(undefined, obj3["0x4"]);
let obj4 =
{12345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890n: 1};
assertEquals(
1,
obj4["12345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890"]);
// 130 hex digits
let obj5 = {0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffn: 1};
assertEquals(
1,
obj5["3432398830065304857490950399540696608634717650071652704697231729592771591698828026061279820330727277488648155695740429018560993999858321906287014145557528575"]);

View File

@ -0,0 +1,23 @@
// Copyright 2021 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.
function fastAssertEquals(expected, actual) {
if (expected === actual) return;
// Formatting large BigInts to base-10 string is slow and verbose, so format
// them to hex strings and report only a prefix.
throw new MjsUnitAssertionError(
'Failure:\nexpected:\n0x' +
expected.toString(16).substring(0, 1000) +
'...n\nfound:\n0x' +
actual.toString(16).substring(0, 1000) + '...n');
}
function regress_1228267(power) {
let a = 2n ** power;
let a_squared = a * a;
let expected = 2n ** (2n * power);
fastAssertEquals(expected, a_squared);
}
regress_1228267(1273000n); // This triggered the bug on 32-bit platforms.
regress_1228267(2564000n); // This triggered the bug on 64-bit platforms.

View File

@ -0,0 +1,12 @@
// Copyright 2021 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.
function regress_1227752(power) {
let a = 2n ** power;
let a_squared = a * a;
let expected = 2n ** (2n * power);
assertEquals(expected, a_squared);
}
regress_1227752(48016n); // This triggered the bug on 32-bit platforms.
regress_1227752(95960n); // This triggered the bug on 64-bit platforms.

View File

@ -0,0 +1,25 @@
// Copyright 2021 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.
assertTrue(BigInt("-0 ") == -0);
assertTrue("-0 " == 0n);
assertTrue(BigInt("-0") == -0);
assertTrue(-0n == -0);
assertTrue(-0n == 0n);
assertTrue(BigInt("-0 ") > -1);
assertTrue("-0 " > -1n);
assertTrue(BigInt("-0") > -1);
assertTrue(-0n > -1);
assertEquals(BigInt("-0 ") & 1n, 0n);
assertEquals(BigInt("-0") & 1n, 0n);
assertEquals(-0n & 1n, 0n);
var zero = BigInt("-0 ");
assertEquals(1n, ++zero);
zero = BigInt("-0");
assertEquals(1n, ++zero);
zero = -0n;
assertEquals(1n, ++zero);

View File

@ -0,0 +1,17 @@
// Copyright 2018 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: --allow-natives-syntax
function f(x, b) {
if (b) return Math.trunc(+(x))
else return Math.trunc(Number(x))
}
%PrepareFunctionForOptimization(f);
f("1", true);
f("2", true);
f("2", false);
%OptimizeFunctionOnNextCall(f);
f(3n);

Some files were not shown because too many files have changed in this diff Show More