[v8-test262-automation] Updated curation log with latest revision sha's from export and changed files.

sourceRevisionAtLastExport: f85a3554 targetRevisionAtLastExport: 6bb8f41e0a
This commit is contained in:
test262-automation 2019-02-04 19:41:17 +00:00
parent 8d9f7690f8
commit 39d5434ab1
198 changed files with 9831 additions and 244 deletions

View File

@ -1,5 +1,5 @@
{
"sourceRevisionAtLastExport": "f85a3554",
"targetRevisionAtLastExport": "6bb8f41e0a",
"sourceRevisionAtLastExport": "ddf72e4b",
"targetRevisionAtLastExport": "8d9f7690f8",
"curatedFiles": {}
}

View File

@ -0,0 +1,61 @@
// Copyright 2019 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Flags: --harmony-intl-bigint
var locales = [
"en", // "1,234,567,890,123,456"
"de", // "1.234.567.890.123.456"
"fr", // "1234567890123456"
"hi", // "1,23,45,67,89,01,23,456"
"fa", // "۱٬۲۳۴٬۵۶۷٬۸۹۰٬۱۲۳٬۴۵۶"
"th-u-nu-thai", // "๑,๒๓๔,๕๖๗,๘๙๐,๑๒๓,๔๕๖"
];
var data = [
Number.MAX_SAFE_INTEGER,
-Number.MAX_SAFE_INTEGER,
Math.floor(Number.MAX_SAFE_INTEGER / 2),
0,
/// -0, // this case is broken now.
];
for (var locale of locales) {
let nf = new Intl.NumberFormat(locale);
let percentOption = {style: "percent"};
let nfPercent = new Intl.NumberFormat(locale, percentOption);
for (var n of data) {
let bigint = BigInt(n);
// Test NumberFormat w/ number output the same as
// BigInt.prototype.toLocaleString()
assertEquals(nf.format(n), bigint.toLocaleString(locale));
// Test NumberFormat output the same regardless pass in as number or BigInt
assertEquals(nf.format(n), nf.format(bigint));
// Test formatToParts
assertEquals(nf.formatToParts(n), nf.formatToParts(bigint));
// Test output with option
// Test NumberFormat w/ number output the same as
// BigInt.prototype.toLocaleString()
assertEquals(nfPercent.format(n),
bigint.toLocaleString(locale, percentOption));
// Test NumberFormat output the same regardless pass in as number or BigInt
assertEquals(nfPercent.format(n), nfPercent.format(bigint));
assertEquals(nfPercent.formatToParts(n), nfPercent.formatToParts(bigint));
}
// Test very big BigInt
let veryBigInt = BigInt(Number.MAX_SAFE_INTEGER) *
BigInt(Number.MAX_SAFE_INTEGER) *
BigInt(Number.MAX_SAFE_INTEGER);
assertEquals(nf.format(veryBigInt), veryBigInt.toLocaleString(locale));
// It should output different than toString
assertFalse(veryBigInt.toLocaleString(locale) == veryBigInt.toString());
assertTrue(veryBigInt.toLocaleString(locale).length >
veryBigInt.toString().length);
}

View File

@ -0,0 +1,108 @@
// Copyright 2019 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Flags: --harmony-intl-datetime-style
// Throws only once during construction.
// Check for all getters to prevent regression.
// Preserve the order of getter initialization.
let getCount = 0;
let weekday = new Array();
let year = new Array();
let month = new Array();
let day = new Array();
let hour = new Array();
let minute = new Array();
let second = new Array();
let localeMatcher = new Array();
let hour12 = new Array();
let hourCycle = new Array();
let dateStyle = new Array();
let timeStyle = new Array();
let timeZone = new Array();
let era = new Array();
let timeZoneName = new Array();
let formatMatcher = new Array();
new Intl.DateTimeFormat(['en-US'], {
get weekday() {
weekday.push(++getCount);
},
get year() {
year.push(++getCount);
},
get month() {
month.push(++getCount);
},
get day() {
day.push(++getCount);
},
get hour() {
hour.push(++getCount);
},
get minute() {
minute.push(++getCount);
},
get second() {
second.push(++getCount);
},
get localeMatcher() {
localeMatcher.push(++getCount);
},
get hour12() {
hour12.push(++getCount);
},
get hourCycle() {
hourCycle.push(++getCount);
},
get timeZone() {
timeZone.push(++getCount);
},
get dateStyle() {
dateStyle.push(++getCount);
return "full";
},
get timeStyle() {
timeStyle.push(++getCount);
},
get era() {
era.push(++getCount);
},
get timeZoneName() {
timeZoneName.push(++getCount);
},
get formatMatcher() {
formatMatcher.push(++getCount);
}
});
assertEquals(1, weekday.length);
assertEquals(1, weekday[0]);
assertEquals(1, year.length);
assertEquals(2, year[0]);
assertEquals(1, month.length);
assertEquals(3, month[0]);
assertEquals(1, day.length);
assertEquals(4, day[0]);
assertEquals(1, hour.length);
assertEquals(5, hour[0]);
assertEquals(1, minute.length);
assertEquals(6, minute[0]);
assertEquals(1, second.length);
assertEquals(7, second[0]);
assertEquals(1, localeMatcher.length);
assertEquals(8, localeMatcher[0]);
assertEquals(1, hour12.length);
assertEquals(9, hour12[0]);
assertEquals(1, hourCycle.length);
assertEquals(10, hourCycle[0]);
assertEquals(1, timeZone.length);
assertEquals(11, timeZone[0]);
assertEquals(1, dateStyle.length);
assertEquals(12, dateStyle[0]);
assertEquals(1, timeStyle.length);
assertEquals(13, timeStyle[0]);
assertEquals(0, era.length);
assertEquals(0, timeZoneName.length);
assertEquals(0, formatMatcher.length);

View File

@ -0,0 +1,109 @@
// Copyright 2019 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Flags: --harmony-intl-datetime-style
// Throws only once during construction.
// Check for all getters to prevent regression.
// Preserve the order of getter initialization.
let getCount = 0;
let weekday = new Array();
let year = new Array();
let month = new Array();
let day = new Array();
let hour = new Array();
let minute = new Array();
let second = new Array();
let localeMatcher = new Array();
let hour12 = new Array();
let hourCycle = new Array();
let dateStyle = new Array();
let timeStyle = new Array();
let timeZone = new Array();
let era = new Array();
let timeZoneName = new Array();
let formatMatcher = new Array();
new Intl.DateTimeFormat(['en-US'], {
get weekday() {
weekday.push(++getCount);
},
get year() {
year.push(++getCount);
},
get month() {
month.push(++getCount);
},
get day() {
day.push(++getCount);
},
get hour() {
hour.push(++getCount);
},
get minute() {
minute.push(++getCount);
},
get second() {
second.push(++getCount);
},
get localeMatcher() {
localeMatcher.push(++getCount);
},
get hour12() {
hour12.push(++getCount);
},
get hourCycle() {
hourCycle.push(++getCount);
},
get timeZone() {
timeZone.push(++getCount);
},
get dateStyle() {
dateStyle.push(++getCount);
return "full";
},
get timeStyle() {
timeStyle.push(++getCount);
return "full";
},
get era() {
era.push(++getCount);
},
get timeZoneName() {
timeZoneName.push(++getCount);
},
get formatMatcher() {
formatMatcher.push(++getCount);
}
});
assertEquals(1, weekday.length);
assertEquals(1, weekday[0]);
assertEquals(1, year.length);
assertEquals(2, year[0]);
assertEquals(1, month.length);
assertEquals(3, month[0]);
assertEquals(1, day.length);
assertEquals(4, day[0]);
assertEquals(1, hour.length);
assertEquals(5, hour[0]);
assertEquals(1, minute.length);
assertEquals(6, minute[0]);
assertEquals(1, second.length);
assertEquals(7, second[0]);
assertEquals(1, localeMatcher.length);
assertEquals(8, localeMatcher[0]);
assertEquals(1, hour12.length);
assertEquals(9, hour12[0]);
assertEquals(1, hourCycle.length);
assertEquals(10, hourCycle[0]);
assertEquals(1, timeZone.length);
assertEquals(11, timeZone[0]);
assertEquals(1, dateStyle.length);
assertEquals(12, dateStyle[0]);
assertEquals(1, timeStyle.length);
assertEquals(13, timeStyle[0]);
assertEquals(0, era.length);
assertEquals(0, timeZoneName.length);
assertEquals(0, formatMatcher.length);

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: --harmony-intl-datetime-style
var validStyle = ["full", "long", "medium", "short", undefined];
var invalidStyle = ["narrow", "numeric"];
validStyle.forEach(function(dateStyle) {
validStyle.forEach(function(timeStyle) {
assertDoesNotThrow(() =>
new Intl.DateTimeFormat("en", {dateStyle, timeStyle}));
});
invalidStyle.forEach(function(timeStyle) {
assertThrows(() =>
new Intl.DateTimeFormat("en", {dateStyle, timeStyle}), RangeError);
});
}
);
invalidStyle.forEach(function(dateStyle) {
validStyle.forEach(function(timeStyle) {
assertThrows(() =>
new Intl.DateTimeFormat("en", {dateStyle, timeStyle}), RangeError);
});
invalidStyle.forEach(function(timeStyle) {
assertThrows(() =>
new Intl.DateTimeFormat("en", {dateStyle, timeStyle}), RangeError);
});
}
);

View File

@ -0,0 +1,114 @@
// Copyright 2019 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Flags: --harmony-intl-datetime-style
// Throws only once during construction.
// Check for all getters to prevent regression.
// Preserve the order of getter initialization.
let getCount = 0;
let weekday = new Array();
let year = new Array();
let month = new Array();
let day = new Array();
let hour = new Array();
let minute = new Array();
let second = new Array();
let localeMatcher = new Array();
let hour12 = new Array();
let hourCycle = new Array();
let dateStyle = new Array();
let timeStyle = new Array();
let timeZone = new Array();
let era = new Array();
let timeZoneName = new Array();
let formatMatcher = new Array();
new Intl.DateTimeFormat(['en-US'], {
get weekday() {
weekday.push(++getCount);
},
get year() {
year.push(++getCount);
},
get month() {
month.push(++getCount);
},
get day() {
day.push(++getCount);
},
get hour() {
hour.push(++getCount);
},
get minute() {
minute.push(++getCount);
},
get second() {
second.push(++getCount);
},
get localeMatcher() {
localeMatcher.push(++getCount);
},
get hour12() {
hour12.push(++getCount);
},
get hourCycle() {
hourCycle.push(++getCount);
},
get timeZone() {
timeZone.push(++getCount);
},
get dateStyle() {
dateStyle.push(++getCount);
},
get timeStyle() {
timeStyle.push(++getCount);
},
get era() {
era.push(++getCount);
},
get timeZoneName() {
timeZoneName.push(++getCount);
},
get formatMatcher() {
formatMatcher.push(++getCount);
}
});
assertEquals(2, weekday.length);
assertEquals(1, weekday[0]);
assertEquals(1, year.length);
assertEquals(2, year[0]);
assertEquals(1, month.length);
assertEquals(3, month[0]);
assertEquals(1, day.length);
assertEquals(4, day[0]);
assertEquals(2, hour.length);
assertEquals(5, hour[0]);
assertEquals(2, minute.length);
assertEquals(6, minute[0]);
assertEquals(2, second.length);
assertEquals(7, second[0]);
assertEquals(1, localeMatcher.length);
assertEquals(8, localeMatcher[0]);
assertEquals(1, hour12.length);
assertEquals(9, hour12[0]);
assertEquals(1, hourCycle.length);
assertEquals(10, hourCycle[0]);
assertEquals(1, timeZone.length);
assertEquals(11, timeZone[0]);
assertEquals(1, dateStyle.length);
assertEquals(12, dateStyle[0]);
assertEquals(1, timeStyle.length);
assertEquals(13, timeStyle[0]);
assertEquals(14, weekday[1]);
assertEquals(1, era.length);
assertEquals(15, era[0]);
assertEquals(16, hour[1]);
assertEquals(17, minute[1]);
assertEquals(18, second[1]);
assertEquals(1, timeZoneName.length);
assertEquals(19, timeZoneName[0]);
assertEquals(1, formatMatcher.length);
assertEquals(20, formatMatcher[0]);

View File

@ -0,0 +1,108 @@
// Copyright 2019 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Flags: --harmony-intl-datetime-style
// Throws only once during construction.
// Check for all getters to prevent regression.
// Preserve the order of getter initialization.
let getCount = 0;
let weekday = new Array();
let year = new Array();
let month = new Array();
let day = new Array();
let hour = new Array();
let minute = new Array();
let second = new Array();
let localeMatcher = new Array();
let hour12 = new Array();
let hourCycle = new Array();
let dateStyle = new Array();
let timeStyle = new Array();
let timeZone = new Array();
let era = new Array();
let timeZoneName = new Array();
let formatMatcher = new Array();
new Intl.DateTimeFormat(['en-US'], {
get weekday() {
weekday.push(++getCount);
},
get year() {
year.push(++getCount);
},
get month() {
month.push(++getCount);
},
get day() {
day.push(++getCount);
},
get hour() {
hour.push(++getCount);
},
get minute() {
minute.push(++getCount);
},
get second() {
second.push(++getCount);
},
get localeMatcher() {
localeMatcher.push(++getCount);
},
get hour12() {
hour12.push(++getCount);
},
get hourCycle() {
hourCycle.push(++getCount);
},
get timeZone() {
timeZone.push(++getCount);
},
get dateStyle() {
dateStyle.push(++getCount);
},
get timeStyle() {
timeStyle.push(++getCount);
return "full";
},
get era() {
era.push(++getCount);
},
get timeZoneName() {
timeZoneName.push(++getCount);
},
get formatMatcher() {
formatMatcher.push(++getCount);
}
});
assertEquals(1, weekday.length);
assertEquals(1, weekday[0]);
assertEquals(1, year.length);
assertEquals(2, year[0]);
assertEquals(1, month.length);
assertEquals(3, month[0]);
assertEquals(1, day.length);
assertEquals(4, day[0]);
assertEquals(1, hour.length);
assertEquals(5, hour[0]);
assertEquals(1, minute.length);
assertEquals(6, minute[0]);
assertEquals(1, second.length);
assertEquals(7, second[0]);
assertEquals(1, localeMatcher.length);
assertEquals(8, localeMatcher[0]);
assertEquals(1, hour12.length);
assertEquals(9, hour12[0]);
assertEquals(1, hourCycle.length);
assertEquals(10, hourCycle[0]);
assertEquals(1, timeZone.length);
assertEquals(11, timeZone[0]);
assertEquals(1, dateStyle.length);
assertEquals(12, dateStyle[0]);
assertEquals(1, timeStyle.length);
assertEquals(13, timeStyle[0]);
assertEquals(0, era.length);
assertEquals(0, timeZoneName.length);
assertEquals(0, formatMatcher.length);

View File

@ -0,0 +1,54 @@
// Copyright 2019 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Flags: --harmony-intl-datetime-style
// Checks for security holes introduced by Object.property overrides.
// For example:
// Object.defineProperty(Array.prototype, 'locale', {
// set: function(value) {
// throw new Error('blah');
// },
// configurable: true,
// enumerable: false
// });
//
// would throw in case of (JS) x.locale = 'us' or (C++) x->Set('locale', 'us').
//
// First get supported properties.
// Some of the properties are optional, so we request them.
var properties = [];
var options = Intl.DateTimeFormat(
'en-US', {dateStyle: 'full'}).resolvedOptions();
for (var prop in options) {
if (options.hasOwnProperty(prop)) {
properties.push(prop);
}
}
// In the order of Table 6 of
// ecma402 #sec-intl.datetimeformat.prototype.resolvedoptions
var expectedProperties = [
'locale',
'calendar',
'numberingSystem',
'timeZone',
'hourCycle',
'hour12',
'weekday',
'year',
'month',
'day',
'dateStyle',
];
assertEquals(expectedProperties.length, properties.length);
properties.forEach(function(prop) {
assertFalse(expectedProperties.indexOf(prop) === -1);
});
taintProperties(properties);
var locale = Intl.DateTimeFormat().resolvedOptions().locale;

View File

@ -0,0 +1,59 @@
// Copyright 2019 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Flags: --harmony-intl-datetime-style
// Checks for security holes introduced by Object.property overrides.
// For example:
// Object.defineProperty(Array.prototype, 'locale', {
// set: function(value) {
// throw new Error('blah');
// },
// configurable: true,
// enumerable: false
// });
//
// would throw in case of (JS) x.locale = 'us' or (C++) x->Set('locale', 'us').
// First get supported properties.
// Some of the properties are optional, so we request them.
var properties = [];
var options = Intl.DateTimeFormat(
'en-US', {dateStyle: 'full', timeStyle: 'full'}).resolvedOptions();
for (var prop in options) {
if (options.hasOwnProperty(prop)) {
properties.push(prop);
}
}
// In the order of Table 6 of
// ecma402 #sec-intl.datetimeformat.prototype.resolvedoptions
var expectedProperties = [
'locale',
'calendar',
'numberingSystem',
'timeZone',
'hourCycle',
'hour12',
'weekday',
'year',
'month',
'day',
'hour',
'minute',
'second',
'timeZoneName',
'dateStyle',
'timeStyle',
];
assertEquals(expectedProperties.length, properties.length);
properties.forEach(function(prop) {
assertFalse(expectedProperties.indexOf(prop) === -1);
});
taintProperties(properties);
var locale = Intl.DateTimeFormat().resolvedOptions().locale;

View File

@ -0,0 +1,54 @@
// Copyright 2019 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Flags: --harmony-intl-datetime-style
// Checks for security holes introduced by Object.property overrides.
// For example:
// Object.defineProperty(Array.prototype, 'locale', {
// set: function(value) {
// throw new Error('blah');
// },
// configurable: true,
// enumerable: false
// });
//
// would throw in case of (JS) x.locale = 'us' or (C++) x->Set('locale', 'us').
// First get supported properties.
// Some of the properties are optional, so we request them.
var properties = [];
var options = Intl.DateTimeFormat(
'en-US', {timeStyle: 'full'}).resolvedOptions();
for (var prop in options) {
if (options.hasOwnProperty(prop)) {
properties.push(prop);
}
}
// In the order of Table 6 of
// ecma402 #sec-intl.datetimeformat.prototype.resolvedoptions
var expectedProperties = [
'locale',
'calendar',
'numberingSystem',
'timeZone',
'hourCycle',
'hour12',
'hour',
'minute',
'second',
'timeZoneName',
'timeStyle',
];
assertEquals(expectedProperties.length, properties.length);
properties.forEach(function(prop) {
assertFalse(expectedProperties.indexOf(prop) === -1);
});
taintProperties(properties);
var locale = Intl.DateTimeFormat().resolvedOptions().locale;

View File

@ -0,0 +1,8 @@
// 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.
// Environment Variables: TZ=Indian/Kerguelen LANG=uk
assertEquals(
"Fri Feb 01 2019 00:00:00 GMT+0500 (за часом на Французьких Південних і Антарктичних територіях)",
new Date(2019, 1,1).toString());

View File

@ -0,0 +1,10 @@
// 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.
assertTrue(new Intl.DateTimeFormat(
"en", { timeZone: 'UTC', hour: 'numeric'}).resolvedOptions().hour12);
assertFalse(new Intl.DateTimeFormat(
"fr", { timeZone: 'UTC', hour: 'numeric'}).resolvedOptions().hour12);
assertFalse(new Intl.DateTimeFormat(
"de", { timeZone: 'UTC', hour: 'numeric'}).resolvedOptions().hour12);

View File

@ -2,8 +2,6 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Flags: --harmony-intl-relative-time-format
// The following test are not part of the comformance. Just some output in
// English to verify the format does return something reasonable for English.
// It may be changed when we update the CLDR data.

View File

@ -94,4 +94,14 @@ assertEquals('second', parts[3].unit);
assertEquals(3, Object.getOwnPropertyNames(parts[4]).length);
assertEquals('decimal', parts[4].type);
assertEquals('.', parts[4].value);
assertEquals('second', pa
assertEquals('second', parts[4].unit);
// 5: "78"
assertEquals(3, Object.getOwnPropertyNames(parts[4]).length);
assertEquals('fraction', parts[5].type);
assertEquals('78', parts[5].value);
assertEquals('second', parts[5].unit);
// 6: " seconds"
assertEquals(2, Object.getOwnPropertyNames(parts[6]).length);
assertEquals('literal', parts[6].type);
assertEquals(' seconds', parts[6].value);
assertEquals(undefined, parts[6].unit);

View File

@ -0,0 +1,26 @@
// 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.
// Check plural w/ formatToParts
// http://tc39.github.io/proposal-intl-relative-time/
let rtf = new Intl.RelativeTimeFormat();
// Test 1.4.4 Intl.RelativeTimeFormat.prototype.formatToParts( value, unit )
function verifyElement(part, expectedUnit) {
assertEquals(true, part.type == 'literal' || part.type == 'integer');
assertEquals('string', typeof part.value);
if (part.type == 'integer') {
assertEquals('string', typeof part.unit);
assertEquals(expectedUnit, part.unit);
}
};
['year', 'quarter', 'month', 'week', 'day', 'hour', 'minute', 'second'].forEach(
function(unit) {
rtf.formatToParts(100, unit + 's').forEach(
function(part) {
verifyElement(part, unit);
});
});

View File

@ -0,0 +1,80 @@
// 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.
// Make sure that RelativeTimeFormat exposes all required properties. Those not specified
// should have undefined value.
// http://tc39.github.io/proposal-intl-relative-time/
let rtf = new Intl.RelativeTimeFormat();
// Test 1.4.4 Intl.RelativeTimeFormat.prototype.formatToParts( value, unit )
assertEquals(true, Array.isArray(rtf.formatToParts(-1, 'seconds')));
assertEquals(true, Array.isArray(rtf.formatToParts(-1, 'second')));
assertEquals(true, Array.isArray(rtf.formatToParts(-1, 'minutes')));
assertEquals(true, Array.isArray(rtf.formatToParts(-1, 'minute')));
assertEquals(true, Array.isArray(rtf.formatToParts(-1, 'hours')));
assertEquals(true, Array.isArray(rtf.formatToParts(-1, 'hour')));
assertEquals(true, Array.isArray(rtf.formatToParts(-1, 'days')));
assertEquals(true, Array.isArray(rtf.formatToParts(-1, 'day')));
assertEquals(true, Array.isArray(rtf.formatToParts(-1, 'weeks')));
assertEquals(true, Array.isArray(rtf.formatToParts(-1, 'week')));
assertEquals(true, Array.isArray(rtf.formatToParts(-1, 'months')));
assertEquals(true, Array.isArray(rtf.formatToParts(-1, 'month')));
assertEquals(true, Array.isArray(rtf.formatToParts(-1, 'quarters')));
assertEquals(true, Array.isArray(rtf.formatToParts(-1, 'quarter')));
assertEquals(true, Array.isArray(rtf.formatToParts(-1, 'years')));
assertEquals(true, Array.isArray(rtf.formatToParts(-1, 'year')));
assertEquals(true, Array.isArray(rtf.formatToParts(-0, 'seconds')));
assertEquals(true, Array.isArray(rtf.formatToParts(-0, 'second')));
assertEquals(true, Array.isArray(rtf.formatToParts(-0, 'minutes')));
assertEquals(true, Array.isArray(rtf.formatToParts(-0, 'minute')));
assertEquals(true, Array.isArray(rtf.formatToParts(-0, 'hours')));
assertEquals(true, Array.isArray(rtf.formatToParts(-0, 'hour')));
assertEquals(true, Array.isArray(rtf.formatToParts(-0, 'days')));
assertEquals(true, Array.isArray(rtf.formatToParts(-0, 'day')));
assertEquals(true, Array.isArray(rtf.formatToParts(-0, 'weeks')));
assertEquals(true, Array.isArray(rtf.formatToParts(-0, 'week')));
assertEquals(true, Array.isArray(rtf.formatToParts(-0, 'months')));
assertEquals(true, Array.isArray(rtf.formatToParts(-0, 'month')));
assertEquals(true, Array.isArray(rtf.formatToParts(-0, 'quarters')));
assertEquals(true, Array.isArray(rtf.formatToParts(-0, 'quarter')));
assertEquals(true, Array.isArray(rtf.formatToParts(-0, 'years')));
assertEquals(true, Array.isArray(rtf.formatToParts(-0, 'year')));
assertThrows(() => rtf.formatToParts(-1, 'decades'), RangeError);
assertThrows(() => rtf.formatToParts(-1, 'decade'), RangeError);
assertThrows(() => rtf.formatToParts(-1, 'centuries'), RangeError);
assertThrows(() => rtf.formatToParts(-1, 'century'), RangeError);
assertThrows(() => rtf.formatToParts(-1, 'milliseconds'), RangeError);
assertThrows(() => rtf.formatToParts(-1, 'millisecond'), RangeError);
assertThrows(() => rtf.formatToParts(-1, 'microseconds'), RangeError);
assertThrows(() => rtf.formatToParts(-1, 'microsecond'), RangeError);
assertThrows(() => rtf.formatToParts(-1, 'nanoseconds'), RangeError);
assertThrows(() => rtf.formatToParts(-1, 'nanosecond'), RangeError);
assertThrows(() => rtf.formatToParts(NaN, 'seconds'), RangeError);
assertThrows(() => rtf.formatToParts(NaN, 'second'), RangeError);
assertThrows(() => rtf.formatToParts(NaN, 'minutes'), RangeError);
assertThrows(() => rtf.formatToParts(NaN, 'minute'), RangeError);
assertThrows(() => rtf.formatToParts(NaN, 'hours'), RangeError);
assertThrows(() => rtf.formatToParts(NaN, 'hour'), RangeError);
assertThrows(() => rtf.formatToParts(NaN, 'days'), RangeError);
assertThrows(() => rtf.formatToParts(NaN, 'day'), RangeError);
assertThrows(() => rtf.formatToParts(NaN, 'weeks'), RangeError);
assertThrows(() => rtf.formatToParts(NaN, 'week'), RangeError);
assertThrows(() => rtf.formatToParts(NaN, 'months'), RangeError);
assertThrows(() => rtf.formatToParts(NaN, 'month'), RangeError);
assertThrows(() => rtf.formatToParts(NaN, 'years'), RangeError);
assertThrows(() => rtf.formatToParts(NaN, 'year'), RangeError);
assertThrows(() => rtf.formatToParts(NaN, 'quarters'), RangeError);
assertThrows(() => rtf.formatToParts(NaN, 'quarter'), RangeError);
assertEquals(true, Array.isArray(rtf.formatToParts(100, 'day')));
rtf.formatToParts(100, 'day').forEach(function(part) {
assertEquals(true, part.type == 'literal' || part.type == 'integer');
assertEquals('string', typeof part.value);
if (part.type == 'integer') {
assertEquals('string', typeof part.unit);
}
});

View File

@ -0,0 +1,80 @@
// 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.
// Make sure that RelativeTimeFormat exposes all required properties. Those not specified
// should have undefined value.
// http://tc39.github.io/proposal-intl-relative-time/
let rtf = new Intl.RelativeTimeFormat();
// Test 1.4.3 Intl.RelativeTimeFormat.prototype.format( value, unit )
assertEquals('string', typeof rtf.format(-1, 'seconds'));
assertEquals('string', typeof rtf.format(-1, 'second'));
assertEquals('string', typeof rtf.format(-1, 'minutes'));
assertEquals('string', typeof rtf.format(-1, 'minute'));
assertEquals('string', typeof rtf.format(-1, 'hours'));
assertEquals('string', typeof rtf.format(-1, 'hour'));
assertEquals('string', typeof rtf.format(-1, 'days'));
assertEquals('string', typeof rtf.format(-1, 'day'));
assertEquals('string', typeof rtf.format(-1, 'weeks'));
assertEquals('string', typeof rtf.format(-1, 'week'));
assertEquals('string', typeof rtf.format(-1, 'months'));
assertEquals('string', typeof rtf.format(-1, 'month'));
assertEquals('string', typeof rtf.format(-1, 'years'));
assertEquals('string', typeof rtf.format(-1, 'year'));
assertEquals('string', typeof rtf.format(-1, 'quarter'));
assertEquals('string', typeof rtf.format(-1, 'quarters'));
assertEquals('string', typeof rtf.format(-0, 'seconds'));
assertEquals('string', typeof rtf.format(-0, 'second'));
assertEquals('string', typeof rtf.format(-0, 'minutes'));
assertEquals('string', typeof rtf.format(-0, 'minute'));
assertEquals('string', typeof rtf.format(-0, 'hours'));
assertEquals('string', typeof rtf.format(-0, 'hour'));
assertEquals('string', typeof rtf.format(-0, 'days'));
assertEquals('string', typeof rtf.format(-0, 'day'));
assertEquals('string', typeof rtf.format(-0, 'weeks'));
assertEquals('string', typeof rtf.format(-0, 'week'));
assertEquals('string', typeof rtf.format(-0, 'months'));
assertEquals('string', typeof rtf.format(-0, 'month'));
assertEquals('string', typeof rtf.format(-0, 'years'));
assertEquals('string', typeof rtf.format(-0, 'year'));
assertEquals('string', typeof rtf.format(-0, 'quarter'));
assertEquals('string', typeof rtf.format(-0, 'quarters'));
assertThrows(() => rtf.format(NaN, 'seconds'), RangeError);
assertThrows(() => rtf.format(NaN, 'second'), RangeError);
assertThrows(() => rtf.format(NaN, 'minutes'), RangeError);
assertThrows(() => rtf.format(NaN, 'minute'), RangeError);
assertThrows(() => rtf.format(NaN, 'hours'), RangeError);
assertThrows(() => rtf.format(NaN, 'hour'), RangeError);
assertThrows(() => rtf.format(NaN, 'days'), RangeError);
assertThrows(() => rtf.format(NaN, 'day'), RangeError);
assertThrows(() => rtf.format(NaN, 'weeks'), RangeError);
assertThrows(() => rtf.format(NaN, 'week'), RangeError);
assertThrows(() => rtf.format(NaN, 'months'), RangeError);
assertThrows(() => rtf.format(NaN, 'month'), RangeError);
assertThrows(() => rtf.format(NaN, 'years'), RangeError);
assertThrows(() => rtf.format(NaN, 'year'), RangeError);
assertThrows(() => rtf.format(NaN, 'quarters'), RangeError);
assertThrows(() => rtf.format(NaN, 'quarter'), RangeError);
assertThrows(() => rtf.format(-1, 'decades'), RangeError);
assertThrows(() => rtf.format(-1, 'decade'), RangeError);
assertThrows(() => rtf.format(-1, 'centuries'), RangeError);
assertThrows(() => rtf.format(-1, 'century'), RangeError);
assertThrows(() => rtf.format(-1, 'milliseconds'), RangeError);
assertThrows(() => rtf.format(-1, 'millisecond'), RangeError);
assertThrows(() => rtf.format(-1, 'microseconds'), RangeError);
assertThrows(() => rtf.format(-1, 'microsecond'), RangeError);
assertThrows(() => rtf.format(-1, 'nanoseconds'), RangeError);
assertThrows(() => rtf.format(-1, 'nanosecond'), RangeError);
assertEquals('string', typeof rtf.format(5, 'day'));
assertEquals('string', typeof rtf.format('5', 'day'));
assertEquals('string', typeof rtf.format('-5', 'day'));
assertEquals('string', typeof rtf.format('534', 'day'));
assertEquals('string', typeof rtf.format('-534', 'day'));
//assertThrows(() => rtf.format('xyz', 'day'), RangeError);

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.
let rtf = new Intl.RelativeTimeFormat();
// Test 1.4.5 Intl.RelativeTimeFormat.prototype.resolvedOptions ()
// The default style is 'long'
assertEquals('long', rtf.resolvedOptions().style);
// The default numeric is 'always'
assertEquals('always', rtf.resolvedOptions().numeric);
// contains style, numeric and locale key
assertEquals(4, Object.getOwnPropertyNames(rtf.resolvedOptions()).length);
// contains style, numeric and locale key
assertEquals(
4,
Object.getOwnPropertyNames(
new Intl.RelativeTimeFormat("en").resolvedOptions()
).length
);
assertEquals(
'short',
(new Intl.RelativeTimeFormat(['sr'], {style: 'short'}))
.resolvedOptions().style);
assertEquals(
'always',
(new Intl.RelativeTimeFormat(['sr'], {style: 'short'}))
.resolvedOptions().numeric);
assertEquals(
'narrow',
(new Intl.RelativeTimeFormat(['sr'], {style: 'narrow'}))
.resolvedOptions().style);
assertEquals(
'always',
(new Intl.RelativeTimeFormat(['sr'], {style: 'narrow'}))
.resolvedOptions().numeric);
assertEquals(
'long',
(new Intl.RelativeTimeFormat(['sr'], {style: 'long'}))
.resolvedOptions().style);
assertEquals(
'always',
(new Intl.RelativeTimeFormat(['sr'], {style: 'long'}))
.resolvedOptions().numeric);
assertEquals(
'auto',
(new Intl.RelativeTimeFormat(['sr'], {numeric: 'auto'}))
.resolvedOptions().numeric);
assertEquals(
'long',
(new Intl.RelativeTimeFormat(['sr'], {numeric: 'auto'}))
.resolvedOptions().style);
assertEquals(
'always',
(new Intl.RelativeTimeFormat(['sr'], {numeric: 'always'}))
.resolvedOptions().numeric);
assertEquals(
'long',
(new Intl.RelativeTimeFormat(['sr'], {numeric: 'always'}))
.resolvedOptions().style);
assertEquals(
'long',
(new Intl.RelativeTimeFormat(['sr'], {style: 'long', numeric: 'auto'}))
.resolvedOptions().style);
assertEquals(
'auto',
(new Intl.RelativeTimeFormat(['sr'], {style: 'long', numeric: 'auto'}))
.resolvedOptions().numeric);
assertEquals(
'long',
(new Intl.RelativeTimeFormat(['sr'], {style: 'long', numeric: 'always'}))
.resolvedOptions().style);
assertEquals(
'always',
(new Intl.RelativeTimeFormat(['sr'], {style: 'long', numeric: 'always'}))
.resolvedOptions().numeric);
assertEquals(
'short',
(new Intl.RelativeTimeFormat(['sr'], {style: 'short', numeric: 'auto'}))
.resolvedOptions().style);
assertEquals(
'auto',
(new Intl.RelativeTimeFormat(['sr'], {style: 'short', numeric: 'auto'}))
.resolvedOptions().numeric);
assertEquals(
'short',
(new Intl.RelativeTimeFormat(['sr'], {style: 'short', numeric: 'always'}))
.resolvedOptions().style);
assertEquals(
'always',
(new Intl.RelativeTimeFormat(['sr'], {style: 'short', numeric: 'always'}))
.resolvedOptions().numeric);
assertEquals(
'narrow',
(new Intl.RelativeTimeFormat(['sr'], {style: 'narrow', numeric: 'auto'}))
.resolvedOptions().style);
assertEquals(
'auto',
(new Intl.RelativeTimeFormat(['sr'], {style: 'narrow', numeric: 'auto'}))
.resolvedOptions().numeric);
assertEquals(
'narrow',
(new Intl.RelativeTimeFormat(['sr'], {style: 'narrow', numeric: 'always'}))
.resolvedOptions().style);
assertEquals(
'always',
(new Intl.RelativeTimeFormat(['sr'], {style: 'narrow', numeric: 'always'}))
.resolvedOptions().numeric);
assertEquals(
'ar',
(new Intl.RelativeTimeFormat(['ar'])).resolvedOptions().locale);
assertEquals(
'ar',
(new Intl.RelativeTimeFormat(['ar', 'en'])).resolvedOptions().locale);
assertEquals(
'fr',
(new Intl.RelativeTimeFormat(['fr', 'en'])).resolvedOptions().locale);
assertEquals(
'ar',
(new Intl.RelativeTimeFormat(['xyz', 'ar'])).resolvedOptions().locale);
{
var receiver = 1;
assertThrows(() =>
Intl.RelativeTimeFormat.prototype.resolvedOptions.call(receiver), TypeError);
receiver = {};
assertThrows(() =>
Intl.RelativeTimeFormat.prototype.resolvedOptions.call(receiver), TypeError);
}
assertEquals(
'ar',
(new Intl.RelativeTimeFormat(['i-default', 'ar'])).resolvedOptions().locale);

View File

@ -0,0 +1,18 @@
// 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(typeof Intl.RelativeTimeFormat.supportedLocalesOf, "function",
"Intl.RelativeTimeFormat.supportedLocalesOf should be a function");
var undef = Intl.RelativeTimeFormat.supportedLocalesOf();
assertEquals([], undef);
var empty = Intl.RelativeTimeFormat.supportedLocalesOf([]);
assertEquals([], empty);
var strLocale = Intl.RelativeTimeFormat.supportedLocalesOf('sr');
assertEquals('sr', strLocale[0]);
var multiLocale = ['sr-Thai-RS', 'de', 'zh-CN'];
assertEquals(multiLocale, Intl.RelativeTimeFormat.supportedLocalesOf(multiLocale));

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.
// Flags: --harmony-intl-segmenter
let invalid_lb = [
"invalid",
"abce",
"breakall",
"keepall",
"none",
"standard",
"strict",
"normal",
"loose",
];
let locales = [
"en",
"ja",
"zh",
];
invalid_lb.forEach(function(lb) {
let df = new Intl.Segmenter(["en-u-lb-" + lb + "-fo-obar"]);
assertEquals("en", df.resolvedOptions().locale);
}
);

View File

@ -0,0 +1,20 @@
// 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: --harmony-intl-segmenter
// Throws only once during construction.
// Check for all getters to prevent regression.
// Preserve the order of getter initialization.
let getCount = 0;
new Intl.Segmenter(['en-US'], {
get localeMatcher() {
assertEquals(0, getCount++);
},
get granularity() {
assertEquals(1, getCount++);
},
});
assertEquals(2, getCount);

View File

@ -0,0 +1,190 @@
// 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: --harmony-intl-segmenter
// Segmenter constructor can't be called as function.
assertThrows(() => Intl.Segmenter(["sr"]), TypeError);
// Invalid locale string.
assertThrows(() => new Intl.Segmenter(["abcdefghi"]), RangeError);
assertDoesNotThrow(() => new Intl.Segmenter(["sr"], {}), TypeError);
assertDoesNotThrow(() => new Intl.Segmenter([], {}));
assertDoesNotThrow(() => new Intl.Segmenter(["fr", "ar"], {}));
assertDoesNotThrow(() => new Intl.Segmenter({ 0: "ja", 1: "fr" }, {}));
assertDoesNotThrow(() => new Intl.Segmenter({ 1: "ja", 2: "fr" }, {}));
assertDoesNotThrow(() => new Intl.Segmenter(["sr"]));
assertDoesNotThrow(() => new Intl.Segmenter());
assertDoesNotThrow(
() =>
new Intl.Segmenter(["sr"], {
lineBreakStyle: "strict",
granularity: "grapheme"
})
);
assertDoesNotThrow(
() => new Intl.Segmenter(["sr"], { granularity: "sentence" })
);
assertDoesNotThrow(() => new Intl.Segmenter(["sr"], { granularity: "word" }));
assertDoesNotThrow(
() => new Intl.Segmenter(["sr"], { granularity: "grapheme" })
);
assertThrows(() => new Intl.Segmenter(["sr"], { granularity: "line" }), RangeError);
assertThrows(
() => new Intl.Segmenter(["sr"], { granularity: "standard" }),
RangeError
);
assertDoesNotThrow(
() => new Intl.Segmenter(["sr"], { lineBreakStyle: "normal" })
);
assertDoesNotThrow(
() => new Intl.Segmenter(["sr"], { lineBreakStyle: "strict" })
);
assertDoesNotThrow(
() => new Intl.Segmenter(["sr"], { lineBreakStyle: "loose" })
);
assertDoesNotThrow(
() => new Intl.Segmenter(["sr"], { lineBreakStyle: "giant" })
);
assertDoesNotThrow(
() =>
new Intl.Segmenter(["sr"], {
granularity: "sentence",
lineBreakStyle: "normal"
})
);
assertDoesNotThrow(
() =>
new Intl.Segmenter(["sr"], {
granularity: "sentence",
lineBreakStyle: "strict"
})
);
assertDoesNotThrow(
() =>
new Intl.Segmenter(["sr"], {
granularity: "sentence",
lineBreakStyle: "loose"
})
);
assertDoesNotThrow(
() =>
new Intl.Segmenter(["sr"], {
granularity: "word",
lineBreakStyle: "normal"
})
);
assertDoesNotThrow(
() =>
new Intl.Segmenter(["sr"], {
granularity: "word",
lineBreakStyle: "strict"
})
);
assertDoesNotThrow(
() =>
new Intl.Segmenter(["sr"], {
granularity: "word",
lineBreakStyle: "loose"
})
);
assertDoesNotThrow(
() =>
new Intl.Segmenter(["sr"], {
granularity: "grapheme",
lineBreakStyle: "normal"
})
);
assertDoesNotThrow(
() =>
new Intl.Segmenter(["sr"], {
granularity: "grapheme",
lineBreakStyle: "strict"
})
);
assertDoesNotThrow(
() =>
new Intl.Segmenter(["sr"], {
granularity: "grapheme",
lineBreakStyle: "loose"
})
);
assertThrows(
() =>
new Intl.Segmenter(["sr"], {
granularity: "line",
lineBreakStyle: "loose"
}), RangeError
);
assertThrows(
() =>
new Intl.Segmenter(["sr"], {
granularity: "line",
lineBreakStyle: "normal"
}), RangeError
);
assertThrows(
() =>
new Intl.Segmenter(["sr"], {
granularity: "line",
lineBreakStyle: "strict"
}), RangeError
);
// propagate exception from getter
assertThrows(
() =>
new Intl.Segmenter(undefined, {
get localeMatcher() {
throw new TypeError("");
}
}),
TypeError
);
assertDoesNotThrow(
() =>
new Intl.Segmenter(undefined, {
get lineBreakStyle() {
throw new TypeError("");
}
})
);
assertThrows(
() =>
new Intl.Segmenter(undefined, {
get granularity() {
throw new TypeError("");
}
}),
TypeError
);

View File

@ -0,0 +1,15 @@
// 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: --harmony-intl-segmenter
const text = "Hello World, Test 123! Foo Bar. How are you?";
for (const granularity of ["grapheme", "word", "sentence"]) {
const segmenter = new Intl.Segmenter("en", { granularity });
const iter = segmenter.segment(text);
assertEquals("number", typeof iter.index);
assertEquals(0, iter.index);
assertEquals(undefined, iter.breakType);
}

View File

@ -567,6 +567,27 @@ function TestPrototypeHoles() {
}
TestPrototypeHoles();
// The following test ensures that elements on the prototype are also copied
// for JSArrays and not only JSObjects.
function TestArrayPrototypeHasElements() {
let array = [1, 2, 3, 4, 5];
for (let i = 0; i < array.length; i++) {
delete array[i];
Object.prototype[i] = 42;
}
let comparator_called = false;
array.sort(function (a, b) {
if (a === 42 || b === 42) {
comparator_called = true;
}
return a - b;
});
assertTrue(comparator_called);
}
TestArrayPrototypeHasElements();
// The following Tests make sure that there is no crash when the element kind
// or the array length changes. Since comparison functions like this are not
// consistent, we do not have to make sure that the array is actually sorted

View File

@ -0,0 +1,28 @@
// 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
function g(code) {
try {
if (typeof code === 'function') {
+Symbol();
} else {
eval();
}
} catch (e) {
return;
}
dummy();
}
function f() {
g(g);
}
try { g(); } catch(e) {; }
f();
%OptimizeFunctionOnNextCall(f);
f();

View File

@ -0,0 +1,196 @@
// 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.
function checkIsRedeclarationError(code) {
try {
eval(`
checkIsRedeclarationError: {
break checkIsRedeclarationError;
${code}
}
`);
assertUnreachable();
} catch (e) {
assertInstanceof(e, SyntaxError);
assertTrue(e.toString().includes("has already been declared"));
}
}
function checkIsNotRedeclarationError(code) {
assertDoesNotThrow(() => eval(`
checkIsNotRedeclarationError_label: {
break checkIsNotRedeclarationError_label;
${code}
}
`));
}
let var_e = [
'var e',
'var {e}',
'var {f, e}',
'var [e]',
'var {f:e}',
'var [[[], e]]'
];
let not_var_e = [
'var f',
'var {}',
'var {e:f}',
'e',
'{e}',
'let e',
'const e',
'let {e}',
'const {e}',
'let [e]',
'const [e]',
'let {f:e}',
'const {f:e}'
];
// Check that both `for (var ... of ...)` and `for (var ... in ...)`
// can redeclare a simple catch variable.
for (let binding of var_e) {
checkIsNotRedeclarationError(`
try {
throw 0;
} catch (e) {
for (${binding} of []);
}
`);
checkIsNotRedeclarationError(`
try {
throw 0;
} catch (e) {
for (${binding} in []);
}
`);
}
// Check that the above applies even for nested catches.
for (let binding of var_e) {
checkIsNotRedeclarationError(`
try {
throw 0;
} catch (e) {
try {
throw 1;
} catch (f) {
try {
throw 2;
} catch ({}) {
for (${binding} of []);
}
}
}
`);
checkIsNotRedeclarationError(`
try {
throw 0;
} catch (e) {
try {
throw 1;
} catch (f) {
try {
throw 2;
} catch ({}) {
for (${binding} in []);
}
}
}
`);
}
// Check that the above applies if a declaration scope is between the
// catch and the loop.
for (let binding of var_e) {
checkIsNotRedeclarationError(`
try {
throw 0;
} catch (e) {
(()=>{for (${binding} of []);})();
}
`);
checkIsNotRedeclarationError(`
try {
throw 0;
} catch (e) {
(function() {
for (${binding} of []);
})();
}
`);
}
// Check that there is no error when not declaring a var named e.
for (let binding of not_var_e) {
checkIsNotRedeclarationError(`
try {
throw 0;
} catch (e) {
for (${binding} of []);
}
`);
}
// Check that there is an error for both for-in and for-of when redeclaring
// a non-simple catch parameter.
for (let binding of var_e) {
checkIsRedeclarationError(`
try {
throw 0;
} catch ({e}) {
for (${binding} of []);
}
`);
checkIsRedeclarationError(`
try {
throw 0;
} catch ({e}) {
for (${binding} in []);
}
`);
}
// Check that the above error occurs even for nested catches.
for (let binding of var_e) {
checkIsRedeclarationError(`
try {
throw 0;
} catch ({e}) {
try {
throw 1;
} catch (f) {
try {
throw 2;
} catch ({}) {
for (${binding} of []);
}
}
}
`);
checkIsRedeclarationError(`
try {
throw 0;
} catch ({e}) {
try {
throw 1;
} catch (f) {
try {
throw 2;
} catch ({}) {
for (${binding} in []);
}
}
}
`);
}

View File

@ -0,0 +1,94 @@
// Copyright 2015 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 target = {
"target_one": 1
};
target.__proto__ = {
"target_proto_two": 2
};
var handler = {
ownKeys: function(target) {
return ["foo", "bar"];
}
}
var proxy = new Proxy(target, handler);
// Simple case.
assertEquals(["foo", "bar"], Reflect.ownKeys(proxy));
// Test interesting steps of the algorithm:
// Step 6: Fall through to target.[[OwnPropertyKeys]] if the trap is undefined.
handler.ownKeys = undefined;
assertEquals(["target_one"], Reflect.ownKeys(proxy));
// Step 7: Throwing traps don't crash.
handler.ownKeys = function(target) { throw 1; };
assertThrows("Reflect.ownKeys(proxy)");
// Step 8: CreateListFromArrayLike error cases:
// Returning a non-Object throws.
var keys = 1;
handler.ownKeys = function(target) { return keys; };
assertThrows("Reflect.ownKeys(proxy)", TypeError);
keys = "string";
assertThrows("Reflect.ownKeys(proxy)", TypeError);
keys = Symbol("foo");
assertThrows("Reflect.ownKeys(proxy)", TypeError);
keys = null;
assertThrows("Reflect.ownKeys(proxy)", TypeError);
// "length" property is honored.
keys = { 0: "a", 1: "b", 2: "c" };
keys.length = 0;
assertEquals([], Reflect.ownKeys(proxy));
keys.length = 1;
assertEquals(["a"], Reflect.ownKeys(proxy));
keys.length = 3;
assertEquals(["a", "b", "c"], Reflect.ownKeys(proxy));
// The spec wants to allow lengths up to 2^53, but we can't allocate arrays
// of that size, so we throw even for smaller values.
keys.length = Math.pow(2, 33);
assertThrows("Reflect.ownKeys(proxy)", RangeError);
// Check that we don't allow duplicated keys.
keys = ['a', 'a', 'a']
assertThrows("Reflect.ownKeys(proxy)", TypeError);
// Non-Name results throw.
keys = [1];
assertThrows("Reflect.ownKeys(proxy)", TypeError);
keys = [{}];
assertThrows("Reflect.ownKeys(proxy)", TypeError);
keys = [{toString: function() { return "foo"; }}];
assertThrows("Reflect.ownKeys(proxy)", TypeError);
keys = [null];
assertThrows("Reflect.ownKeys(proxy)", TypeError);
// Step 17a: The trap result must include all non-configurable keys.
Object.defineProperty(target, "nonconf", {value: 1, configurable: false});
keys = ["foo"];
assertThrows("Reflect.ownKeys(proxy)", TypeError);
keys = ["nonconf"];
assertEquals(keys, Reflect.ownKeys(proxy));
// Check that we don't allow duplicated keys.
keys = ['nonconf', 'nonconf', 'nonconf']
assertThrows("Reflect.ownKeys(proxy)", TypeError);
// Step 19a: The trap result must all keys of a non-extensible target.
Object.preventExtensions(target);
assertThrows("Reflect.ownKeys(proxy)", TypeError);
keys = ["nonconf", "target_one"];
assertEquals(keys, Reflect.ownKeys(proxy));
// Step 20: The trap result must not add keys to a non-extensible target.
keys = ["nonconf", "target_one", "fantasy"];
assertThrows("Reflect.ownKeys(proxy)", TypeError);
// Check that we don't allow duplicated keys.
keys = ['nonconf', 'target_one', 'nonconf', 'nonconf', 'target_one',]
assertThrows("Reflect.ownKeys(proxy)", TypeError);

View File

@ -0,0 +1,151 @@
// Copyright 2015 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
var typedArrayConstructors = [
Uint8Array,
Int8Array,
Uint16Array,
Int16Array,
Uint32Array,
Int32Array,
Uint8ClampedArray,
Float32Array,
Float64Array
];
function assertArrayLikeEquals(value, expected, type) {
assertEquals(value.__proto__, type.prototype);
// Don't test value.length because we mess with that;
// instead in certain callsites we check that length
// is set appropriately.
for (var i = 0; i < expected.length; ++i) {
// Use Object.is to differentiate between +-0
assertSame(expected[i], value[i]);
}
}
for (var constructor of typedArrayConstructors) {
// Test default numerical sorting order
var a = new constructor([100, 7, 45])
assertEquals(a.sort(), a);
assertArrayLikeEquals(a, [7, 45, 100], constructor);
assertEquals(a.length, 3);
// For arrays of floats, certain handling of +-0/NaN
if (constructor === Float32Array || constructor === Float64Array) {
var b = new constructor([+0, -0, NaN, -0, NaN, +0])
b.sort();
assertArrayLikeEquals(b, [-0, -0, +0, +0, NaN, NaN], constructor);
assertEquals(b.length, 6);
}
// Custom sort--backwards
a.sort(function(x, y) { return y - x; });
assertArrayLikeEquals(a, [100, 45, 7], constructor);
// Basic TypedArray method properties:
// Length field is ignored
Object.defineProperty(a, 'length', {value: 1});
assertEquals(a.sort(), a);
assertArrayLikeEquals(a, [7, 45, 100], constructor);
assertEquals(a.length, 1);
// Method doesn't work on other objects
assertThrows(function() { a.sort.call([]); }, TypeError);
// Do not touch elements out of byte offset
var buf = new ArrayBuffer(constructor.BYTES_PER_ELEMENT * 3);
var a = new constructor(buf, constructor.BYTES_PER_ELEMENT);
var b = new constructor(buf);
b[0] = 3; b[1] = 2; b[2] = 1;
a.sort();
assertArrayLikeEquals(a, [1, 2], constructor);
// Detached Operation
var array = new constructor([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);
%ArrayBufferDetach(array.buffer);
assertThrows(() => array.sort(), TypeError);
}
// Check that TypedArray.p.sort is stable.
for (let constructor of typedArrayConstructors) {
// Sort an array [0..kSize-1] modulo 4. If the sort is stable, the array
// will be partitioned into 4 parts, where each part has only increasing
// elements.
const kSize = 128;
const kModulo = 4;
const kRunSize = kSize / kModulo;
const template = Array.from({ length: kSize }, (_, i) => i);
const array = new constructor(template);
const compare = (a, b) => (b % kModulo) - (a % kModulo);
array.sort(compare);
function assertIncreasing(from) {
for (let i = from + 1; i < from + kRunSize; ++i) {
assertTrue(array[i - 1] < array[i]);
assertEquals(array[i - 1] % kModulo, array[i] % kModulo);
}
}
for (let i = 0; i < kModulo; ++i) assertIncreasing(i * kRunSize);
}
// The following creates a test for each typed element kind, where the array
// to sort consists of some max/min/zero elements.
//
// When providing a custom compare function, the torque version of
// TypedArray.p.sort needs to convert array elements to "Number"/"BigInt"
// and back. The following test checks the edge cases for that conversion.
let constructorsWithArrays = [
{ctor: Uint8Array, array: [255, 254, 4, 3, 2, 1, 0]},
{ctor: Int8Array, array: [127, 126, 1, 0, -1, -127, -128]},
{ctor: Uint16Array, array: [2 ** 16 - 1, 2 ** 16 - 2, 4, 3, 2, 1, 0]},
{
ctor: Int16Array,
array: [2 ** 15 - 1, 2 ** 15 - 2, 1, 0, -1, -(2 ** 15 - 1), -(2 ** 15)]
},
{ctor: Uint32Array, array: [2 ** 32 - 1, 2 ** 32 - 2, 4, 3, 2, 1, 0]},
{
ctor: Int32Array,
array: [2 ** 31 - 1, 2 ** 31 - 2, 1, 0, -1, -(2 ** 31 - 1), -(2 ** 31)]
},
{
ctor: Float32Array,
array: [2 ** 24, 2 ** 24 - 1, 1, 0,-1, -(2 ** 24 - 1), -(2 ** 24)]
},
{
ctor: Float64Array,
array: [2 ** 53, 2 ** 53 - 1, 1, 0, -1, -(2 ** 53 - 1), -(2 ** 53)]
},
{ctor: Uint8ClampedArray, array: [255, 254, 4, 3, 2, 1, 0]},
{
ctor: BigUint64Array,
array: [2n ** 64n - 1n, 2n ** 64n - 2n, 4n, 3n, 2n, 1n, 0n]
},
{
ctor: BigInt64Array,
array: [2n ** 63n - 1n, 2n ** 63n - 2n, 1n, 0n,
-1n, -(2n ** 63n - 1n), -(2n ** 63n)]
}
];
// Compare function needs to return a Number in all cases, and not a BigInt.
// Hence we can not simply return "a - b".
function cmpfn(a, b) {
if (a < b) return -1;
if (b < a) return 1;
return 0;
}
for (let constructor of constructorsWithArrays) {
let array = new constructor.ctor(constructor.array);
assertEquals(array.sort(cmpfn), array);
assertArrayLikeEquals(array, constructor.array.reverse(), constructor.ctor);
assertEquals(array.length, constructor.array.length);
}

View File

@ -144,29 +144,11 @@ function TestOrderWithDuplicates(withWarmup) {
});
if (withWarmup) {
for (const key in P) {}
for (const key in O) {};
try { for (const key in P) {} } catch {};
}
log = [];
assertEquals([
["a", 1],
["a", 1],
["456", 123],
["456", 123]
], Object.entries(P));
assertEquals([
"[[OwnPropertyKeys]]",
"[[GetOwnProperty]](\"a\")",
"[[Get]](\"a\")",
"[[GetOwnProperty]](\"a\")",
"[[Get]](\"a\")",
"[[GetOwnProperty]](\"456\")",
"[[Get]](\"456\")",
"[[GetOwnProperty]](\"HIDDEN\")",
"[[GetOwnProperty]](\"HIDDEN\")",
"[[GetOwnProperty]](\"456\")",
"[[Get]](\"456\")"
], log);
assertThrows(() => Object.entries(P), TypeError);
}
TestOrderWithDuplicates();
TestOrderWithDuplicates(true);

View File

@ -0,0 +1,220 @@
// 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.
// Flags: --allow-natives-syntax
function DataDescriptor(value) {
return { "enumerable": true, "configurable": true, "writable": true, value };
}
function TestMeta() {
assertEquals(1, Object.getOwnPropertyDescriptors.length);
assertEquals(Function.prototype,
Object.getPrototypeOf(Object.getOwnPropertyDescriptors));
assertEquals(
'getOwnPropertyDescriptors', Object.getOwnPropertyDescriptors.name);
var desc = Reflect.getOwnPropertyDescriptor(
Object, 'getOwnPropertyDescriptors');
assertFalse(desc.enumerable);
assertTrue(desc.writable);
assertTrue(desc.configurable);
}
TestMeta();
function TestToObject() {
assertThrows(function() {
Object.getOwnPropertyDescriptors(null);
}, TypeError);
assertThrows(function() {
Object.getOwnPropertyDescriptors(undefined);
}, TypeError);
assertThrows(function() {
Object.getOwnPropertyDescriptors();
}, TypeError);
}
TestToObject();
function TestPrototypeProperties() {
function F() {};
F.prototype.a = "A";
F.prototype.b = "B";
var F2 = new F();
Object.defineProperties(F2, {
"b": {
enumerable: false,
configurable: true,
writable: false,
value: "Shadowed 'B'"
},
"c": {
enumerable: false,
configurable: true,
writable: false,
value: "C"
}
});
assertEquals({
"b": {
enumerable: false,
configurable: true,
writable: false,
value: "Shadowed 'B'"
},
"c": {
enumerable: false,
configurable: true,
writable: false,
value: "C"
}
}, Object.getOwnPropertyDescriptors(F2));
}
TestPrototypeProperties();
function TestPrototypeProperties() {
function F() {};
F.prototype.a = "A";
F.prototype.b = "B";
var F2 = new F();
Object.defineProperties(F2, {
"b": {
enumerable: false,
configurable: true,
writable: false,
value: "Shadowed 'B'"
},
"c": {
enumerable: false,
configurable: true,
writable: false,
value: "C"
}
});
assertEquals({
"b": {
enumerable: false,
configurable: true,
writable: false,
value: "Shadowed 'B'"
},
"c": {
enumerable: false,
configurable: true,
writable: false,
value: "C"
}
}, Object.getOwnPropertyDescriptors(F2));
}
TestPrototypeProperties();
function TestTypeFilteringAndOrder() {
var log = [];
var sym = Symbol("foo");
var psym = %CreatePrivateSymbol("private");
var O = {
0: 0,
[sym]: 3,
"a": 2,
[psym]: 4,
1: 1,
};
var P = new Proxy(O, {
ownKeys(target) {
log.push("ownKeys()");
return Reflect.ownKeys(target);
},
getOwnPropertyDescriptor(target, name) {
log.push(`getOwnPropertyDescriptor(${String(name)})`);
return Reflect.getOwnPropertyDescriptor(target, name);
},
get(target, name) { assertUnreachable(); },
set(target, name, value) { assertUnreachable(); },
deleteProperty(target, name) { assertUnreachable(); },
defineProperty(target, name, desc) { assertUnreachable(); }
});
var result1 = Object.getOwnPropertyDescriptors(O);
assertEquals({
0: DataDescriptor(0),
1: DataDescriptor(1),
"a": DataDescriptor(2),
[sym]: DataDescriptor(3)
}, result1);
var result2 = Object.getOwnPropertyDescriptors(P);
assertEquals([
"ownKeys()",
"getOwnPropertyDescriptor(0)",
"getOwnPropertyDescriptor(1)",
"getOwnPropertyDescriptor(a)",
"getOwnPropertyDescriptor(Symbol(foo))"
], log);
assertEquals({
0: DataDescriptor(0),
1: DataDescriptor(1),
"a": DataDescriptor(2),
[sym]: DataDescriptor(3)
}, result2);
}
TestTypeFilteringAndOrder();
function TestDuplicateKeys() {
var i = 0;
var log = [];
var P = new Proxy({}, {
ownKeys() {
log.push(`ownKeys()`);
return ["A", "A"];
},
getOwnPropertyDescriptor(t, name) {
log.push(`getOwnPropertyDescriptor(${name})`);
if (i++) return;
return {
configurable: true,
writable: false,
value: "VALUE"
};
},
get(target, name) { assertUnreachable(); },
set(target, name, value) { assertUnreachable(); },
deleteProperty(target, name) { assertUnreachable(); },
defineProperty(target, name, desc) { assertUnreachable(); }
});
assertThrows(() => Object.getOwnPropertyDescriptors(P), TypeError);
}
TestDuplicateKeys();
function TestFakeProperty() {
var log = [];
var P = new Proxy({}, {
ownKeys() {
log.push(`ownKeys()`);
return ["fakeProperty"];
},
getOwnPropertyDescriptor(target, name) {
log.push(`getOwnPropertyDescriptor(${name})`);
return;
}
});
var result = Object.getOwnPropertyDescriptors(P);
assertEquals({}, result);
assertFalse(result.hasOwnProperty("fakeProperty"));
assertEquals([
"ownKeys()",
"getOwnPropertyDescriptor(fakeProperty)"
], log);
}
TestFakeProperty();

View File

@ -0,0 +1,278 @@
// 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.
// Flags: --allow-natives-syntax
function TestMeta() {
assertEquals(1, Object.values.length);
assertEquals(Function.prototype, Object.getPrototypeOf(Object.values));
assertEquals("values", Object.values.name);
var descriptor = Object.getOwnPropertyDescriptor(Object, "values");
assertTrue(descriptor.writable);
assertFalse(descriptor.enumerable);
assertTrue(descriptor.configurable);
assertThrows(() => new Object.values({}), TypeError);
}
TestMeta();
function TestBasic() {
var x = 16;
var O = {
d: 1,
c: 3,
[Symbol.iterator]: void 0,
0: 123,
1000: 456,
[x * x]: "ducks",
[`0x${(x * x).toString(16)}`]: "quack"
};
O.a = 2;
O.b = 4;
Object.defineProperty(O, "HIDDEN", { enumerable: false, value: NaN });
assertEquals([123, "ducks", 456, 1, 3, "quack", 2, 4], Object.values(O));
assertEquals(Object.values(O), Object.keys(O).map(key => O[key]));
assertTrue(Array.isArray(Object.values({})));
assertEquals(0, Object.values({}).length);
}
TestBasic();
function TestToObject() {
assertThrows(function() { Object.values(); }, TypeError);
assertThrows(function() { Object.values(null); }, TypeError);
assertThrows(function() { Object.values(void 0); }, TypeError);
}
TestToObject();
function TestOrder() {
var O = {
a: 1,
[Symbol.iterator]: null
};
O[456] = 123;
Object.defineProperty(O, "HIDDEN", { enumerable: false, value: NaN });
var priv = %CreatePrivateSymbol("Secret");
O[priv] = 56;
var log = [];
var P = new Proxy(O, {
ownKeys(target) {
log.push("[[OwnPropertyKeys]]");
return Reflect.ownKeys(target);
},
get(target, name) {
log.push(`[[Get]](${JSON.stringify(name)})`);
return Reflect.get(target, name);
},
getOwnPropertyDescriptor(target, name) {
log.push(`[[GetOwnProperty]](${JSON.stringify(name)})`);
return Reflect.getOwnPropertyDescriptor(target, name);
},
set(target, name, value) {
assertUnreachable();
}
});
assertEquals([123, 1], Object.values(P));
assertEquals([
"[[OwnPropertyKeys]]",
"[[GetOwnProperty]](\"456\")",
"[[Get]](\"456\")",
"[[GetOwnProperty]](\"a\")",
"[[Get]](\"a\")",
"[[GetOwnProperty]](\"HIDDEN\")"
], log);
}
TestOrder();
function TestOrderWithDuplicates() {
var O = {
a: 1,
[Symbol.iterator]: null
};
O[456] = 123;
Object.defineProperty(O, "HIDDEN", { enumerable: false, value: NaN });
O[priv] = 56;
var priv = %CreatePrivateSymbol("private");
var log = [];
var P = new Proxy(O, {
ownKeys(target) {
log.push("[[OwnPropertyKeys]]");
return [ "a", Symbol.iterator, "a", "456", "HIDDEN", "HIDDEN", "456" ];
},
get(target, name) {
log.push(`[[Get]](${JSON.stringify(name)})`);
return Reflect.get(target, name);
},
getOwnPropertyDescriptor(target, name) {
log.push(`[[GetOwnProperty]](${JSON.stringify(name)})`);
return Reflect.getOwnPropertyDescriptor(target, name);
},
set(target, name, value) {
assertUnreachable();
}
});
assertThrows(() => Object.values(P), TypeError);
}
TestOrderWithDuplicates();
function TestPropertyFilter() {
var object = { prop3: 30 };
object[2] = 40;
object["prop4"] = 50;
Object.defineProperty(object, "prop5", { value: 60, enumerable: true });
Object.defineProperty(object, "prop6", { value: 70, enumerable: false });
Object.defineProperty(object, "prop7", {
enumerable: true, get() { return 80; }});
var sym = Symbol("prop8");
object[sym] = 90;
values = Object.values(object);
assertEquals(5, values.length);
assertEquals([40,30,50,60,80], values);
}
TestPropertyFilter();
function TestWithProxy() {
var obj1 = {prop1:10};
var proxy1 = new Proxy(obj1, { });
assertEquals([10], Object.values(proxy1));
var obj2 = {};
Object.defineProperty(obj2, "prop2", { value: 20, enumerable: true });
Object.defineProperty(obj2, "prop3", {
get() { return 30; }, enumerable: true });
var proxy2 = new Proxy(obj2, {
getOwnPropertyDescriptor(target, name) {
return Reflect.getOwnPropertyDescriptor(target, name);
}
});
assertEquals([20, 30], Object.values(proxy2));
var obj3 = {};
var count = 0;
var proxy3 = new Proxy(obj3, {
get(target, property, receiver) {
return count++ * 5;
},
getOwnPropertyDescriptor(target, property) {
return { configurable: true, enumerable: true };
},
ownKeys(target) {
return [ "prop0", "prop1", Symbol("prop2"), Symbol("prop5") ];
}
});
assertEquals([0, 5], Object.values(proxy3));
}
TestWithProxy();
function TestMutateDuringEnumeration() {
var aDeletesB = {
get a() {
delete this.b;
return 1;
},
b: 2
};
assertEquals([1], Object.values(aDeletesB));
var aRemovesB = {
get a() {
Object.defineProperty(this, "b", { enumerable: false });
return 1;
},
b: 2
};
assertEquals([1], Object.values(aRemovesB));
var aAddsB = { get a() { this.b = 2; return 1; } };
assertEquals([1], Object.values(aAddsB));
var aMakesBEnumerable = {};
Object.defineProperty(aMakesBEnumerable, "a", {
get() {
Object.defineProperty(this, "b", { enumerable: true });
return 1;
},
enumerable: true
});
Object.defineProperty(aMakesBEnumerable, "b", {
value: 2, configurable:true, enumerable: false });
assertEquals([1, 2], Object.values(aMakesBEnumerable));
}
TestMutateDuringEnumeration();
(function TestElementKinds() {
var O1 = { name: "1" }, O2 = { name: "2" }, O3 = { name: "3" };
var PI = 3.141592653589793;
var E = 2.718281828459045;
function fastSloppyArguments(a, b, c) {
delete arguments[0];
arguments[0] = a;
return arguments;
}
function slowSloppyArguments(a, b, c) {
delete arguments[0];
arguments[0] = a;
Object.defineProperties(arguments, {
0: {
enumerable: true,
value: a
},
9999: {
enumerable: false,
value: "Y"
}
});
arguments[10000] = "X";
return arguments;
}
var element_kinds = {
PACKED_SMI_ELEMENTS: [ [1, 2, 3], [1, 2, 3] ],
HOLEY_SMI_ELEMENTS: [ [, , 3], [ 3 ] ],
PACKED_ELEMENTS: [ [O1, O2, O3], [O1, O2, O3] ],
HOLEY_ELEMENTS: [ [, , O3], [O3] ],
PACKED_DOUBLE_ELEMENTS: [ [E, NaN, PI], [E, NaN, PI] ],
HOLEY_DOUBLE_ELEMENTS: [ [, , NaN], [NaN] ],
DICTIONARY_ELEMENTS: [ Object.defineProperties({ 10000: "world" }, {
100: { enumerable: true, value: "hello" },
99: { enumerable: false, value: "nope" }
}), [ "hello", "world" ] ],
FAST_SLOPPY_ARGUMENTS_ELEMENTS: [
fastSloppyArguments("a", "b", "c"), ["a", "b", "c"] ],
SLOW_SLOPPY_ARGUMENTS_ELEMENTS: [
slowSloppyArguments("a", "b", "c"), [ "a", "b", "c", "X"]],
FAST_STRING_WRAPPER_ELEMENTS: [ new String("str"), ["s", "t", "r"] ],
SLOW_STRING_WRAPPER_ELEMENTS: [
Object.defineProperties(new String("str"), {
10000: { enumerable: false, value: "X" },
9999: { enumerable: true, value: "Y" }
}), ["s", "t", "r", "Y"] ],
};
for (let [kind, [object, expected]] of Object.entries(element_kinds)) {
let result1 = Object.values(object);
assertEquals(expected, result1, `fast Object.values() with ${kind}`);
let proxy = new Proxy(object, {});
let result2 = Object.values(proxy);
assertEquals(result1, result2, `slow Object.values() with ${kind}`);
}
})();

View File

@ -0,0 +1,5 @@
// 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.
assertDoesNotThrow("try { } catch (e) { var e; for (var e of []) {} }")

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,140 @@
// 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: --harmony-weak-refs
(function TestConstructFinalizationGroup() {
let fg = new FinalizationGroup(() => {});
assertEquals(fg.toString(), "[object FinalizationGroup]");
assertNotSame(fg.__proto__, Object.prototype);
assertSame(fg.__proto__.__proto__, Object.prototype);
})();
(function TestFinalizationGroupConstructorCallAsFunction() {
let caught = false;
let message = "";
try {
let f = FinalizationGroup(() => {});
} catch (e) {
message = e.message;
caught = true;
} finally {
assertTrue(caught);
assertEquals(message, "Constructor FinalizationGroup requires 'new'");
}
})();
(function TestConstructFinalizationGroupCleanupNotCallable() {
let message = "FinalizationGroup: cleanup must be callable";
assertThrows(() => { let fg = new FinalizationGroup(); }, TypeError, message);
assertThrows(() => { let fg = new FinalizationGroup(1); }, TypeError, message);
assertThrows(() => { let fg = new FinalizationGroup(null); }, TypeError, message);
})();
(function TestConstructFinalizationGroupWithCallableProxyAsCleanup() {
let handler = {};
let obj = () => {};
let proxy = new Proxy(obj, handler);
let fg = new FinalizationGroup(proxy);
})();
(function TestConstructFinalizationGroupWithNonCallableProxyAsCleanup() {
let message = "FinalizationGroup: cleanup must be callable";
let handler = {};
let obj = {};
let proxy = new Proxy(obj, handler);
assertThrows(() => { let fg = new FinalizationGroup(proxy); }, TypeError, message);
})();
(function TestRegisterWithNonObjectTarget() {
let fg = new FinalizationGroup(() => {});
let message = "FinalizationGroup.prototype.register: target must be an object";
assertThrows(() => fg.register(1, "holdings"), TypeError, message);
assertThrows(() => fg.register(false, "holdings"), TypeError, message);
assertThrows(() => fg.register("foo", "holdings"), TypeError, message);
assertThrows(() => fg.register(Symbol(), "holdings"), TypeError, message);
assertThrows(() => fg.register(null, "holdings"), TypeError, message);
assertThrows(() => fg.register(undefined, "holdings"), TypeError, message);
})();
(function TestRegisterWithProxy() {
let handler = {};
let obj = {};
let proxy = new Proxy(obj, handler);
let fg = new FinalizationGroup(() => {});
fg.register(proxy);
})();
(function TestRegisterTargetAndHoldingsSameValue() {
let fg = new FinalizationGroup(() => {});
let obj = {a: 1};
// SameValue(target, holdings) not ok
assertThrows(() => fg.register(obj, obj), TypeError,
"FinalizationGroup.prototype.register: target and holdings must not be same");
let holdings = {a: 1};
fg.register(obj, holdings);
})();
(function TestRegisterWithoutFinalizationGroup() {
assertThrows(() => FinalizationGroup.prototype.register.call({}, {}, "holdings"), TypeError);
// Does not throw:
let fg = new FinalizationGroup(() => {});
FinalizationGroup.prototype.register.call(fg, {}, "holdings");
})();
(function TestUnregisterWithNonExistentKey() {
let fg = new FinalizationGroup(() => {});
fg.unregister({"k": "whatever"});
})();
(function TestWeakRefConstructor() {
let wr = new WeakRef({});
assertEquals(wr.toString(), "[object WeakRef]");
assertNotSame(wr.__proto__, Object.prototype);
let deref_desc = Object.getOwnPropertyDescriptor(wr.__proto__, "deref");
assertEquals(true, deref_desc.configurable);
assertEquals(false, deref_desc.enumerable);
assertEquals("function", typeof deref_desc.value);
})();
(function TestWeakRefConstructorWithNonObject() {
let message = "WeakRef: target must be an object";
assertThrows(() => new WeakRef(), TypeError, message);
assertThrows(() => new WeakRef(1), TypeError, message);
assertThrows(() => new WeakRef(false), TypeError, message);
assertThrows(() => new WeakRef("foo"), TypeError, message);
assertThrows(() => new WeakRef(Symbol()), TypeError, message);
assertThrows(() => new WeakRef(null), TypeError, message);
assertThrows(() => new WeakRef(undefined), TypeError, message);
})();
(function TestWeakRefConstructorCallAsFunction() {
let caught = false;
let message = "";
try {
let f = WeakRef({});
} catch (e) {
message = e.message;
caught = true;
} finally {
assertTrue(caught);
assertEquals(message, "Constructor WeakRef requires 'new'");
}
})();
(function TestWeakRefWithProxy() {
let handler = {};
let obj = {};
let proxy = new Proxy(obj, handler);
let wr = new WeakRef(proxy);
})();
(function TestCleanupSomeWithoutFinalizationGroup() {
assertThrows(() => FinalizationGroup.prototype.cleanupSome.call({}), TypeError);
// Does not throw:
let fg = new FinalizationGroup(() => {});
let rv = FinalizationGroup.prototype.cleanupSome.call(fg);
assertEquals(undefined, rv);
})();

View File

@ -7,48 +7,47 @@
let cleanup_call_count = 0;
let cleanup = function(iter) {
if (cleanup_call_count == 0) {
// First call: iterate 2 of the 3 cells
let cells = [];
for (wc of iter) {
cells.push(wc);
// Don't iterate the rest of the cells
if (cells.length == 2) {
// First call: iterate 2 of the 3 holdings
let holdings_list = [];
for (holdings of iter) {
holdings_list.push(holdings);
// Don't iterate the rest of the holdings
if (holdings_list.length == 2) {
break;
}
}
assertEquals(cells.length, 2);
assertTrue(cells[0].holdings < 3);
assertTrue(cells[1].holdings < 3);
assertEquals(holdings_list.length, 2);
assertTrue(holdings_list[0] < 3);
assertTrue(holdings_list[1] < 3);
// Update call count only after the asserts; this ensures that the test
// fails even if the exceptions inside the cleanup function are swallowed.
cleanup_call_count++;
} else {
// Second call: iterate one leftover cell and one new cell.
// Second call: iterate one leftover holdings and one holdings.
assertEquals(1, cleanup_call_count);
let cells = [];
for (wc of iter) {
cells.push(wc);
let holdings_list = [];
for (holdings of iter) {
holdings_list.push(holdings);
}
assertEquals(cells.length, 2);
assertTrue((cells[0].holdings < 3 && cells[1].holdings == 100) ||
(cells[1].holdings < 3 && cells[0].holdings == 100));
assertEquals(holdings_list.length, 2);
assertTrue((holdings_list[0] < 3 && holdings_list[1] == 100) ||
(holdings_list[1] < 3 && holdings_list[0] == 100));
// Update call count only after the asserts; this ensures that the test
// fails even if the exceptions inside the cleanup function are swallowed.
cleanup_call_count++;
}
}
let wf = new WeakFactory(cleanup);
// Create 3 objects and WeakCells pointing to them. The objects need to be
// inside a closure so that we can reliably kill them!
let weak_cells = [];
let fg = new FinalizationGroup(cleanup);
// Create 3 objects and register them in the FinalizationGroup. The objects need
// to be inside a closure so that we can reliably kill them!
(function() {
let objects = [];
for (let i = 0; i < 3; ++i) {
objects[i] = {a: i};
weak_cells[i] = wf.makeCell(objects[i], i);
fg.register(objects[i], i);
}
gc();
@ -58,14 +57,14 @@ let weak_cells = [];
objects = [];
})();
// This GC will discover dirty WeakCells.
// This GC will reclaim the targets.
gc();
assertEquals(0, cleanup_call_count);
let timeout_func_1 = function() {
assertEquals(1, cleanup_call_count);
// Assert that the cleanup function won't be called unless new WeakCells appear.
// Assert that the cleanup function won't be called unless new targets appear.
setTimeout(timeout_func_2, 0);
}
@ -74,9 +73,9 @@ setTimeout(timeout_func_1, 0);
let timeout_func_2 = function() {
assertEquals(1, cleanup_call_count);
// Create a new WeakCells to be cleaned up.
// Create a new object and register it.
let obj = {};
let wc = wf.makeCell(obj, 100);
let wc = fg.register(obj, 100);
obj = null;
gc();

View File

@ -0,0 +1,34 @@
// 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: --harmony-weak-refs --expose-gc --noincremental-marking
let r = Realm.create();
let cleanup = Realm.eval(r, "var stored_global; function cleanup() { stored_global = globalThis; } cleanup");
let realm_global_this = Realm.eval(r, "globalThis");
let fg = new FinalizationGroup(cleanup);
// Create an object and a register it in the FinalizationGroup. The object needs
// to be inside a closure so that we can reliably kill them!
let weak_cell;
(function() {
let object = {};
fg.register(object, {});
// object goes out of scope.
})();
gc();
// Assert that the cleanup function was called in its Realm.
let timeout_func = function() {
let stored_global = Realm.eval(r, "stored_global;");
assertNotEquals(stored_global, globalThis);
assertEquals(stored_global, realm_global_this);
}
setTimeout(timeout_func, 0);

View File

@ -0,0 +1,56 @@
// 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: --harmony-weak-refs --expose-gc --noincremental-marking
// This test asserts that the cleanup function call, scheduled by GC, is a
// microtask and not a normal task.
// Inside a microtask, cause GC (which should schedule the cleanup as
// microtask). lso schedule another microtask. Assert that the cleanup
// function ran before the other microtask.
function scheduleMicrotask(func) {
Promise.resolve().then(func);
}
let log = [];
let cleanup = (iter) => {
log.push("cleanup");
for (holdings of iter) { }
}
let fg = new FinalizationGroup(cleanup);
let o = null;
(function() {
// Use a closure here to avoid other references to o which might keep it alive
// (e.g., stack frames pointing to it).
o = {};
fg.register(o, {});
})();
let microtask_after_cleanup = () => {
log.push("microtask_after_cleanup");
}
let first_microtask = function() {
log.push("first_microtask");
// This schedules the cleanup function as microtask.
o = null;
gc();
// Schedule a microtask which should run after the cleanup microtask.
scheduleMicrotask(microtask_after_cleanup);
}
scheduleMicrotask(first_microtask);
setTimeout(() => {
// Assert that the functions got called in the right order.
let wanted_log = ["first_microtask", "cleanup", "microtask_after_cleanup"];
assertEquals(wanted_log, log);
}, 0);

View File

@ -0,0 +1,34 @@
// 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: --harmony-weak-refs --expose-gc --noincremental-marking
let r = Realm.create();
let cleanup = Realm.eval(r, "var stored_global; let cleanup = new Proxy(function() { stored_global = globalThis;}, {}); cleanup");
let realm_global_this = Realm.eval(r, "globalThis");
let fg = new FinalizationGroup(cleanup);
// Create an object and register it in the FinalizationGroup. The object needs
// to be inside a closure so that we can reliably kill them!
let weak_cell;
(function() {
let object = {};
fg.register(object, "holdings");
// object goes out of scope.
})();
gc();
// Assert that the cleanup function was called in its Realm.
let timeout_func = function() {
let stored_global = Realm.eval(r, "stored_global;");
assertNotEquals(stored_global, globalThis);
assertEquals(stored_global, realm_global_this);
}
setTimeout(timeout_func, 0);

View File

@ -5,31 +5,31 @@
// Flags: --harmony-weak-refs --expose-gc --noincremental-marking
let cleanup_count = 0;
let cleanup_cells = [];
let cleanup_holdings = [];
let cleanup = function(iter) {
for (wc of iter) {
cleanup_cells.push(wc);
for (holdings of iter) {
cleanup_holdings.push(holdings);
}
++cleanup_count;
}
let wf = new WeakFactory(cleanup);
let weak_cell;
let fg = new FinalizationGroup(cleanup);
let key = {"k": "this is the key"};
(function() {
let o = {};
weak_cell = wf.makeCell(o);
weak_cell = fg.register(o, "holdings", key);
// cleanupSome won't do anything since there are no dirty WeakCells.
wf.cleanupSome();
// cleanupSome won't do anything since there are no reclaimed targets.
fg.cleanupSome();
assertEquals(0, cleanup_count);
})();
// GC will detect the WeakCell as dirty.
gc();
// Clear the WeakCell just before we would've called cleanupSome.
weak_cell.clear();
// Unregister the tracked object just before calling cleanupSome.
fg.unregister(key);
wf.cleanupSome();
fg.cleanupSome();
assertEquals(0, cleanup_count);

View File

@ -5,29 +5,28 @@
// Flags: --harmony-weak-refs --expose-gc --noincremental-marking
let cleanup_count = 0;
let cleanup_cells = [];
let cleanup_holdings = [];
let cleanup = function(iter) {
for (wc of iter) {
cleanup_cells.push(wc);
for (holdings of iter) {
cleanup_holdings.push(holdings);
}
++cleanup_count;
}
let wf = new WeakFactory(cleanup);
let weak_cell;
let fg = new FinalizationGroup(cleanup);
(function() {
let o = {};
weak_cell = wf.makeCell(o);
fg.register(o, "holdings");
// cleanupSome won't do anything since there are no dirty WeakCells.
wf.cleanupSome();
// cleanupSome won't do anything since there are no reclaimed targets.
fg.cleanupSome();
assertEquals(0, cleanup_count);
})();
// GC will detect the WeakCell as dirty.
// GC will detect o as dead.
gc();
wf.cleanupSome();
fg.cleanupSome();
assertEquals(1, cleanup_count);
assertEquals(1, cleanup_cells.length);
assertEquals(weak_cell, cleanup_cells[0]);
assertEquals(1, cleanup_holdings.length);
assertEquals("holdings", cleanup_holdings[0]);

View File

@ -7,18 +7,19 @@
let cleanup_called = false;
let cleanup = function(iter) {
assertFalse(cleanup_called);
let cells = [];
for (wc of iter) {
cells.push(wc);
let holdings_list = [];
for (holdings of iter) {
holdings_list.push(holdings);
}
assertEquals(cells.length, 1);
assertEquals(cells[0].holdings, "this is my cell");
assertEquals(holdings_list.length, 1);
assertEquals(holdings_list[0].a, "this is the holdings object");
cleanup_called = true;
}
let wf = new WeakFactory(cleanup);
let fg = new FinalizationGroup(cleanup);
let o1 = {};
let wc1 = wf.makeCell(o1, "this is my cell");
let holdings = {'a': 'this is the holdings object'};
fg.register(o1, holdings);
gc();
assertFalse(cleanup_called);
@ -26,9 +27,9 @@ assertFalse(cleanup_called);
// Drop the last references to o1.
o1 = null;
// Drop the last reference to the WeakCell. The WeakFactory keeps it alive, so
// the cleanup function will be called as normal.
wc1 = null;
// Drop the last reference to the holdings. The FinalizationGroup keeps it
// alive, so the cleanup function will be called as normal.
holdings = null;
gc();
assertFalse(cleanup_called);

View File

@ -7,27 +7,26 @@
let cleanup_called = false;
let cleanup = function(iter) {
assertFalse(cleanup_called);
let cells = [];
for (wc of iter) {
cells.push(wc);
let holdings_list = [];
for (holdings of iter) {
holdings_list.push(holdings);
}
assertEquals(1, cells.length);
assertEquals(weak_cell, cells[0]);
assertEquals(1, holdings_list.length);
assertEquals("holdings", holdings_list[0]);
cleanup_called = true;
}
let wf = new WeakFactory(cleanup);
let fg = new FinalizationGroup(cleanup);
let weak_ref;
let weak_cell;
(function() {
let o = {};
weak_ref = new WeakRef(o);
weak_cell = wf.makeCell(o);
fg.register(o, "holdings");
})();
// Since the WeakRef was created during this turn, it is not cleared by GC. The
// WeakCell is not cleared either, since the WeakRef keeps the target object
// alive.
// pointer inside the FinalizationGroup is not cleared either, since the WeakRef
// keeps the target object alive.
gc();
(function() {
assertNotEquals(undefined, weak_ref.deref());

View File

@ -6,66 +6,66 @@
// Flags: --no-stress-flush-bytecode
let cleanup0_call_count = 0;
let cleanup0_weak_cell_count = 0;
let cleanup0_holdings_count = 0;
let cleanup1_call_count = 0;
let cleanup1_weak_cell_count = 0;
let cleanup1_holdings_count = 0;
let cleanup0 = function(iter) {
for (wc of iter) {
++cleanup0_weak_cell_count;
for (holdings of iter) {
++cleanup0_holdings_count;
}
++cleanup0_call_count;
}
let cleanup1 = function(iter) {
for (wc of iter) {
++cleanup1_weak_cell_count;
for (holdings of iter) {
++cleanup1_holdings_count;
}
++cleanup1_call_count;
}
let wf0 = new WeakFactory(cleanup0);
let wf1 = new WeakFactory(cleanup1);
let fg0 = new FinalizationGroup(cleanup0);
let fg1 = new FinalizationGroup(cleanup1);
// Create 1 WeakCell for each WeakFactory and kill the objects they point to.
// Register 1 weak reference for each FinalizationGroup and kill the objects they point to.
(function() {
// The objects need to be inside a closure so that we can reliably kill them.
let objects = [];
objects[0] = {};
objects[1] = {};
wf0.makeCell(objects[0]);
wf1.makeCell(objects[1]);
fg0.register(objects[0], "holdings0-0");
fg1.register(objects[1], "holdings1-0");
// Drop the references to the objects.
objects = [];
// Will schedule both wf0 and wf1 for cleanup.
// Will schedule both fg0 and fg1 for cleanup.
gc();
})();
// Before the cleanup task has a chance to run, do the same thing again, so both
// factories are (again) scheduled for cleanup. This has to be a IIFE function
// FinalizationGroups are (again) scheduled for cleanup. This has to be a IIFE function
// (so that we can reliably kill the objects) so we cannot use the same function
// as before.
(function() {
let objects = [];
objects[0] = {};
objects[1] = {};
wf0.makeCell(objects[0]);
wf1.makeCell(objects[1]);
fg0.register(objects[0], "holdings0-1");
fg1.register(objects[1], "holdings1-1");
objects = [];
gc();
})();
let timeout_func = function() {
assertEquals(1, cleanup0_call_count);
assertEquals(2, cleanup0_weak_cell_count);
assertEquals(2, cleanup0_holdings_count);
assertEquals(1, cleanup1_call_count);
assertEquals(2, cleanup1_weak_cell_count);
assertEquals(2, cleanup1_holdings_count);
}
// Give the cleanup task a chance to run. All WeakCells to cleanup will be
// available during the same invocation of the cleanup function.
// Give the cleanup task a chance to run. All holdings will be iterated during
// the same invocation of the cleanup function.
setTimeout(timeout_func, 0);

View File

@ -7,29 +7,25 @@
let cleanup_called = false;
let cleanup = function(iter) {
assertFalse(cleanup_called);
let cells = [];
for (wc of iter) {
cells.push(wc);
let holdings_list = [];
for (holdings of iter) {
holdings_list.push(holdings);
}
assertEquals(cells.length, 2);
if (cells[0] == wc1) {
assertEquals(cells[0].holdings, 1);
assertEquals(cells[1], wc2);
assertEquals(cells[1].holdings, 2);
assertEquals(holdings_list.length, 2);
if (holdings_list[0] == 1) {
assertEquals(holdings_list[1], 2);
} else {
assertEquals(cells[0], wc2);
assertEquals(cells[0].holdings, 2);
assertEquals(cells[1], wc1);
assertEquals(cells[1].holdings, 1);
assertEquals(holdings_list[0], 2);
assertEquals(holdings_list[1], 1);
}
cleanup_called = true;
}
let wf = new WeakFactory(cleanup);
let fg = new FinalizationGroup(cleanup);
let o1 = {};
let o2 = {};
let wc1 = wf.makeCell(o1, 1);
let wc2 = wf.makeCell(o2, 2);
fg.register(o1, 1);
fg.register(o2, 2);
gc();
assertFalse(cleanup_called);
@ -37,8 +33,8 @@ assertFalse(cleanup_called);
// Drop the last references to o1 and o2.
o1 = null;
o2 = null;
// GC will clear the WeakCells; the cleanup function will be called the next time
// we enter the event loop.
// GC will reclaim the target objects; the cleanup function will be called the
// next time we enter the event loop.
gc();
assertFalse(cleanup_called);

View File

@ -5,28 +5,26 @@
// Flags: --harmony-weak-refs --expose-gc --noincremental-marking
let cleanup_call_count = 0;
let cleanup_weak_cell_count = 0;
let cleanup_holdings_count = 0;
let cleanup = function(iter) {
for (wc of iter) {
++cleanup_weak_cell_count;
for (holdings of iter) {
++cleanup_holdings_count;
}
++cleanup_call_count;
}
let wf1 = new WeakFactory(cleanup);
let wf2 = new WeakFactory(cleanup);
let fg1 = new FinalizationGroup(cleanup);
let fg2 = new FinalizationGroup(cleanup);
// Create two objects and WeakCells pointing to them. The objects need to be inside
// a closure so that we can reliably kill them!
let weak_cell1;
let weak_cell2;
// Create two objects and register them in FinalizationGroups. The objects need
// to be inside a closure so that we can reliably kill them!
(function() {
let object1 = {};
weak_cell1 = wf1.makeCell(object1);
fg1.register(object1, "holdings1");
let object2 = {};
weak_cell2 = wf2.makeCell(object2);
fg2.register(object2, "holdings2");
// object1 and object2 go out of scope.
})();
@ -35,10 +33,10 @@ let weak_cell2;
gc();
assertEquals(0, cleanup_call_count);
// Assert that the cleanup function was called and iterated the WeakCells.
// Assert that the cleanup function was called and iterated the holdings.
let timeout_func = function() {
assertEquals(2, cleanup_call_count);
assertEquals(2, cleanup_weak_cell_count);
assertEquals(2, cleanup_holdings_count);
}
setTimeout(timeout_func, 0);

View File

@ -0,0 +1,39 @@
// Copyright 2019 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Flags: --harmony-weak-refs --expose-gc --noincremental-marking
let cleanup_call_count = 0;
let cleanup_holdings_count = 0;
let cleanup = function(iter) {
for (holdings of iter) {
assertEquals(holdings, undefined);
++cleanup_holdings_count;
}
++cleanup_call_count;
}
let fg = new FinalizationGroup(cleanup);
// Create an object and register it in the FinalizationGroup. The object needs to be inside
// a closure so that we can reliably kill them!
(function() {
let object = {};
fg.register(object);
// object goes out of scope.
})();
// This GC will reclaim the target object and schedule cleanup.
gc();
assertEquals(0, cleanup_call_count);
// Assert that the cleanup function was called and iterated the holdings.
let timeout_func = function() {
assertEquals(1, cleanup_call_count);
assertEquals(1, cleanup_holdings_count);
}
setTimeout(timeout_func, 0);

View File

@ -5,42 +5,42 @@
// Flags: --harmony-weak-refs --expose-gc --noincremental-marking
let cleanup_call_count = 0;
let cleanup_weak_cell_count = 0;
let cleanup_holdings_count = 0;
let cleanup = function(iter) {
for (wc of iter) {
assertSame(wc, weak_cell);
++cleanup_weak_cell_count;
for (holdings of iter) {
assertEquals("holdings", holdings);
++cleanup_holdings_count;
}
++cleanup_call_count;
}
let wf = new WeakFactory(cleanup);
// Create an object and a WeakCell pointing to it. The object needs to be inside
// a closure so that we can reliably kill them!
let weak_cell;
let fg = new FinalizationGroup(cleanup);
let key = {"k": "this is the key"};
// Create an object and register it in the FinalizationGroup. The object needs
// to be inside a closure so that we can reliably kill them!
(function() {
let object = {};
weak_cell = wf.makeCell(object);
fg.register(object, "holdings", key);
// object goes out of scope.
})();
// This GC will discover dirty WeakCells and schedule cleanup.
// This GC will reclaim the target object and schedule cleanup.
gc();
assertEquals(0, cleanup_call_count);
// Assert that the cleanup function was called and iterated the WeakCell.
// Assert that the cleanup function was called and iterated the holdings.
let timeout_func = function() {
assertEquals(1, cleanup_call_count);
assertEquals(1, cleanup_weak_cell_count);
assertEquals(1, cleanup_holdings_count);
// Clear an already iterated over WeakCell.
weak_cell.clear();
// Unregister an already iterated over weak reference.
fg.unregister(key);
// Assert that it didn't do anything.
setTimeout(() => { assertEquals(1, cleanup_call_count); }, 0);
setTimeout(() => { assertEquals(1, cleanup_weak_cell_count); }, 0);
setTimeout(() => { assertEquals(1, cleanup_holdings_count); }, 0);
}
setTimeout(timeout_func, 0);

View File

@ -9,30 +9,27 @@ let cleanup = function(iter) {
++cleanup_call_count;
}
let wf = new WeakFactory(cleanup);
// Create an object and a WeakCell pointing to it. The object needs to be inside
// a closure so that we can reliably kill them!
let weak_cell;
let fg = new FinalizationGroup(cleanup);
let key = {"k": "this is the key"};
// Create an object and register it in the FinalizationGroup. The object needs
// to be inside a closure so that we can reliably kill them!
(function() {
let object = {};
weak_cell = wf.makeCell(object, "my holdings");
fg.register(object, "my holdings", key);
// Clear the WeakCell before the GC has a chance to discover it.
let return_value = weak_cell.clear();
let return_value = fg.unregister(key);
assertEquals(undefined, return_value);
// Assert holdings got cleared too.
assertEquals(undefined, weak_cell.holdings);
// object goes out of scope.
})();
// This GC will discover dirty WeakCells.
// This GC will reclaim the target object.
gc();
assertEquals(0, cleanup_call_count);
// Assert that the cleanup function won't be called, since the WeakCell was cleared.
// Assert that the cleanup function won't be called, since we called unregister.
let timeout_func = function() {
assertEquals(0, cleanup_call_count);
}

View File

@ -0,0 +1,40 @@
// 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: --harmony-weak-refs --expose-gc --noincremental-marking
let cleanup_call_count = 0;
let cleanup = function(iter) {
++cleanup_call_count;
}
let fg = new FinalizationGroup(cleanup);
let key = {"k": "this is the key"};
// Create an object and register it in the FinalizationGroup. The object needs
// to be inside a closure so that we can reliably kill them!
(function() {
let object = {};
fg.register(object, "holdings", key);
// Unregister before the GC has a chance to discover the object.
fg.unregister(key);
// Call unregister again (just to assert we handle this gracefully).
fg.unregister(key);
// object goes out of scope.
})();
// This GC will reclaim the target object.
gc();
assertEquals(0, cleanup_call_count);
// Assert that the cleanup function won't be called, since the weak reference
// was unregistered.
let timeout_func = function() {
assertEquals(0, cleanup_call_count);
}
setTimeout(timeout_func, 0);

View File

@ -5,37 +5,37 @@
// Flags: --harmony-weak-refs --expose-gc --noincremental-marking
let cleanup_call_count = 0;
let cleanup_weak_cell_count = 0;
let cleanup_holdings_count = 0;
let cleanup = function(iter) {
// Clear the WeakCell before we've iterated through it.
weak_cell.clear();
// Unregister before we've iterated through the holdings.
fg.unregister(key);
for (wc of iter) {
++cleanup_weak_cell_count;
++cleanup_holdings_count;
}
++cleanup_call_count;
}
let wf = new WeakFactory(cleanup);
// Create an object and a WeakCell pointing to it. The object needs to be inside
// a closure so that we can reliably kill them!
let weak_cell;
let fg = new FinalizationGroup(cleanup);
let key = {"k": "the key"};
// Create an object and register it in the FinalizationGroup. The object needs
// to be inside a closure so that we can reliably kill them!
(function() {
let object = {};
weak_cell = wf.makeCell(object);
fg.register(object, "holdings", key);
// object goes out of scope.
})();
// This GC will discover dirty WeakCells and schedule cleanup.
// This GC will discover unretained targets and schedule cleanup.
gc();
assertEquals(0, cleanup_call_count);
// Assert that the cleanup function was called, but didn't iterate any weak cells.
// Assert that the cleanup function was called, but didn't iterate any holdings.
let timeout_func = function() {
assertEquals(1, cleanup_call_count);
assertEquals(0, cleanup_weak_cell_count);
assertEquals(0, cleanup_holdings_count);
}
setTimeout(timeout_func, 0);

View File

@ -5,24 +5,24 @@
// Flags: --harmony-weak-refs --expose-gc --noincremental-marking
let cleanup_call_count = 0;
let cleanup_weak_cell_count = 0;
let cleanup_holdings_count = 0;
let cleanup = function(iter) {
for (wc of iter) {
assertSame(wc, weak_cell);
wc.clear();
++cleanup_weak_cell_count;
for (holdings of iter) {
assertEquals(holdings, "holdings");
fg.unregister(key);
++cleanup_holdings_count;
}
++cleanup_call_count;
}
let wf = new WeakFactory(cleanup);
// Create an object and a WeakCell pointing to it. The object needs to be inside
let fg = new FinalizationGroup(cleanup);
// Create an object and register it in the FinalizationGroup. The object needs to be inside
// a closure so that we can reliably kill them!
let weak_cell;
let key = {"k": "this is the key"};
(function() {
let object = {};
weak_cell = wf.makeCell(object);
fg.register(object, "holdings", key);
// object goes out of scope.
})();
@ -34,7 +34,7 @@ assertEquals(0, cleanup_call_count);
// Assert that the cleanup function was called and iterated the WeakCell.
let timeout_func = function() {
assertEquals(1, cleanup_call_count);
assertEquals(1, cleanup_weak_cell_count);
assertEquals(1, cleanup_holdings_count);
}
setTimeout(timeout_func, 0);

View File

@ -5,37 +5,38 @@
// Flags: --harmony-weak-refs --expose-gc --noincremental-marking
let cleanup_call_count = 0;
let cleanup_weak_cell_count = 0;
let cleanup_holdings_count = 0;
let cleanup = function(iter) {
for (wc of iter) {
assertSame(wc, weak_cell);
++cleanup_weak_cell_count;
for (holdings of iter) {
assertEquals(holdings, "holdings");
++cleanup_holdings_count;
}
// Clear an already iterated over WeakCell.
weak_cell.clear();
// Unregister an already iterated over weak reference.
fg.unregister(key);
++cleanup_call_count;
}
let wf = new WeakFactory(cleanup);
// Create an object and a WeakCell pointing to it. The object needs to be inside
let fg = new FinalizationGroup(cleanup);
let key = {"k": "this is the key"};
// Create an object and register it in the FinalizationGroup. The object needs to be inside
// a closure so that we can reliably kill them!
let weak_cell;
(function() {
let object = {};
weak_cell = wf.makeCell(object);
fg.register(object, "holdings", key);
// object goes out of scope.
})();
// This GC will discover dirty WeakCells and schedule cleanup.
// This GC will reclaim the target object and schedule cleanup.
gc();
assertEquals(0, cleanup_call_count);
// Assert that the cleanup function was called and iterated the WeakCell.
// Assert that the cleanup function was called and iterated the holdings.
let timeout_func = function() {
assertEquals(1, cleanup_call_count);
assertEquals(1, cleanup_weak_cell_count);
assertEquals(1, cleanup_holdings_count);
}
setTimeout(timeout_func, 0);

View File

@ -0,0 +1,48 @@
// 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: --harmony-weak-refs --expose-gc --noincremental-marking
let cleanup_call_count = 0;
let cleanup_holdings_count = 0;
let cleanup = function(iter) {
for (holdings of iter) {
// See which target we're iterating over and unregister the other one.
if (holdings == 1) {
fg.unregister(key2);
} else {
assertSame(holdings, 2);
fg.unregister(key1);
}
++cleanup_holdings_count;
}
++cleanup_call_count;
}
let fg = new FinalizationGroup(cleanup);
let key1 = {"k": "first key"};
let key2 = {"k": "second key"};
// Create two objects and register them in the FinalizationGroup. The objects
// need to be inside a closure so that we can reliably kill them!
(function() {
let object1 = {};
fg.register(object1, 1, key1);
let object2 = {};
fg.register(object2, 2, key2);
// object1 and object2 go out of scope.
})();
// This GC will reclaim target objects and schedule cleanup.
gc();
assertEquals(0, cleanup_call_count);
// Assert that the cleanup function was called and iterated one holdings (but not the other one).
let timeout_func = function() {
assertEquals(1, cleanup_call_count);
assertEquals(1, cleanup_holdings_count);
}
setTimeout(timeout_func, 0);

View File

@ -0,0 +1,50 @@
// Copyright 2019 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Flags: --harmony-weak-refs --expose-gc --noincremental-marking
let cleanup_call_count = 0;
let cleanup_holdings_count = 0;
let cleanup = function(iter) {
for (holdings of iter) {
assertEquals("holdings2", holdings);
++cleanup_holdings_count;
}
++cleanup_call_count;
}
let fg = new FinalizationGroup(cleanup);
let key1 = {"k": "key1"};
let key2 = {"k": "key2"};
// Create three objects and register them in the FinalizationGroup. The objects
// need to be inside a closure so that we can reliably kill them!
(function() {
let object1a = {};
fg.register(object1a, "holdings1a", key1);
let object1b = {};
fg.register(object1b, "holdings1b", key1);
let object2 = {};
fg.register(object2, "holdings2", key2);
// Unregister before the GC has a chance to discover the objects.
fg.unregister(key1);
// objects go out of scope.
})();
// This GC will reclaim the target objects.
gc();
assertEquals(0, cleanup_call_count);
// Assert that the cleanup function will be called only for the reference which
// was not unregistered.
let timeout_func = function() {
assertEquals(1, cleanup_call_count);
assertEquals(1, cleanup_holdings_count);
}
setTimeout(timeout_func, 0);

View File

@ -9,14 +9,14 @@ let cleanup = function(iter) {
++cleanup_call_count;
}
let wf = new WeakFactory(cleanup);
// Create an object and a WeakCell pointing to it. The object needs to be inside
let key = {"k": "this is my key"};
let fg = new FinalizationGroup(cleanup);
// Create an object and register it in the FinalizationGroup. The object needs to be inside
// a closure so that we can reliably kill them!
let weak_cell;
(function() {
let object = {};
weak_cell = wf.makeCell(object);
fg.register(object, {}, key);
// object goes out of scope.
})();
@ -25,10 +25,10 @@ let weak_cell;
gc();
assertEquals(0, cleanup_call_count);
// Clear the WeakCell before cleanup has ran.
weak_cell.clear();
// Unregister the object from the FinalizationGroup before cleanup has ran.
fg.unregister(key);
// Assert that the cleanup function won't be called, since the WeakCell was cleared.
// Assert that the cleanup function won't be called.
let timeout_func = function() {
assertEquals(0, cleanup_call_count);
}

View File

@ -0,0 +1,37 @@
// 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: --harmony-weak-refs --expose-gc --noincremental-marking
let cleanup_called = false;
let cleanup = function(iter) {
assertFalse(cleanup_called);
let result = iter.next();
assertEquals(result.value, holdings);
assertFalse(result.done);
result = iter.next();
assertTrue(result.done);
cleanup_called = true;
}
let fg = new FinalizationGroup(cleanup);
let o = {};
let holdings = {'h': 55};
fg.register(o, holdings);
gc();
assertFalse(cleanup_called);
// Drop the last reference to o.
o = null;
// GC will clear the WeakCell; the cleanup function will be called the next time
// we enter the event loop.
gc();
assertFalse(cleanup_called);
let timeout_func = function() {
assertTrue(cleanup_called);
}
setTimeout(timeout_func, 0);

View File

@ -0,0 +1,166 @@
// 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
(function SealAndReconfigure() {
function C() { this.x = 1; this.y = 1; Object.seal(this); }
let c1 = new C();
c1.x = 0.1;
let c2 = new C();
let c3 = new C();
let c4 = new C();
// The objects c2, c3 and c4 should follow the same transition
// path that we reconfigured c1 to.
assertTrue(%HaveSameMap(c1, c2));
assertTrue(%HaveSameMap(c1, c3));
assertTrue(%HaveSameMap(c1, c4));
c2.x = 0.1;
c3.x = 0.1;
c4.x = 0.1;
assertTrue(%HaveSameMap(c1, c2));
assertTrue(%HaveSameMap(c1, c3));
assertTrue(%HaveSameMap(c1, c4));
})();
(function SealAndReconfigureWithIC() {
function C() { this.x = 1; this.y = 1; Object.seal(this); }
let c1 = new C();
function g(o) {
o.x = 0.1;
}
g(c1);
let c2 = new C();
let c3 = new C();
let c4 = new C();
// The objects c2, c3 and c4 should follow the same transition
// path that we reconfigured c1 to.
assertTrue(%HaveSameMap(c1, c2));
assertTrue(%HaveSameMap(c1, c3));
assertTrue(%HaveSameMap(c1, c4));
g(c2);
g(c3);
g(c4);
assertTrue(%HaveSameMap(c1, c2));
assertTrue(%HaveSameMap(c1, c3));
assertTrue(%HaveSameMap(c1, c4));
})();
(function SealReconfigureAndMigrateWithIC() {
function C() { this.x = 1; this.y = 1; Object.seal(this); }
let c1 = new C();
let c2 = new C();
let c3 = new C();
let c4 = new C();
function g(o) {
o.x = 0.1;
}
g(c1);
// Now c2, c3 and c4 have deprecated maps.
assertFalse(%HaveSameMap(c1, c2));
assertFalse(%HaveSameMap(c1, c3));
assertFalse(%HaveSameMap(c1, c4));
g(c2);
g(c3);
g(c4);
assertTrue(%HaveSameMap(c1, c2));
assertTrue(%HaveSameMap(c1, c3));
assertTrue(%HaveSameMap(c1, c4));
})();
(function SealReconfigureAndMigrateWithOptCode() {
function C() { this.x = 1; this.y = 1; Object.seal(this); }
let c1 = new C();
let c2 = new C();
let c3 = new C();
let c4 = new C();
function g(o) {
o.x = 0.1;
}
g(c1);
g(c2);
g(c3);
%OptimizeFunctionOnNextCall(g);
g(c4);
assertTrue(%HaveSameMap(c1, c2));
assertTrue(%HaveSameMap(c1, c3));
assertTrue(%HaveSameMap(c1, c4));
})();
(function PreventExtensionsAndReconfigure() {
function C() { this.x = 1; this.y = 1; Object.preventExtensions(this); }
let c1 = new C();
function g(o) {
o.x = 0.1;
}
g(c1);
let c2 = new C();
let c3 = new C();
let c4 = new C();
c2.x = 0.1;
c3.x = 0.1;
c4.x = 0.1;
assertTrue(%HaveSameMap(c1, c2));
assertTrue(%HaveSameMap(c1, c3));
assertTrue(%HaveSameMap(c1, c4));
})();
(function PreventExtensionsSealAndReconfigure() {
function C() {
this.x = 1;
this.y = 1;
Object.preventExtensions(this);
Object.seal(this);
}
let c1 = new C();
function g(o) {
o.x = 0.1;
}
g(c1);
let c2 = new C();
let c3 = new C();
let c4 = new C();
c2.x = 0.1;
c3.x = 0.1;
c4.x = 0.1;
// Ideally, all the objects would have the same map, but at the moment
// we shortcut the unnecessary integrity level transitions.
assertTrue(%HaveSameMap(c2, c3));
assertTrue(%HaveSameMap(c2, c4));
})();

View File

@ -126,13 +126,6 @@ test(function() {
[].join(o);
}, "Cannot convert object to primitive value", TypeError);
// kCircularStructure
test(function() {
var o = {};
o.o = o;
JSON.stringify(o);
}, "Converting circular structure to JSON", TypeError);
// kConstructorNotFunction
test(function() {
Map();

View File

@ -213,7 +213,7 @@ var prettyPrinted;
// TODO(neis): Remove try-catch once BigInts are enabled by default.
try {
BigIntPrototypeValueOf = BigInt.prototype.valueOf;
} catch(e) {}
} catch (e) {}
function classOf(object) {
// Argument must not be null or undefined.
@ -480,14 +480,17 @@ var prettyPrinted;
}
};
function executeCode(code) {
if (typeof code === 'function') return code();
if (typeof code === 'string') return eval(code);
failWithMessage(
'Given code is neither function nor string, but ' + (typeof code) +
': <' + prettyPrinted(code) + '>');
}
assertThrows = function assertThrows(code, type_opt, cause_opt) {
try {
if (typeof code === 'function') {
code();
} else {
eval(code);
}
executeCode(code);
} catch (e) {
if (typeof type_opt === 'function') {
assertInstanceof(e, type_opt);
@ -508,11 +511,10 @@ var prettyPrinted;
failWithMessage("Did not throw exception");
};
assertThrowsEquals = function assertThrowsEquals(fun, val) {
try {
fun();
} catch(e) {
} catch (e) {
assertSame(val, e);
return;
}
@ -533,15 +535,11 @@ var prettyPrinted;
}
};
assertDoesNotThrow = function assertDoesNotThrow(code, name_opt) {
assertDoesNotThrow = function assertDoesNotThrow(code, name_opt) {
try {
if (typeof code === 'function') {
return code();
} else {
return eval(code);
}
executeCode(code);
} catch (e) {
if (e instanceof MjsUnitAssertionError) throw e;
failWithMessage("threw an exception: " + (e.message || e));
}
};
@ -584,13 +582,15 @@ var prettyPrinted;
}
assertPromiseResult = function(promise, success, fail) {
if (success !== undefined) assertEquals('function', typeof success);
if (fail !== undefined) assertEquals('function', typeof fail);
const stack = (new Error()).stack;
var test_promise = promise.then(
result => {
try {
if (--promiseTestCount == 0) testRunner.notifyDone();
if (success) success(result);
if (success !== undefined) success(result);
} catch (e) {
// Use setTimeout to throw the error again to get out of the promise
// chain.
@ -602,7 +602,7 @@ var prettyPrinted;
result => {
try {
if (--promiseTestCount == 0) testRunner.notifyDone();
if (!fail) throw result;
if (fail === undefined) throw result;
fail(result);
} catch (e) {
// Use setTimeout to throw the error again to get out of the promise
@ -667,7 +667,9 @@ var prettyPrinted;
// option is provided. Such tests must add --opt to flags comment.
assertFalse((opt_status & V8OptimizationStatus.kNeverOptimize) !== 0,
"test does not make sense with --no-opt");
assertTrue((opt_status & V8OptimizationStatus.kIsFunction) !== 0, name_opt);
assertTrue(
(opt_status & V8OptimizationStatus.kIsFunction) !== 0,
'should be a function: ' + name_opt);
if (skip_if_maybe_deopted &&
(opt_status & V8OptimizationStatus.kMaybeDeopted) !== 0) {
// When --deopt-every-n-times flag is specified it's no longer guaranteed
@ -675,7 +677,9 @@ var prettyPrinted;
// to stress test the deoptimizer.
return;
}
assertTrue((opt_status & V8OptimizationStatus.kOptimized) !== 0, name_opt);
assertTrue(
(opt_status & V8OptimizationStatus.kOptimized) !== 0,
'should be optimized: ' + name_opt);
}
isNeverOptimizeLiteMode = function isNeverOptimizeLiteMode() {
@ -772,7 +776,7 @@ var prettyPrinted;
return frame;
});
return "" + error.message + "\n" + ArrayPrototypeJoin.call(stack, "\n");
} catch(e) {};
} catch (e) {};
return error.stack;
}
})();

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,39 @@
// Copyright 2010 the V8 project authors. All rights reserved.
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following
// disclaimer in the documentation and/or other materials provided
// with the distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// This tests that a global key values are preserved when used in
// an expression which will bail out.
var m = Math;
var p = "floor";
function test() {
var bignumber = 31363200000;
assertEquals(m[p](Math.round(bignumber/864E5)/7)+1, 52);
}
test();

View File

@ -0,0 +1,19 @@
// 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: --allow-natives-syntax --enable-slow-asserts
var arr = [];
var str = new String('x');
function f(a,b) {
a[b] = 1;
}
f(arr, 0);
f(str, 0);
f(str, 0);
// This is just to trigger elements validation, object already broken.
%SetKeyedProperty(str, 1, 'y');

View File

@ -0,0 +1,37 @@
// Copyright 2014 the V8 project authors. All rights reserved.
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following
// disclaimer in the documentation and/or other materials provided
// with the distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// Flags: --max-old-space-size=1600
assertThrows((function() {
let str = "a".repeat(1e7);
let arr = new Array(2000);
for (let i = 0; i < 200; ++i) {
arr[i*10] = str;
}
let res = arr.join(':');
}), RangeError);

View File

@ -0,0 +1,75 @@
// 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.
load("test/mjsunit/wasm/wasm-module-builder.js");
(function() {
var builder = new WasmModuleBuilder();
builder.addMemory(32, 32, false);
builder.addFunction("test", kSig_i_iii)
.addBodyWithEnd([
// body:
kExprI64Const, 0xb4, 0x42,
kExprI64Const, 0x7a,
kExprI64Const, 0x42,
kExprI64Const, 0x7a,
kExprI64Ior,
kExprI64Ctz,
kExprI64Ctz,
kExprI64Shl,
kExprI64Mul,
kExprI64Const, 0x41,
kExprI64Ctz,
kExprI64Ctz,
kExprI64Shl,
kExprF32SConvertI64,
kExprI64Const, 0x42,
kExprI64Const, 0x02,
kExprI64Const, 0x7a,
kExprI64Mul,
kExprI64Const, 0x42,
kExprI64Ctz,
kExprI64Shl,
kExprI64Const, 0x7a,
kExprI64Ctz,
kExprI64Shl,
kExprI64Mul,
kExprI64Const, 0x41,
kExprI64Ctz,
kExprI64Ctz,
kExprI64Shl,
kExprF32SConvertI64,
kExprUnreachable,
kExprEnd, // @65
])
.exportFunc();
var module = new WebAssembly.Module(builder.toBuffer());
})();
(function() {
var builder = new WasmModuleBuilder();
builder.addMemory(16, 32, false);
builder.addFunction("test", kSig_i_iii)
.addBodyWithEnd([
// body:
kExprI64Const, 0x42,
kExprI64Const, 0x7a,
kExprI64Ctz,
kExprI64Mul,
kExprI64Ctz,
kExprI64Const, 0x41,
kExprI64Ctz,
kExprI64Ctz,
kExprI64Shl,
kExprI64Const, 0x41,
kExprI64Ctz,
kExprI64Ctz,
kExprI64Shl,
kExprF32SConvertI64,
kExprUnreachable,
kExprEnd, // @20
])
.exportFunc();
var module = new WebAssembly.Module(builder.toBuffer());
})();

View File

@ -0,0 +1,31 @@
// 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.
load("test/mjsunit/wasm/wasm-module-builder.js");
(function() {
var builder = new WasmModuleBuilder();
builder.addMemory(32, 32, false);
builder.addFunction("test", kSig_i_iii)
.addBodyWithEnd([
// body:
kExprI64Const, 0x42,
kExprI64Const, 0x7a,
kExprI64RemU,
kExprI64Const, 0x42,
kExprI64Const, 0x37,
kExprI64Mul,
kExprI64Const, 0x36,
kExprI64Mul,
kExprI64Const, 0x42,
kExprI64Ctz,
kExprI64Ctz,
kExprI64Shl,
kExprF32SConvertI64,
kExprUnreachable,
kExprEnd, // @21
])
.exportFunc();
var module = new WebAssembly.Module(builder.toBuffer());
})();

View File

@ -0,0 +1,21 @@
// 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.
// ensure `delete this` throws before `super` is called.
assertThrows(()=>{
new class extends Object {
constructor() {
delete this;
super();
}
}
}, ReferenceError);
// ensure `delete this` doesn't throw after `super` is called.
new class extends Object {
constructor() {
super();
delete this;
}
}

View File

@ -0,0 +1,74 @@
// Copyright 2009 the V8 project authors. All rights reserved.
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following
// disclaimer in the documentation and/or other materials provided
// with the distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// This regression includes a number of cases where we did not correctly
// update a accessor property to a data property using Object.defineProperty.
var obj = { get value() {}, set value (v) { throw "Error";} };
Object.defineProperty(obj, "value",
{ value: 5, writable:true, configurable: true });
var desc = Object.getOwnPropertyDescriptor(obj, "value");
assertEquals(obj.value, 5);
assertTrue(desc.configurable);
assertTrue(desc.enumerable);
assertTrue(desc.writable);
assertEquals(desc.get, undefined);
assertEquals(desc.set, undefined);
var proto = {
get value() {},
set value(v) { Object.defineProperty(this, "value", {value: v}); }
};
var create = Object.create(proto);
assertEquals(create.value, undefined);
create.value = 4;
assertEquals(create.value, 4);
// These tests where provided in bug 959, but are all related to the this issue.
var obj1 = {};
Object.defineProperty(obj1, 'p', {get: undefined, set: undefined});
assertTrue("p" in obj1);
desc = Object.getOwnPropertyDescriptor(obj1, "p");
assertFalse(desc.configurable);
assertFalse(desc.enumerable);
assertEquals(desc.value, undefined);
assertEquals(desc.get, undefined);
assertEquals(desc.set, undefined);
var obj2 = { get p() {}};
Object.defineProperty(obj2, 'p', {get: undefined})
assertTrue("p" in obj2);
desc = Object.getOwnPropertyDescriptor(obj2, "p");
assertTrue(desc.configurable);
assertTrue(desc.enumerable);
assertEquals(desc.value, undefined);
assertEquals(desc.get, undefined);
assertEquals(desc.set, undefined);

View File

@ -0,0 +1,16 @@
// 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: --invoke-weak-callbacks --omit-quit --expose-wasm --allow-natives-syntax
load("test/mjsunit/wasm/wasm-module-builder.js");
const builder = new WasmModuleBuilder();
builder.addFunction('f', kSig_i_v).addBody([kExprI32Const, 42]);
const buffer = builder.toBuffer();
// Start async compilation, but don't wait for it to finish.
const module = WebAssembly.compile(buffer);
// This create the collator.
'퓛'.localeCompare();

View File

@ -0,0 +1,18 @@
// 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: --no-liftoff --no-wasm-tier-up --no-future --debug-code
load('test/mjsunit/wasm/wasm-module-builder.js');
const builder = new WasmModuleBuilder();
builder.addFunction('main', kSig_i_v)
.addBody([
kExprI64Const, 0xa3, 0x82, 0x83, 0x86, 0x8c, 0xd8, 0xae, 0xb5, 0x40,
kExprI32ConvertI64,
kExprI32Const, 0x00,
kExprI32Sub,
]).exportFunc();
const instance = builder.instantiate();
print(instance.exports.main(1, 2, 3));

View File

@ -0,0 +1,10 @@
// 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: --stack-size=100
let array = new Array(1);
array.splice(1, 0, array);
assertThrows(() => array.flat(Infinity), RangeError);

View File

@ -0,0 +1,14 @@
// 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: --stack-size=50
function __f_3() {
try {
__f_3();
} catch(e) {
eval("let fun = ({a} = {a: 30}) => {");
}
}
assertThrows(__f_3);

View File

@ -0,0 +1,5 @@
// 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.
assertThrows("async() => { for await (var a ;;) {} }", SyntaxError);

View File

@ -0,0 +1,25 @@
// 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
function MODULE() {
"use asm";
function f() {
bogus_function_table[0 & LIMIT]();
}
return { f:f };
}
var bogus_function_table = [ Object ];
var test_set = [ 0x3fffffff, 0x7fffffff, 0xffffffff ];
for (var i = 0; i < test_set.length; ++i) {
bogus_function_table[i] = Object;
var src = MODULE.toString();
src = src.replace(/MODULE/g, "Module" + i);
src = src.replace(/LIMIT/g, test_set[i]);
var module = eval("(" + src + ")");
module(this).f();
assertFalse(%IsAsmWasmCode(module));
}

View File

@ -0,0 +1,16 @@
// 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: --expose-wasm
load("test/mjsunit/wasm/wasm-module-builder.js");
var builder = new WasmModuleBuilder();
builder.addImportedTable("x", "table", 1, 10000000);
let module = new WebAssembly.Module(builder.toBuffer());
let table = new WebAssembly.Table({element: "anyfunc",
initial: 1, maximum:1000000});
let instance = new WebAssembly.Instance(module, {x: {table:table}});
assertThrows(() => table.grow(Infinity), TypeError);

View File

@ -0,0 +1,27 @@
// 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: --verify-heap --expose-gc
let paramName = '';
for (let i=0; i < 2**10; i++) {
paramName += 'a';
}
let params = '';
for (let i = 0; i < 2**10; i++) {
params += paramName + i + ',';
}
let fn = eval(`(
class A {
constructor (${params}) {
function lazy() {
return function lazier() { return ${paramName+1} }
};
return lazy;
}
})`);
gc()

View File

@ -0,0 +1,9 @@
// 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.
let a = {0: 5, 1: 4, 2: 3, length: 2};
Object.freeze(a);
assertThrows(() => Array.prototype.sort.call(a));
assertPropertiesEqual({0: 5, 1: 4, 2: 3, length: 2}, a);

View File

@ -0,0 +1,15 @@
// 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: --verify-heap
function __f_5() {
function __f_1() {
function __f_0() {
({y = eval()}) => assertEquals()();
}
}
}
__f_5();

View File

@ -0,0 +1,5 @@
// Copyright 2015 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.
assertThrows("a(function(){{let f;function f}})", SyntaxError);

View File

@ -0,0 +1,18 @@
// 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.
// Need a fast array with enough elements to surpass
// kMaxRegularHeapObjectSize.
var size = 63392;
var a = [];
function build() {
for (let i = 0; i < size; i++) {
a.push(i);
}
}
build();
function c(v) { return v + 0.5; }
a.map(c);

View File

@ -0,0 +1,18 @@
// 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.
// Flags: --expose-wasm
load("test/mjsunit/wasm/wasm-module-builder.js");
(function() {
var builder = new WasmModuleBuilder();
builder.addFunction("foo", kSig_i_ii)
.addBody([
kExprLoop, 00,
kExprBrTable, 0xfb, 0xff, 0xff, 0xff,
])
.exportFunc();
assertThrows(function() { builder.instantiate(); });
})();

View File

@ -264,7 +264,6 @@ var __v_11 = this;
var __v_12 = {};
var __v_13 = {};
try {
load("test/mjsunit/wasm/wasm-constants.js");
load("test/mjsunit/wasm/wasm-module-__v_1.js");
__v_2 = 0x10000;
} catch (e) {

View File

@ -0,0 +1,21 @@
// 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.
// Flags: --expose-wasm
load("test/mjsunit/wasm/wasm-module-builder.js");
(function() {
var builder = new WasmModuleBuilder();
builder.addMemory(1, 1, false);
builder.addFunction("foo", kSig_i_v)
.addBody([
kExprI32Const, 0x00,
kExprI32Const, 0x0b,
kExprI32Const, 0x0f,
kExprBrTable, 0xcb, 0xcb, 0xcb, 0x00, 0x00, 0xcb, 0x00 // entries=1238475
])
.exportFunc();
assertThrows(function() { builder.instantiate(); });
})();

View File

@ -0,0 +1,55 @@
// 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.
load("test/mjsunit/wasm/wasm-module-builder.js");
(function AddTest() {
let builder = new WasmModuleBuilder();
builder.addFunction("main", kSig_i_v)
.addBody([
kExprBlock, kWasmStmt,
kExprI64Const, 0,
// 0x80 ... 0x10 is the LEB encoding of 0x100000000. This is chosen so
// that the 64-bit constant has a non-zero top half. In this bug, the
// top half was clobbering eax, leading to the function return 1 rather
// than 0.
kExprI64Const, 0x80, 0x80, 0x80, 0x80, 0x10,
kExprI64Add,
kExprI64Eqz,
kExprBrIf, 0,
kExprI32Const, 0,
kExprReturn,
kExprEnd,
kExprI32Const, 0
])
.exportFunc();
let module = builder.instantiate();
assertEquals(0, module.exports.main());
})();
(function SubTest() {
let builder = new WasmModuleBuilder();
builder.addFunction("main", kSig_i_v)
.addBody([
kExprBlock, kWasmStmt,
kExprI64Const, 0,
// 0x80 ... 0x10 is the LEB encoding of 0x100000000. This is chosen so
// that the 64-bit constant has a non-zero top half. In this bug, the
// top half was clobbering eax, leading to the function return 1 rather
// than 0.
kExprI64Const, 0x80, 0x80, 0x80, 0x80, 0x10,
kExprI64Sub,
kExprI64Eqz,
kExprBrIf, 0,
kExprI32Const, 0,
kExprReturn,
kExprEnd,
kExprI32Const, 0
])
.exportFunc();
let module = builder.instantiate();
assertEquals(0, module.exports.main());
})();

View File

@ -0,0 +1,29 @@
// 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: --expose-wasm
load('test/mjsunit/wasm/wasm-module-builder.js');
let module1 = (() => {
let builder = new WasmModuleBuilder();
builder.addMemory(1, 1);
builder.addFunction('load', kSig_i_i)
.addBody([kExprI32Const, 0, kExprI32LoadMem, 0, 0])
.exportAs('load');
return new WebAssembly.Module(builder.toBuffer());
})();
let module2 = (() => {
let builder = new WasmModuleBuilder();
builder.addMemory(1, 1);
builder.addImport('A', 'load', kSig_i_i);
builder.addExportOfKind('load', kExternalFunction, 0);
return new WebAssembly.Module(builder.toBuffer());
})();
let instance1 = new WebAssembly.Instance(module1);
let instance2 = new WebAssembly.Instance(module2, {A: instance1.exports});
assertEquals(0, instance2.exports.load());

View File

@ -0,0 +1,19 @@
// 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.
load('test/mjsunit/wasm/wasm-module-builder.js');
(function() {
var builder = new WasmModuleBuilder();
builder.addMemory(31, 31, false);
builder.addFunction('test', kSig_i_iii)
.addBodyWithEnd([
// body:
kExprI64Const, 0x41, kExprI64Const, 0x41, kExprI64LtS, kExprI32Const,
0x01, kExprI32StoreMem, 0x00, 0x41, kExprUnreachable,
kExprEnd, // @60
])
.exportFunc();
var module = builder.instantiate();
})();

View File

@ -2,7 +2,6 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
load('test/mjsunit/wasm/wasm-constants.js');
load('test/mjsunit/wasm/wasm-module-builder.js');
(function() {

View File

@ -0,0 +1,18 @@
// 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.
load('test/mjsunit/wasm/wasm-module-builder.js');
(function() {
var builder = new WasmModuleBuilder();
builder.addMemory(31, 31, false);
builder.addFunction('test', kSig_l_v)
.addBodyWithEnd([
// body:
kExprUnreachable,
kExprEnd, // @374
])
.exportFunc();
var module = builder.instantiate();
})();

View File

@ -0,0 +1,25 @@
// 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.
// Flags: --expose-wasm
load("test/mjsunit/wasm/wasm-module-builder.js");
(function() {
var builder = new WasmModuleBuilder();
builder.addFunction("regression_644682", kSig_i_v)
.addBody([
kExprBlock, // @1
kExprI32Const, 0x3b,
kExprI32LoadMem, 0x00, 0x00,
kExprI32Const, 0x10,
kExprBrIf, 0x01, 0x00, // arity=1 depth0
kExprI32Const, 0x45,
kExprI32Const, 0x3b,
kExprI64LoadMem16S, 0x00, 0x3b,
kExprBrIf, 0x01, 0x00 // arity=1 depth0
])
.exportFunc();
assertThrows(function() { builder.instantiate(); });
})();

View File

@ -4,7 +4,6 @@
// Flags: --expose-wasm
load("test/mjsunit/wasm/wasm-constants.js");
load("test/mjsunit/wasm/wasm-module-builder.js");
// Non-standard opcodes.

View File

@ -0,0 +1,23 @@
// 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.
// Flags: --expose-wasm
load("test/mjsunit/wasm/wasm-module-builder.js");
(function() {
var builder = new WasmModuleBuilder();
builder.addMemory(1, 32, false);
builder.addFunction("foo", kSig_i_v)
.addBody([
kExprMemorySize, kMemoryZero,
kExprI32Const, 0x10,
kExprMemoryGrow, kMemoryZero,
kExprI32Mul,
])
.exportFunc();
var module = builder.instantiate();
var result = module.exports.foo();
assertEquals(1, result);
})();

View File

@ -0,0 +1,22 @@
// 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.
// Flags: --expose-wasm
load("test/mjsunit/wasm/wasm-module-builder.js");
(function() {
var builder = new WasmModuleBuilder();
builder.addMemory(1, 1, false);
builder.addFunction("foo", kSig_i_v)
.addBody([
kExprI32Const, 00,
kExprMemorySize,
kExprBrIf, 00,
kExprMemorySize,
kExprBr, 0xe7, 0xd2, 0xf2, 0xff, 0x1d
])
.exportFunc();
assertThrows(function() { builder.instantiate(); });
})();

View File

@ -0,0 +1,13 @@
// 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: --expose-wasm
load("test/mjsunit/wasm/wasm-module-builder.js");
(function() {
var builder = new WasmModuleBuilder();
var module = builder.instantiate();
assertTrue(typeof(module.exports) != "undefined");
})();

View File

@ -0,0 +1,388 @@
// 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.
// Flags: --expose-wasm
load("test/mjsunit/wasm/wasm-module-builder.js");
(function() {
var builder = new WasmModuleBuilder();
builder.addMemory(0, 0, false);
builder.addFunction("test", kSig_i_iii)
.addBody([
kExprI32Const, 0x0b,
kExprI32Clz,
kExprI32Clz,
kExprI32Clz,
kExprI32Const, 0x67,
kExprI32Const, 0x07,
kExprI32Clz,
kExprI32Clz,
kExprI32Clz,
kExprI32Clz,
kExprI32Clz,
kExprI32Eq,
kExprI32RemU,
kExprI32Clz,
kExprI32Const, 0x25,
kExprI32Const, 0x82, 0x6c,
kExprI32Add,
kExprI32Const, 0x41,
kExprI32Clz,
kExprI32Clz,
kExprI32Const, 0x41,
kExprI32Const, 0x41,
kExprI32Const, 0x70,
kExprI32Clz,
kExprI32Clz,
kExprI32Clz,
kExprI32Const, 0x70,
kExprI32Clz,
kExprI32Clz,
kExprI32Const, 0x67,
kExprI32Clz,
kExprI32Clz,
kExprI32GeS,
kExprI32Const, 0x67,
kExprI32Clz,
kExprI32Clz,
kExprI32Clz,
kExprI32Clz,
kExprI32Const, 0x41,
kExprDrop,
kExprI32Const, 0x41,
kExprI32Const, 0x41,
kExprI32Clz,
kExprI32Clz,
kExprI32Const, 0x41,
kExprI32Clz,
kExprI32Clz,
kExprI32Clz,
kExprI32Clz,
kExprI32Clz,
kExprI32Clz,
kExprI32Clz,
kExprCallFunction, 0x00, // function #0
kExprCallFunction, 0x00, // function #0
kExprNop,
kExprNop,
kExprNop,
kExprNop,
kExprNop,
kExprNop,
kExprNop,
kExprNop,
kExprNop,
kExprNop,
kExprNop,
kExprNop,
kExprNop,
kExprI32Const, 0x41,
kExprI32Const, 0x41,
kExprI32Const, 0x01,
kExprNop,
kExprNop,
kExprNop,
kExprNop,
kExprSelect,
kExprNop,
kExprNop,
kExprNop,
kExprNop,
kExprNop,
kExprI32Const, 0x41,
kExprI32Const, 0x0e,
kExprI32Const, 0x41,
kExprI32Const, 0x41,
kExprI32Clz,
kExprI32Clz,
kExprI32Clz,
kExprI32Clz,
kExprI32Clz,
kExprI32Clz,
kExprI32Const, 0x41,
kExprI32Const, 0x41,
kExprI32Clz,
kExprI32Clz,
kExprI32Clz,
kExprI32Clz,
kExprI32Clz,
kExprI32Clz,
kExprI32Clz,
kExprI32Clz,
kExprCallFunction, 0x00, // function #0
kExprCallFunction, 0x00, // function #0
kExprNop,
kExprNop,
kExprNop,
kExprNop,
kExprNop,
kExprNop,
kExprNop,
kExprNop,
kExprNop,
kExprNop,
kExprNop,
kExprNop,
kExprNop,
kExprI32Const, 0x41,
kExprI32Const, 0x41,
kExprI32Const, 0x01,
kExprNop,
kExprNop,
kExprNop,
kExprNop,
kExprSelect,
kExprNop,
kExprNop,
kExprNop,
kExprNop,
kExprNop,
kExprI32Const, 0x41,
kExprI32Const, 0x0e,
kExprI32Const, 0x41,
kExprI32Const, 0x41,
kExprI32Clz,
kExprI32Clz,
kExprI32Clz,
kExprI32Clz,
kExprI32Clz,
kExprI32Clz,
kExprI32Const, 0x41,
kExprI32Const, 0x41,
kExprI32Clz,
kExprI32Clz,
kExprI32Clz,
kExprI32Clz,
kExprI32Clz,
kExprI32Clz,
kExprI32Clz,
kExprI32Clz,
kExprCallFunction, 0x00, // function #0
kExprCallFunction, 0x00, // function #0
kExprNop,
kExprNop,
kExprNop,
kExprNop,
kExprNop,
kExprNop,
kExprNop,
kExprNop,
kExprNop,
kExprNop,
kExprNop,
kExprNop,
kExprNop,
kExprI32Const, 0x41,
kExprI32Const, 0x41,
kExprNop,
kExprNop,
kExprNop,
kExprNop,
kExprNop,
kExprI32Const, 0x41,
kExprI32Const, 0x41,
kExprI32Const, 0x01,
kExprNop,
kExprNop,
kExprNop,
kExprNop,
kExprSelect,
kExprNop,
kExprNop,
kExprNop,
kExprNop,
kExprNop,
kExprI32Const, 0x41,
kExprI32Const, 0x0e,
kExprI32Const, 0x41,
kExprI32Const, 0x41,
kExprI32Clz,
kExprI32Clz,
kExprI32Clz,
kExprI32Clz,
kExprI32Clz,
kExprI32Clz,
kExprI32Const, 0x41,
kExprI32Const, 0x41,
kExprI32Clz,
kExprI32Clz,
kExprI32Clz,
kExprI32Clz,
kExprI32Clz,
kExprI32Clz,
kExprI32Clz,
kExprI32Clz,
kExprCallFunction, 0x00, // function #0
kExprCallFunction, 0x00, // function #0
kExprNop,
kExprNop,
kExprNop,
kExprNop,
kExprNop,
kExprNop,
kExprNop,
kExprNop,
kExprNop,
kExprNop,
kExprNop,
kExprNop,
kExprNop,
kExprI32Const, 0x41,
kExprI32Const, 0x41,
kExprI32Const, 0x01,
kExprNop,
kExprNop,
kExprNop,
kExprNop,
kExprSelect,
kExprNop,
kExprNop,
kExprNop,
kExprNop,
kExprNop,
kExprI32Const, 0x41,
kExprI32Const, 0x0e,
kExprI32Const, 0x41,
kExprI32Const, 0x41,
kExprI32Clz,
kExprI32Clz,
kExprI32Clz,
kExprI32Clz,
kExprI32Clz,
kExprI32Clz,
kExprI32Const, 0x41,
kExprI32Const, 0x41,
kExprI32Clz,
kExprI32Clz,
kExprI32Clz,
kExprI32Clz,
kExprI32Clz,
kExprI32Clz,
kExprI32Clz,
kExprI32Clz,
kExprCallFunction, 0x00, // function #0
kExprCallFunction, 0x00, // function #0
kExprNop,
kExprNop,
kExprNop,
kExprNop,
kExprNop,
kExprNop,
kExprNop,
kExprNop,
kExprNop,
kExprNop,
kExprNop,
kExprNop,
kExprNop,
kExprNop,
kExprNop,
kExprNop,
kExprI32Const, 0x4a,
kExprI32Const, 0x41,
kExprI32LtU,
kExprI32Const, 0x67,
kExprI32Clz,
kExprI32GtS,
kExprI32Const, 0x41,
kExprI32Const, 0x41,
kExprI32Ne,
kExprI32Clz,
kExprI32Clz,
kExprI32Clz,
kExprI32Clz,
kExprI32Clz,
kExprI32Const, 0x41,
kExprI32Const, 0x1a,
kExprI32Const, 0x71,
kExprI32And,
kExprI32And,
kExprI32And,
kExprI32And,
kExprI32And,
kExprI32And,
kExprI32And,
kExprI32And,
kExprI32ShrS,
kExprI32Clz,
kExprCallFunction, 0x00, // function #0
kExprCallFunction, 0x00, // function #0
kExprI32Clz,
kExprNop,
kExprNop,
kExprNop,
kExprNop,
kExprNop,
kExprNop,
kExprNop,
kExprNop,
kExprNop,
kExprNop,
kExprNop,
kExprNop,
kExprNop,
kExprNop,
kExprNop,
kExprNop,
kExprNop,
kExprNop,
kExprI32Const, 0x4a,
kExprI32Const, 0x41,
kExprI32LtU,
kExprI32Const, 0x67,
kExprI32Clz,
kExprI32GtS,
kExprI32Const, 0x41,
kExprI32Const, 0x41,
kExprI32Ne,
kExprI32Clz,
kExprI32Clz,
kExprI32Clz,
kExprI32Clz,
kExprI32Clz,
kExprI32Const, 0x41,
kExprI32Const, 0x1a,
kExprI32Const, 0x71,
kExprI32And,
kExprI32And,
kExprI32And,
kExprI32And,
kExprI32And,
kExprI32And,
kExprI32And,
kExprI32And,
kExprI32ShrS,
kExprI32Clz,
kExprCallFunction, 0x00, // function #0
kExprCallFunction, 0x00, // function #0
kExprI32Clz,
kExprNop,
kExprNop,
kExprNop,
kExprNop,
kExprNop,
kExprNop,
kExprNop,
kExprNop,
kExprNop,
kExprNop,
kExprNop,
kExprI32Clz,
kExprI32Clz,
kExprI32Clz,
kExprI32Clz,
kExprUnreachable,
kExprCallFunction, 0x00, // function #0
kExprCallFunction, 0x00, // function #0
kExprNop,
kExprNop,
kExprNop,
kExprNop,
kExprReturn
])
.exportFunc();
var module = builder.instantiate();
assertTrue(module != undefined);
})();

View File

@ -0,0 +1,33 @@
// 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.
load('test/mjsunit/wasm/wasm-module-builder.js');
var name = 'regression_684858';
function patchNameLength(buffer) {
var count = 0;
var view = new Uint8Array(buffer);
for (var i = 0, e = view.length - name.length; i <= e; ++i) {
var subs = String.fromCharCode.apply(null, view.slice(i, i + name.length));
if (subs != name) continue;
++count;
// One byte before this name, its length is encoded.
// Patch this to 127, making it out of bounds.
if (view.length >= 127) throw Error('cannot patch reliably');
if (view[i - 1] != name.length) throw Error('unexpected length');
view[i - 1] = 0x7f;
}
if (count != 1) throw Error('did not find name');
}
var builder = new WasmModuleBuilder();
builder.addFunction(name, kSig_i_v)
.addBody([kExprI32Const, 2, kExprI32Const, 0, kExprI32DivU])
.exportAs('main');
var buffer = builder.toBuffer();
patchNameLength(buffer);
var module = new WebAssembly.Module(buffer);
var instance = new WebAssembly.Instance(module);
assertThrows(() => instance.exports.main(), WebAssembly.RuntimeError);

View File

@ -0,0 +1,41 @@
// 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.
load('test/mjsunit/wasm/wasm-module-builder.js');
(function() {
var builder = new WasmModuleBuilder();
builder.addMemory(16, 32, false);
builder.addFunction('test', kSig_i_i)
.addBodyWithEnd([
kExprI32Const, 0x41,
kExprI32Const, 0x45,
kExprI32Const, 0x41,
kExprI32DivU,
kExprI32LoadMem8S, 0x00, 0x3a,
kExprI32Const, 0x75,
kExprI32Const, 0x75,
kExprI32Const, 0x6e,
kExprI32Eqz,
kExprI32LoadMem8S, 0x00, 0x3a,
kExprI32Add,
kExprI32DivU,
kExprI32LoadMem8S, 0x00, 0x74,
kExprI32And,
kExprI32Eqz,
kExprI32And,
kExprMemoryGrow, 0x00,
kExprI32Const, 0x55,
kExprI32LoadMem8S, 0x00, 0x3a,
kExprI32LoadMem16U, 0x00, 0x71,
kExprI32Const, 0x00,
kExprI32RemU,
kExprI32And,
kExprI32Eqz,
kExprEnd, // @44
])
.exportFunc();
var module = builder.instantiate();
assertThrows(() => {module.exports.test(1);});
})();

View File

@ -0,0 +1,24 @@
// 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.
load('test/mjsunit/wasm/wasm-module-builder.js');
(function() {
var builder = new WasmModuleBuilder();
builder.addMemory(16, 32, false);
builder.addFunction('test', kSig_i_i)
.addBodyWithEnd([
kExprGetLocal, 0x00,
kExprI32Const, 0x29,
kExprI32Shl,
kExprI32Const, 0x18,
kExprI32ShrS,
kExprI32Const, 0x18,
kExprI32Shl,
kExprEnd,
])
.exportFunc();
var module = builder.instantiate();
assertEquals(0, module.exports.test(16));
})();

View File

@ -0,0 +1,29 @@
// 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.
load('test/mjsunit/wasm/wasm-module-builder.js');
// This test checks for accidental sign extension. The Wasm spec says we do
// arbitrary precision unsigned arithmetic to compute the memory address,
// meaning this test should do 0xfffffffc + 8, which is 0x100000004 and out of
// bounds. However, if we interpret 0xfffffffc as -4, then the result is 4 and
// succeeds erroneously.
(function() {
let builder = new WasmModuleBuilder();
builder.addMemory(1, 1, false);
builder.addFunction('test', kSig_v_v)
.addBody([
kExprI32Const, 0x7c, // address = -4
kExprI32Const, 0,
kExprI32StoreMem, 0, 8, // align = 0, offset = 8
])
.exportFunc();
let module = builder.instantiate();
assertTraps(kTrapMemOutOfBounds, module.exports.test);
})();

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