mirror of
https://github.com/tc39/test262.git
synced 2025-04-08 19:35:28 +02:00
[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:
parent
8d9f7690f8
commit
39d5434ab1
@ -1,5 +1,5 @@
|
||||
{
|
||||
"sourceRevisionAtLastExport": "f85a3554",
|
||||
"targetRevisionAtLastExport": "6bb8f41e0a",
|
||||
"sourceRevisionAtLastExport": "ddf72e4b",
|
||||
"targetRevisionAtLastExport": "8d9f7690f8",
|
||||
"curatedFiles": {}
|
||||
}
|
61
implementation-contributed/v8/intl/bigint/tolocalestring.js
Normal file
61
implementation-contributed/v8/intl/bigint/tolocalestring.js
Normal 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", // "1 234 567 890 123 456"
|
||||
"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);
|
||||
}
|
@ -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);
|
@ -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);
|
@ -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);
|
||||
});
|
||||
}
|
||||
);
|
@ -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]);
|
@ -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);
|
@ -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;
|
@ -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;
|
@ -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;
|
8
implementation-contributed/v8/intl/regress-7770.js
Normal file
8
implementation-contributed/v8/intl/regress-7770.js
Normal 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());
|
10
implementation-contributed/v8/intl/regress-925216.js
Normal file
10
implementation-contributed/v8/intl/regress-925216.js
Normal 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);
|
@ -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.
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
});
|
||||
});
|
@ -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);
|
||||
}
|
||||
});
|
@ -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);
|
@ -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);
|
@ -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));
|
@ -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);
|
||||
}
|
||||
);
|
@ -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);
|
@ -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
|
||||
);
|
@ -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);
|
||||
}
|
@ -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
|
||||
|
@ -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();
|
@ -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 []);
|
||||
}
|
||||
}
|
||||
}
|
||||
`);
|
||||
}
|
@ -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);
|
@ -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);
|
||||
}
|
@ -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);
|
||||
|
@ -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();
|
@ -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}`);
|
||||
}
|
||||
})();
|
@ -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 []) {} }")
|
@ -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);
|
||||
}
|
@ -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);
|
||||
}
|
@ -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);
|
||||
}
|
@ -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);
|
||||
}
|
@ -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);
|
||||
})();
|
@ -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();
|
||||
|
@ -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);
|
@ -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);
|
@ -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);
|
@ -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);
|
||||
|
@ -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]);
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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());
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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);
|
@ -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);
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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);
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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);
|
@ -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);
|
@ -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);
|
||||
}
|
||||
|
@ -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);
|
@ -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));
|
||||
})();
|
@ -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();
|
||||
|
@ -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,7 +511,6 @@ var prettyPrinted;
|
||||
failWithMessage("Did not throw exception");
|
||||
};
|
||||
|
||||
|
||||
assertThrowsEquals = function assertThrowsEquals(fun, val) {
|
||||
try {
|
||||
fun();
|
||||
@ -533,15 +535,11 @@ var prettyPrinted;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
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() {
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -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();
|
@ -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');
|
@ -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);
|
@ -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());
|
||||
})();
|
@ -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());
|
||||
})();
|
@ -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;
|
||||
}
|
||||
}
|
@ -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);
|
@ -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();
|
@ -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));
|
@ -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);
|
@ -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);
|
@ -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);
|
@ -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));
|
||||
}
|
@ -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);
|
@ -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()
|
@ -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);
|
@ -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();
|
@ -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);
|
@ -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);
|
@ -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(); });
|
||||
})();
|
@ -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) {
|
||||
|
@ -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(); });
|
||||
})();
|
@ -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());
|
||||
})();
|
@ -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());
|
@ -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();
|
||||
})();
|
@ -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() {
|
||||
|
@ -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();
|
||||
})();
|
@ -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(); });
|
||||
})();
|
@ -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.
|
||||
|
@ -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);
|
||||
})();
|
@ -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(); });
|
||||
})();
|
@ -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");
|
||||
})();
|
@ -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);
|
||||
})();
|
@ -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);
|
@ -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);});
|
||||
})();
|
@ -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));
|
||||
})();
|
@ -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
Loading…
x
Reference in New Issue
Block a user