From 30d7394e89165a9b0ae9ee107c4c20344b6e635e Mon Sep 17 00:00:00 2001 From: test262-automation <test262-automation@bocoup.com> Date: Thu, 17 Jan 2019 19:35:57 +0000 Subject: [PATCH] [v8-test262-automation] Updated curation log with latest revision sha's from export and changed files. sourceRevisionAtLastExport: f88d169e targetRevisionAtLastExport: ad1b4aadf8 --- .../curation_logs/v8.json | 4 +- .../CanonicalizeLocaleListTakeLocale.js | 65 ++ .../v8/intl/locale/property.js | 22 + .../v8/intl/regress-8657.js | 7 + .../v8/intl/regress-917151.js | 11 + .../resolved-options-nu.js | 97 +++ .../v8/mjsunit/asm/regress-920076.js | 13 + .../v8/mjsunit/compiler/regress-919754.js | 15 + .../v8/mjsunit/es6/block-sloppy-function.js | 668 ++++++++++++++++ .../mjsunit/es6/destructuring-assignment.js | 55 ++ .../v8/mjsunit/es6/unscopables.js | 739 ++++++++++++++++++ .../v8/mjsunit/harmony/hashbang-eval.js | 11 + .../mjsunit/harmony/private-fields-static.js | 356 +++++++++ .../v8/mjsunit/mjsunit.status | 43 +- .../v8/mjsunit/object-seal.js | 395 ++++++++++ .../v8/mjsunit/regress-918763.js | 14 + .../v8/mjsunit/regress/regress-8630.js | 32 + .../v8/mjsunit/regress/regress-8659.js | 5 + .../v8/mjsunit/regress/regress-913844.js | 7 + .../v8/mjsunit/regress/regress-917215.js | 6 + .../v8/mjsunit/regress/regress-917755.js | 12 + .../v8/mjsunit/regress/regress-917988.js | 31 + .../v8/mjsunit/regress/regress-919340.js | 17 + .../v8/mjsunit/regress/regress-919710.js | 5 + .../v8/mjsunit/regress/regress-921382.js | 5 + .../mjsunit/regress/regress-crbug-917076.js | 20 + .../mjsunit/regress/regress-crbug-917980.js | 33 + .../mjsunit/regress/regress-crbug-920184.js | 14 + ...ess-loop-var-assign-without-block-scope.js | 14 + ...-sloppy-block-function-hoisting-dynamic.js | 6 + .../v8/mjsunit/regress/wasm/regress-905815.js | 27 + .../v8/mjsunit/regress/wasm/regress-917412.js | 34 + .../v8/mjsunit/regress/wasm/regress-917588.js | 26 + .../mjsunit/regress/wasm/regress-917588b.js | 55 ++ .../v8/mjsunit/regress/wasm/regress-918149.js | 12 + .../v8/mjsunit/regress/wasm/regress-918284.js | 21 + .../v8/mjsunit/regress/wasm/regress-918917.js | 22 + .../v8/mjsunit/regress/wasm/regress-919308.js | 37 + .../v8/mjsunit/regress/wasm/regress-919533.js | 25 + .../v8/mjsunit/regress/wasm/regress-922432.js | 21 + .../v8/mjsunit/testcfg.py | 283 +++++++ .../v8/test262/test262.status | 86 +- 42 files changed, 3290 insertions(+), 81 deletions(-) create mode 100644 implementation-contributed/v8/intl/general/CanonicalizeLocaleListTakeLocale.js create mode 100644 implementation-contributed/v8/intl/locale/property.js create mode 100644 implementation-contributed/v8/intl/regress-8657.js create mode 100644 implementation-contributed/v8/intl/regress-917151.js create mode 100644 implementation-contributed/v8/intl/relative-time-format/resolved-options-nu.js create mode 100644 implementation-contributed/v8/mjsunit/asm/regress-920076.js create mode 100644 implementation-contributed/v8/mjsunit/compiler/regress-919754.js create mode 100644 implementation-contributed/v8/mjsunit/harmony/hashbang-eval.js create mode 100644 implementation-contributed/v8/mjsunit/harmony/private-fields-static.js create mode 100644 implementation-contributed/v8/mjsunit/regress-918763.js create mode 100644 implementation-contributed/v8/mjsunit/regress/regress-8630.js create mode 100644 implementation-contributed/v8/mjsunit/regress/regress-8659.js create mode 100644 implementation-contributed/v8/mjsunit/regress/regress-913844.js create mode 100644 implementation-contributed/v8/mjsunit/regress/regress-917215.js create mode 100644 implementation-contributed/v8/mjsunit/regress/regress-917755.js create mode 100644 implementation-contributed/v8/mjsunit/regress/regress-917988.js create mode 100644 implementation-contributed/v8/mjsunit/regress/regress-919340.js create mode 100644 implementation-contributed/v8/mjsunit/regress/regress-919710.js create mode 100644 implementation-contributed/v8/mjsunit/regress/regress-921382.js create mode 100644 implementation-contributed/v8/mjsunit/regress/regress-crbug-917076.js create mode 100644 implementation-contributed/v8/mjsunit/regress/regress-crbug-917980.js create mode 100644 implementation-contributed/v8/mjsunit/regress/regress-crbug-920184.js create mode 100644 implementation-contributed/v8/mjsunit/regress/regress-loop-var-assign-without-block-scope.js create mode 100644 implementation-contributed/v8/mjsunit/regress/regress-sloppy-block-function-hoisting-dynamic.js create mode 100644 implementation-contributed/v8/mjsunit/regress/wasm/regress-905815.js create mode 100644 implementation-contributed/v8/mjsunit/regress/wasm/regress-917412.js create mode 100644 implementation-contributed/v8/mjsunit/regress/wasm/regress-917588.js create mode 100644 implementation-contributed/v8/mjsunit/regress/wasm/regress-917588b.js create mode 100644 implementation-contributed/v8/mjsunit/regress/wasm/regress-918149.js create mode 100644 implementation-contributed/v8/mjsunit/regress/wasm/regress-918284.js create mode 100644 implementation-contributed/v8/mjsunit/regress/wasm/regress-918917.js create mode 100644 implementation-contributed/v8/mjsunit/regress/wasm/regress-919308.js create mode 100644 implementation-contributed/v8/mjsunit/regress/wasm/regress-919533.js create mode 100644 implementation-contributed/v8/mjsunit/regress/wasm/regress-922432.js diff --git a/implementation-contributed/curation_logs/v8.json b/implementation-contributed/curation_logs/v8.json index f73abe59c5..b7e11fb57a 100644 --- a/implementation-contributed/curation_logs/v8.json +++ b/implementation-contributed/curation_logs/v8.json @@ -1,5 +1,5 @@ { - "sourceRevisionAtLastExport": "f88d169e", - "targetRevisionAtLastExport": "ad1b4aadf8", + "sourceRevisionAtLastExport": "f85a3554", + "targetRevisionAtLastExport": "6bb8f41e0a", "curatedFiles": {} } \ No newline at end of file diff --git a/implementation-contributed/v8/intl/general/CanonicalizeLocaleListTakeLocale.js b/implementation-contributed/v8/intl/general/CanonicalizeLocaleListTakeLocale.js new file mode 100644 index 0000000000..e4ff793cca --- /dev/null +++ b/implementation-contributed/v8/intl/general/CanonicalizeLocaleListTakeLocale.js @@ -0,0 +1,65 @@ +// 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-locale +// +// Test NumberFormat will accept Intl.Locale as first parameter, or +// as in the array. + +let tag = "zh-Hant-TW-u-nu-thai" +let l = new Intl.Locale(tag); + +var nf; +// Test with String +assertDoesNotThrow(() => nf = new Intl.NumberFormat(tag)); +assertEquals(tag, nf.resolvedOptions().locale); + +// Test with Array with one String +assertDoesNotThrow(() => nf = new Intl.NumberFormat([tag])); +assertEquals(tag, nf.resolvedOptions().locale); + +// Test with Array with two String +assertDoesNotThrow(() => nf = new Intl.NumberFormat([tag, "en"])); +assertEquals(tag, nf.resolvedOptions().locale); + +// Test with a Locale +assertDoesNotThrow(() => nf = new Intl.NumberFormat(l)); +assertEquals(tag, nf.resolvedOptions().locale); + +// Test with a Array of one Locale +assertDoesNotThrow(() => nf = new Intl.NumberFormat([l])); +assertEquals(tag, nf.resolvedOptions().locale); + +// Test with a Array of one Locale and a Sring +assertDoesNotThrow(() => nf = new Intl.NumberFormat([l, "en"])); +assertEquals(tag, nf.resolvedOptions().locale); + +// Test DateTimeFormat +var df; +assertDoesNotThrow(() => df = new Intl.DateTimeFormat(tag)); +assertEquals(tag, df.resolvedOptions().locale); +assertDoesNotThrow(() => df = new Intl.DateTimeFormat([tag])); +assertEquals(tag, df.resolvedOptions().locale); + +// Test RelativeTimeFormat +var rtf; +assertDoesNotThrow(() => rtf = new Intl.RelativeTimeFormat(tag)); +assertEquals(tag, rtf.resolvedOptions().locale); +assertDoesNotThrow(() => rtf = new Intl.RelativeTimeFormat([tag])); +assertEquals(tag, rtf.resolvedOptions().locale); + +// Test ListFormat +tag = "zh-Hant-TW" +var lf; +assertDoesNotThrow(() => lf = new Intl.ListFormat(tag)); +assertEquals(tag, lf.resolvedOptions().locale); +assertDoesNotThrow(() => lf = new Intl.ListFormat([tag])); +assertEquals(tag, lf.resolvedOptions().locale); + +// Test Collator +var col; +assertDoesNotThrow(() => col = new Intl.Collator(tag)); +assertEquals(tag, lf.resolvedOptions().locale); +assertDoesNotThrow(() => col = new Intl.Collator([tag])); +assertEquals(tag, lf.resolvedOptions().locale); diff --git a/implementation-contributed/v8/intl/locale/property.js b/implementation-contributed/v8/intl/locale/property.js new file mode 100644 index 0000000000..cbe076842f --- /dev/null +++ b/implementation-contributed/v8/intl/locale/property.js @@ -0,0 +1,22 @@ +// 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-locale + +// Make sure that accessing locale property will return undefined instead of +// crash. + +let locale = new Intl.Locale('sr'); + +assertEquals('sr', locale.toString()); +assertEquals('sr', locale.baseName); +assertEquals('sr', locale.language); +assertEquals(undefined, locale.script); +assertEquals(undefined, locale.region); +assertEquals(false, locale.numeric); +assertEquals(undefined, locale.calendar); +assertEquals(undefined, locale.collation); +assertEquals(undefined, locale.hourCycle); +assertEquals(undefined, locale.caseFirst); +assertEquals(undefined, locale.numberingSystem); diff --git a/implementation-contributed/v8/intl/regress-8657.js b/implementation-contributed/v8/intl/regress-8657.js new file mode 100644 index 0000000000..c1c5cea708 --- /dev/null +++ b/implementation-contributed/v8/intl/regress-8657.js @@ -0,0 +1,7 @@ +// 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-locale + +assertDoesNotThrow(() => new Intl.Locale('und')); diff --git a/implementation-contributed/v8/intl/regress-917151.js b/implementation-contributed/v8/intl/regress-917151.js new file mode 100644 index 0000000000..9b971fe2b9 --- /dev/null +++ b/implementation-contributed/v8/intl/regress-917151.js @@ -0,0 +1,11 @@ +// 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. + +// Regression test for 917151 + +assertThrows( + () => Number.prototype.toLocaleString.call( + -22, + "x-6-6-6-6-6-6-6-6-6-6-6-6-6-6-6-6-6-6-6-6-6-6-6-6-6-6-6-6-6-6-6-6-6-6-6-6-6-6-6-6-6-6-6-6-6-6-6-6-6-6-6-6-6-6-6-6-6-6-6-6-6-6-6-6-6-6-6-6-6-6-6-6"), + RangeError) diff --git a/implementation-contributed/v8/intl/relative-time-format/resolved-options-nu.js b/implementation-contributed/v8/intl/relative-time-format/resolved-options-nu.js new file mode 100644 index 0000000000..fb1fa72a93 --- /dev/null +++ b/implementation-contributed/v8/intl/relative-time-format/resolved-options-nu.js @@ -0,0 +1,97 @@ +// 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-relative-time-format + +// For locale default the numberingSystem to 'latn' +assertEquals( + "latn", + new Intl.RelativeTimeFormat("ar").resolvedOptions().numberingSystem +); +assertEquals( + "latn", + new Intl.RelativeTimeFormat("en").resolvedOptions().numberingSystem +); +assertEquals( + "latn", + new Intl.RelativeTimeFormat("fr").resolvedOptions().numberingSystem +); +assertEquals( + "latn", + new Intl.RelativeTimeFormat("hi").resolvedOptions().numberingSystem +); +assertEquals( + "latn", + new Intl.RelativeTimeFormat("th").resolvedOptions().numberingSystem +); +assertEquals( + "latn", + new Intl.RelativeTimeFormat("zh-Hant").resolvedOptions().numberingSystem +); + +// For locale default the numberingSystem to other than 'latn' +assertEquals( + "arab", + new Intl.RelativeTimeFormat("ar-TD").resolvedOptions().numberingSystem +); +assertEquals( + "arabext", + new Intl.RelativeTimeFormat("fa").resolvedOptions().numberingSystem +); +assertEquals( + "beng", + new Intl.RelativeTimeFormat("bn").resolvedOptions().numberingSystem +); + +// For locale use -u-nu- to change to other numberingSystem +assertEquals( + "thai", + new Intl.RelativeTimeFormat("en-u-nu-thai").resolvedOptions() + .numberingSystem +); +assertEquals( + "arab", + new Intl.RelativeTimeFormat("en-u-nu-arab").resolvedOptions() + .numberingSystem +); + +// For locale which default others but use -u-nu-latn to change to 'latn' numberingSystem +assertEquals( + "latn", + new Intl.RelativeTimeFormat("fa-u-nu-latn").resolvedOptions() + .numberingSystem +); +assertEquals( + "latn", + new Intl.RelativeTimeFormat("ar-TD-u-nu-latn").resolvedOptions() + .numberingSystem +); +assertEquals( + "latn", + new Intl.RelativeTimeFormat("fa-u-nu-latn").resolvedOptions() + .numberingSystem +); +assertEquals( + "latn", + new Intl.RelativeTimeFormat("bn-u-nu-latn").resolvedOptions() + .numberingSystem +); + +// For locale use -u-nu- with invalid value still back to default. +assertEquals( + "latn", + new Intl.RelativeTimeFormat("en-u-nu-abcd").resolvedOptions() + .numberingSystem +); + +assertEquals( + "arabext", + new Intl.RelativeTimeFormat("fa-u-nu-abcd").resolvedOptions() + .numberingSystem +); +assertEquals( + "beng", + new Intl.RelativeTimeFormat("bn-u-nu-abcd").resolvedOptions() + .numberingSystem +); diff --git a/implementation-contributed/v8/mjsunit/asm/regress-920076.js b/implementation-contributed/v8/mjsunit/asm/regress-920076.js new file mode 100644 index 0000000000..754b931cb8 --- /dev/null +++ b/implementation-contributed/v8/mjsunit/asm/regress-920076.js @@ -0,0 +1,13 @@ +// 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 Module() { + "use asm"; + function f() {} + return f +} +eval("(" + Module.toString().replace(/;/, String.fromCharCode(8233)) + ")();"); +assertFalse(%IsAsmWasmCode(Module)); // Valid asm.js, but we reject Unicode. diff --git a/implementation-contributed/v8/mjsunit/compiler/regress-919754.js b/implementation-contributed/v8/mjsunit/compiler/regress-919754.js new file mode 100644 index 0000000000..5f20aad928 --- /dev/null +++ b/implementation-contributed/v8/mjsunit/compiler/regress-919754.js @@ -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: --allow-natives-syntax + + +function f(get, ...a) { + for (let i = 0; i < 1000; i++) { + if (i === 999) %OptimizeOsr(); + a.map(f); + } + return get(); +} +assertThrows(f); diff --git a/implementation-contributed/v8/mjsunit/es6/block-sloppy-function.js b/implementation-contributed/v8/mjsunit/es6/block-sloppy-function.js index e69de29bb2..5d22cd85c0 100644 --- a/implementation-contributed/v8/mjsunit/es6/block-sloppy-function.js +++ b/implementation-contributed/v8/mjsunit/es6/block-sloppy-function.js @@ -0,0 +1,668 @@ +// 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. + +// Test Annex B 3.3 semantics for functions declared in blocks in sloppy mode. +// http://www.ecma-international.org/ecma-262/6.0/#sec-block-level-function-declarations-web-legacy-compatibility-semantics + +(function overridingLocalFunction() { + var x = []; + assertEquals('function', typeof f); + function f() { + x.push(1); + } + f(); + { + f(); + function f() { + x.push(2); + } + f(); + } + f(); + { + f(); + function f() { + x.push(3); + } + f(); + } + f(); + assertArrayEquals([1, 2, 2, 2, 3, 3, 3], x); +})(); + +(function newFunctionBinding() { + var x = []; + assertEquals('undefined', typeof f); + { + f(); + function f() { + x.push(2); + } + f(); + } + f(); + { + f(); + function f() { + x.push(3); + } + f(); + } + f(); + assertArrayEquals([2, 2, 2, 3, 3, 3], x); +})(); + +(function shadowingLetDoesntBind() { + let f = 1; + assertEquals(1, f); + { + let y = 3; + function f() { + y = 2; + } + f(); + assertEquals(2, y); + } + assertEquals(1, f); +})(); + +(function shadowingLetDoesntBindGenerator() { + let f = function *f() { + while(true) { + yield 1; + } + }; + assertEquals(1, f().next().value); + { + function *f() { + while(true) { + yield 2; + } + } + assertEquals(2, f().next().value); + } + assertEquals(1, f().next().value); +})(); + +(function shadowingClassDoesntBind() { + class f { } + assertEquals('class f { }', f.toString()); + { + let y = 3; + function f() { + y = 2; + } + f(); + assertEquals(2, y); + } + assertEquals('class f { }', f.toString()); +})(); + +(function shadowingConstDoesntBind() { + const f = 1; + assertEquals(1, f); + { + let y = 3; + function f() { + y = 2; + } + f(); + assertEquals(2, y); + } + assertEquals(1, f); +})(); + +(function shadowingVarBinds() { + var f = 1; + assertEquals(1, f); + { + let y = 3; + function f() { + y = 2; + } + f(); + assertEquals(2, y); + } + assertEquals('function', typeof f); +})(); + +(function complexParams(a = 0) { + { + let y = 3; + function f(b = 0) { + y = 2; + } + f(); + assertEquals(2, y); + } + assertEquals('function', typeof f); +})(); + +(function complexVarParams(a = 0) { + var f; + { + let y = 3; + function f(b = 0) { + y = 2; + } + f(); + assertEquals(2, y); + } + assertEquals('function', typeof f); +})(); + +(function conditional() { + if (true) { + function f() { return 1; } + } else { + function f() { return 2; } + } + assertEquals(1, f()); + + if (false) { + function g() { return 1; } + } else { + function g() { return 2; } + } + assertEquals(2, g()); +})(); + +(function skipExecution() { + { + function f() { return 1; } + } + assertEquals(1, f()); + { + function f() { return 2; } + } + assertEquals(2, f()); + L: { + assertEquals(3, f()); + break L; + function f() { return 3; } + } + assertEquals(2, f()); +})(); + +(function executionOrder() { + function getOuter() { + return f; + } + assertEquals('undefined', typeof getOuter()); + + { + assertEquals('function', typeof f); + assertEquals('undefined', typeof getOuter()); + function f () {} + assertEquals('function', typeof f); + assertEquals('function', typeof getOuter()); + } + + assertEquals('function', typeof getOuter()); +})(); + +(function reassignBindings() { + function getOuter() { + return f; + } + assertEquals('undefined', typeof getOuter()); + + { + assertEquals('function', typeof f); + assertEquals('undefined', typeof getOuter()); + f = 1; + assertEquals('number', typeof f); + assertEquals('undefined', typeof getOuter()); + function f () {} + assertEquals('number', typeof f); + assertEquals('number', typeof getOuter()); + f = ''; + assertEquals('string', typeof f); + assertEquals('number', typeof getOuter()); + } + + assertEquals('number', typeof getOuter()); +})(); + +// Test that shadowing arguments is fine +(function shadowArguments(x) { + assertArrayEquals([1], arguments); + { + assertEquals('function', typeof arguments); + function arguments() {} + assertEquals('function', typeof arguments); + } + assertEquals('function', typeof arguments); +})(1); + + +// Don't shadow simple parameter +(function shadowingParameterDoesntBind(x) { + assertEquals(1, x); + { + function x() {} + } + assertEquals(1, x); +})(1); + +// Don't shadow complex parameter +(function shadowingDefaultParameterDoesntBind(x = 0) { + assertEquals(1, x); + { + function x() {} + } + assertEquals(1, x); +})(1); + +// Don't shadow nested complex parameter +(function shadowingNestedParameterDoesntBind([[x]]) { + assertEquals(1, x); + { + function x() {} + } + assertEquals(1, x); +})([[1]]); + +// Don't shadow rest parameter +(function shadowingRestParameterDoesntBind(...x) { + assertArrayEquals([1], x); + { + function x() {} + } + assertArrayEquals([1], x); +})(1); + +// Don't shadow complex rest parameter +(function shadowingComplexRestParameterDoesntBind(...[x]) { + assertArrayEquals(1, x); + { + function x() {} + } + assertArrayEquals(1, x); +})(1); + +// Previous tests with a var declaration thrown in. +// Don't shadow simple parameter +(function shadowingVarParameterDoesntBind(x) { + var x; + assertEquals(1, x); + { + function x() {} + } + assertEquals(1, x); +})(1); + +// Don't shadow complex parameter +(function shadowingVarDefaultParameterDoesntBind(x = 0) { + var x; + assertEquals(1, x); + { + function x() {} + } + assertEquals(1, x); +})(1); + +// Don't shadow nested complex parameter +(function shadowingVarNestedParameterDoesntBind([[x]]) { + var x; + assertEquals(1, x); + { + function x() {} + } + assertEquals(1, x); +})([[1]]); + +// Don't shadow rest parameter +(function shadowingVarRestParameterDoesntBind(...x) { + var x; + assertArrayEquals([1], x); + { + function x() {} + } + assertArrayEquals([1], x); +})(1); + +// Don't shadow complex rest parameter +(function shadowingVarComplexRestParameterDoesntBind(...[x]) { + var x; + assertArrayEquals(1, x); + { + function x() {} + } + assertArrayEquals(1, x); +})(1); + + +// Hoisting is not affected by other simple parameters +(function irrelevantParameterBinds(y, z) { + assertEquals(undefined, x); + { + function x() {} + } + assertEquals('function', typeof x); +})(1); + +// Hoisting is not affected by other complex parameters +(function irrelevantComplexParameterBinds([y] = [], z) { + assertEquals(undefined, x); + { + function x() {} + } + assertEquals('function', typeof x); +})(); + +// Hoisting is not affected by rest parameters +(function irrelevantRestParameterBinds(y, ...z) { + assertEquals(undefined, x); + { + function x() {} + } + assertEquals('function', typeof x); +})(); + +// Hoisting is not affected by complex rest parameters +(function irrelevantRestParameterBinds(y, ...[z]) { + assertEquals(undefined, x); + { + function x() {} + } + assertEquals('function', typeof x); +})(); + + +// Test that shadowing function name is fine +{ + let called = false; + (function shadowFunctionName() { + if (called) assertUnreachable(); + called = true; + { + function shadowFunctionName() { + return 0; + } + assertEquals(0, shadowFunctionName()); + } + assertEquals(0, shadowFunctionName()); + })(); +} + +{ + let called = false; + (function shadowFunctionNameWithComplexParameter(...r) { + if (called) assertUnreachable(); + called = true; + { + function shadowFunctionNameWithComplexParameter() { + return 0; + } + assertEquals(0, shadowFunctionNameWithComplexParameter()); + } + assertEquals(0, shadowFunctionNameWithComplexParameter()); + })(); +} + +(function shadowOuterVariable() { + { + let f = 0; + (function () { + assertEquals(undefined, f); + { + assertEquals(1, f()); + function f() { return 1; } + assertEquals(1, f()); + } + assertEquals(1, f()); + })(); + assertEquals(0, f); + } +})(); + +(function notInDefaultScope() { + var y = 1; + (function innerNotInDefaultScope(x = y) { + assertEquals('undefined', typeof y); + { + function y() {} + } + assertEquals('function', typeof y); + assertEquals(1, x); + })(); +})(); + +(function noHoistingThroughNestedLexical() { + { + let f = 2; + { + let y = 3; + function f() { + y = 2; + } + f(); + assertEquals(2, y); + } + assertEquals(2, f); + } + assertThrows(()=>f, ReferenceError); +})(); + +// Only the first function is hoisted; the second is blocked by the first. +// Contrast overridingLocalFunction, in which the outer function declaration +// is not lexical and so the inner declaration is hoisted. +(function noHoistingThroughNestedFunctions() { + assertEquals(undefined, f); // Also checks that the var-binding exists + + { + assertEquals(4, f()); + + function f() { + return 4; + } + + { + assertEquals(5, f()); + function f() { + return 5; + } + assertEquals(5, f()); + } + + assertEquals(4, f()); + } + + assertEquals(4, f()); +})(); + +// B.3.5 interacts with B.3.3 to allow this. +(function hoistingThroughSimpleCatch() { + assertEquals(undefined, f); + + try { + throw 0; + } catch (f) { + { + assertEquals(4, f()); + + function f() { + return 4; + } + + assertEquals(4, f()); + } + + assertEquals(0, f); + } + + assertEquals(4, f()); +})(); + +(function noHoistingThroughComplexCatch() { + try { + throw 0; + } catch ({f}) { + { + assertEquals(4, f()); + + function f() { + return 4; + } + + assertEquals(4, f()); + } + } + + assertThrows(()=>f, ReferenceError); +})(); + +(function hoistingThroughWith() { + with ({f: 0}) { + assertEquals(0, f); + + { + assertEquals(4, f()); + + function f() { + return 4; + } + + assertEquals(4, f()); + } + + assertEquals(0, f); + } + + assertEquals(4, f()); +})(); + +// Test that hoisting from blocks does happen in global scope +function globalHoisted() { return 0; } +{ + function globalHoisted() { return 1; } +} +assertEquals(1, globalHoisted()); + +// Also happens when not previously defined +assertEquals(undefined, globalUndefinedHoisted); +{ + function globalUndefinedHoisted() { return 1; } +} +assertEquals(1, globalUndefinedHoisted()); +var globalUndefinedHoistedDescriptor = + Object.getOwnPropertyDescriptor(this, "globalUndefinedHoisted"); +assertFalse(globalUndefinedHoistedDescriptor.configurable); +assertTrue(globalUndefinedHoistedDescriptor.writable); +assertTrue(globalUndefinedHoistedDescriptor.enumerable); +assertEquals(1, globalUndefinedHoistedDescriptor.value()); + +// When a function property is hoisted, it should be +// made enumerable. +// BUG(v8:4451) +Object.defineProperty(this, "globalNonEnumerable", { + value: false, + configurable: true, + writable: true, + enumerable: false +}); +eval("{function globalNonEnumerable() { return 1; }}"); +var globalNonEnumerableDescriptor + = Object.getOwnPropertyDescriptor(this, "globalNonEnumerable"); +// BUG(v8:4451): Should be made non-configurable +assertTrue(globalNonEnumerableDescriptor.configurable); +assertTrue(globalNonEnumerableDescriptor.writable); +// BUG(v8:4451): Should be made enumerable +assertFalse(globalNonEnumerableDescriptor.enumerable); +assertEquals(1, globalNonEnumerableDescriptor.value()); + +// When a function property is hoisted, it should be overwritten and +// made writable and overwritten, even if the property was non-writable. +Object.defineProperty(this, "globalNonWritable", { + value: false, + configurable: true, + writable: false, + enumerable: true +}); +eval("{function globalNonWritable() { return 1; }}"); +var globalNonWritableDescriptor + = Object.getOwnPropertyDescriptor(this, "globalNonWritable"); +// BUG(v8:4451): Should be made non-configurable +assertTrue(globalNonWritableDescriptor.configurable); +// BUG(v8:4451): Should be made writable +assertFalse(globalNonWritableDescriptor.writable); +assertFalse(globalNonEnumerableDescriptor.enumerable); +// BUG(v8:4451): Should be overwritten +assertEquals(false, globalNonWritableDescriptor.value); + +// Test that hoisting from blocks does happen in an eval +eval(` + function evalHoisted() { return 0; } + { + function evalHoisted() { return 1; } + } + assertEquals(1, evalHoisted()); +`); + +// Test that hoisting from blocks happens from eval in a function +!function() { + eval(` + function evalInFunctionHoisted() { return 0; } + { + function evalInFunctionHoisted() { return 1; } + } + assertEquals(1, evalInFunctionHoisted()); + `); +}(); + +(function evalHoistingThroughSimpleCatch() { + try { + throw 0; + } catch (f) { + eval(`{ function f() { + return 4; + } }`); + + assertEquals(0, f); + } + + assertEquals(4, f()); +})(); + +(function evalHoistingThroughWith() { + with ({f: 0}) { + eval(`{ function f() { + return 4; + } }`); + + assertEquals(0, f); + } + + assertEquals(4, f()); +})(); + +let dontHoistGlobal; +{ function dontHoistGlobal() {} } +assertEquals(undefined, dontHoistGlobal); + +let dontHoistEval; +var throws = false; +try { + eval("{ function dontHoistEval() {} }"); +} catch (e) { + throws = true; +} +assertFalse(throws); + +// When the global object is frozen, silently don't hoist +// Currently this actually throws BUG(v8:4452) +Object.freeze(this); +{ + let throws = false; + try { + eval('{ function hoistWhenFrozen() {} }'); + } catch (e) { + throws = true; + } + assertFalse(this.hasOwnProperty("hoistWhenFrozen")); + assertThrows(() => hoistWhenFrozen, ReferenceError); + // Should be assertFalse BUG(v8:4452) + assertTrue(throws); +} diff --git a/implementation-contributed/v8/mjsunit/es6/destructuring-assignment.js b/implementation-contributed/v8/mjsunit/es6/destructuring-assignment.js index dee7a0b16d..7f61e023fc 100644 --- a/implementation-contributed/v8/mjsunit/es6/destructuring-assignment.js +++ b/implementation-contributed/v8/mjsunit/es6/destructuring-assignment.js @@ -574,3 +574,58 @@ assertEquals(oz, [1, 2, 3, 4, 5]); assertEquals(1, ext("let x; ({x} = { x: super() })").x); assertEquals(1, ext("let x, y; ({ x: y } = { x } = { x: super() })").x); })(); + +(function testInvalidReturn() { + function* g() { yield 1; } + + let executed_x_setter; + let executed_return; + var a = { + set x(val) { + executed_x_setter = true; + throw 3; + } + }; + + // The exception from the execution of g().return() should be suppressed by + // the setter error. + executed_x_setter = false; + executed_return = false; + g.prototype.return = function() { + executed_return = true; + throw 4; + }; + assertThrowsEquals("[a.x] = g()", 3); + assertTrue(executed_x_setter); + assertTrue(executed_return); + + // The exception from g().return() not returning an object should be + // suppressed by the setter error. + executed_x_setter = false; + executed_return = false; + g.prototype.return = function() { + assertTrue(executed_return); + return null; + }; + assertThrowsEquals("[a.x] = g()", 3); + assertTrue(executed_x_setter); + assertTrue(executed_return); + + // The TypeError from g().return not being a method should suppress the setter + // error. + executed_x_setter = false; + g.prototype.return = "not a method"; + assertThrows("[a.x] = g()", TypeError); + assertTrue(executed_x_setter); + + // The exception from the access of g().return should suppress the setter + // error. + executed_x_setter = false; + Object.setPrototypeOf(g.prototype, { + get return() { + throw 4; + } + }); + assertThrowsEquals("[a.x] = g()", 4); + assertTrue(executed_x_setter); +}) diff --git a/implementation-contributed/v8/mjsunit/es6/unscopables.js b/implementation-contributed/v8/mjsunit/es6/unscopables.js index e69de29bb2..d60abc4b4e 100644 --- a/implementation-contributed/v8/mjsunit/es6/unscopables.js +++ b/implementation-contributed/v8/mjsunit/es6/unscopables.js @@ -0,0 +1,739 @@ +// 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. + +var global = this; +var globalProto = Object.getPrototypeOf(global); + +// Number of objects being tested. There is an assert ensuring this is correct. +var objectCount = 21; + + +function runTest(f) { + function restore(object, oldProto) { + delete object[Symbol.unscopables]; + delete object.x; + delete object.x_; + delete object.y; + delete object.z; + Object.setPrototypeOf(object, oldProto); + } + + function getObject(i) { + var objects = [ + {}, + [], + function() {}, + function() { + return arguments; + }(), + function() { + 'use strict'; + return arguments; + }(), + Object(1), + Object(true), + Object('bla'), + new Date, + new RegExp, + new Set, + new Map, + new WeakMap, + new WeakSet, + new ArrayBuffer(10), + new Int32Array(5), + Object, + Function, + Date, + RegExp, + global + ]; + + assertEquals(objectCount, objects.length); + return objects[i]; + } + + // Tests depends on this not being there to start with. + delete Array.prototype[Symbol.unscopables]; + + if (f.length === 1) { + for (var i = 0; i < objectCount; i++) { + var object = getObject(i); + var oldObjectProto = Object.getPrototypeOf(object); + f(object); + restore(object, oldObjectProto); + } + } else { + for (var i = 0; i < objectCount; i++) { + for (var j = 0; j < objectCount; j++) { + var object = getObject(i); + var proto = getObject(j); + if (object === proto) { + continue; + } + var oldObjectProto = Object.getPrototypeOf(object); + var oldProtoProto = Object.getPrototypeOf(proto); + f(object, proto); + restore(object, oldObjectProto); + restore(proto, oldProtoProto); + } + } + } +} + +// Test array first, since other tests are changing +// Array.prototype[Symbol.unscopables]. +function TestArrayPrototypeUnscopables() { + var descr = Object.getOwnPropertyDescriptor(Array.prototype, + Symbol.unscopables); + assertFalse(descr.enumerable); + assertFalse(descr.writable); + assertTrue(descr.configurable); + assertEquals(null, Object.getPrototypeOf(descr.value)); + + var copyWithin = 'local copyWithin'; + var entries = 'local entries'; + var fill = 'local fill'; + var find = 'local find'; + var findIndex = 'local findIndex'; + var flat = 'local flat'; + var flatMap = 'local flatMap'; + var keys = 'local keys'; + var includes = 'local includes'; + var values = 'local values'; + + var array = []; + array.toString = 42; + + with (array) { + assertEquals('local copyWithin', copyWithin); + assertEquals('local entries', entries); + assertEquals('local fill', fill); + assertEquals('local find', find); + assertEquals('local findIndex', findIndex); + assertEquals('local flat', flat); + assertEquals('local flatMap', flatMap); + assertEquals('local includes', includes); + assertEquals('local keys', keys); + assertEquals('local values', values); + assertEquals(42, toString); + } +} +TestArrayPrototypeUnscopables(); + + + +function TestBasics(object) { + var x = 1; + var y = 2; + var z = 3; + object.x = 4; + object.y = 5; + + with (object) { + assertEquals(4, x); + assertEquals(5, y); + assertEquals(3, z); + } + + var truthyValues = [true, 1, 'x', {}, Symbol()]; + for (var truthyValue of truthyValues) { + object[Symbol.unscopables] = {x: truthyValue}; + with (object) { + assertEquals(1, x); + assertEquals(5, y); + assertEquals(3, z); + } + } + + var falsyValues = [false, 0, -0, NaN, '', null, undefined]; + for (var falsyValue of falsyValues) { + object[Symbol.unscopables] = {x: falsyValue, y: true}; + with (object) { + assertEquals(4, x); + assertEquals(2, y); + assertEquals(3, z); + } + } + + for (var xFalsy of falsyValues) { + for (var yFalsy of falsyValues) { + object[Symbol.unscopables] = {x: xFalsy, y: yFalsy}; + with (object) { + assertEquals(4, x); + assertEquals(5, y); + assertEquals(3, z); + } + } + } +} +runTest(TestBasics); + + +function TestUnscopableChain(object) { + var x = 1; + object.x = 2; + + with (object) { + assertEquals(2, x); + } + + object[Symbol.unscopables] = { + __proto__: {x: true} + }; + with (object) { + assertEquals(1, x); + } + + object[Symbol.unscopables] = { + __proto__: {x: undefined} + }; + with (object) { + assertEquals(2, x); + } +} +runTest(TestUnscopableChain); + + +function TestBasicsSet(object) { + var x = 1; + object.x = 2; + + with (object) { + assertEquals(2, x); + } + + object[Symbol.unscopables] = {x: true}; + with (object) { + assertEquals(1, x); + x = 3; + assertEquals(3, x); + } + + assertEquals(3, x); + assertEquals(2, object.x); +} +runTest(TestBasicsSet); + + +function TestOnProto(object, proto) { + var x = 1; + var y = 2; + var z = 3; + proto.x = 4; + + Object.setPrototypeOf(object, proto); + object.y = 5; + + with (object) { + assertEquals(4, x); + assertEquals(5, y); + assertEquals(3, z); + } + + proto[Symbol.unscopables] = {x: true}; + with (object) { + assertEquals(1, x); + assertEquals(5, y); + assertEquals(3, z); + } + + object[Symbol.unscopables] = {y: true}; + with (object) { + assertEquals(4, x); + assertEquals(2, y); + assertEquals(3, z); + } + + proto[Symbol.unscopables] = {y: true}; + object[Symbol.unscopables] = {x: true}; + with (object) { + assertEquals(1, x); + assertEquals(5, y); + assertEquals(3, z); + } + + proto[Symbol.unscopables] = {y: true}; + object[Symbol.unscopables] = {x: true, y: undefined}; + with (object) { + assertEquals(1, x); + assertEquals(5, y); + assertEquals(3, z); + } +} +runTest(TestOnProto); + + +function TestSetBlockedOnProto(object, proto) { + var x = 1; + object.x = 2; + + with (object) { + assertEquals(2, x); + } + + Object.setPrototypeOf(object, proto); + proto[Symbol.unscopables] = {x: true}; + with (object) { + assertEquals(1, x); + x = 3; + assertEquals(3, x); + } + + assertEquals(3, x); + assertEquals(2, object.x); +} +runTest(TestSetBlockedOnProto); + + +function TestNonObject(object) { + var x = 1; + var y = 2; + object.x = 3; + object.y = 4; + + object[Symbol.unscopables] = 'xy'; + with (object) { + assertEquals(3, x); + assertEquals(4, y); + } + + object[Symbol.unscopables] = null; + with (object) { + assertEquals(3, x); + assertEquals(4, y); + } +} +runTest(TestNonObject); + + +function TestChangeDuringWith(object) { + var x = 1; + var y = 2; + object.x = 3; + object.y = 4; + + with (object) { + assertEquals(3, x); + assertEquals(4, y); + object[Symbol.unscopables] = {x: true}; + assertEquals(1, x); + assertEquals(4, y); + } +} +runTest(TestChangeDuringWith); + + +function TestChangeDuringWithWithPossibleOptimization(object) { + var x = 1; + object.x = 2; + with (object) { + for (var i = 0; i < 1000; i++) { + if (i === 500) object[Symbol.unscopables] = {x: true}; + assertEquals(i < 500 ? 2: 1, x); + } + } +} +TestChangeDuringWithWithPossibleOptimization({}); + + +function TestChangeDuringWithWithPossibleOptimization2(object) { + var x = 1; + object.x = 2; + object[Symbol.unscopables] = {x: true}; + with (object) { + for (var i = 0; i < 1000; i++) { + if (i === 500) delete object[Symbol.unscopables]; + assertEquals(i < 500 ? 1 : 2, x); + } + } +} +TestChangeDuringWithWithPossibleOptimization2({}); + + +function TestChangeDuringWithWithPossibleOptimization3(object) { + var x = 1; + object.x = 2; + object[Symbol.unscopables] = {}; + with (object) { + for (var i = 0; i < 1000; i++) { + if (i === 500) object[Symbol.unscopables].x = true; + assertEquals(i < 500 ? 2 : 1, x); + } + } +} +TestChangeDuringWithWithPossibleOptimization3({}); + + +function TestChangeDuringWithWithPossibleOptimization4(object) { + var x = 1; + object.x = 2; + object[Symbol.unscopables] = {x: true}; + with (object) { + for (var i = 0; i < 1000; i++) { + if (i === 500) delete object[Symbol.unscopables].x; + assertEquals(i < 500 ? 1 : 2, x); + } + } +} +TestChangeDuringWithWithPossibleOptimization4({}); + + +function TestChangeDuringWithWithPossibleOptimization4(object) { + var x = 1; + object.x = 2; + object[Symbol.unscopables] = {x: true}; + with (object) { + for (var i = 0; i < 1000; i++) { + if (i === 500) object[Symbol.unscopables].x = undefined; + assertEquals(i < 500 ? 1 : 2, x); + } + } +} +TestChangeDuringWithWithPossibleOptimization4({}); + + +function TestAccessorReceiver(object, proto) { + var x = 'local'; + + Object.defineProperty(proto, 'x', { + get: function() { + assertEquals(object, this); + return this.x_; + }, + configurable: true + }); + proto.x_ = 'proto'; + + Object.setPrototypeOf(object, proto); + proto.x_ = 'object'; + + with (object) { + assertEquals('object', x); + } +} +runTest(TestAccessorReceiver); + + +function TestUnscopablesGetter(object) { + // This test gets really messy when object is the global since the assert + // functions are properties on the global object and the call count gets + // completely different. + if (object === global) return; + + var x = 'local'; + object.x = 'object'; + + var callCount = 0; + Object.defineProperty(object, Symbol.unscopables, { + get: function() { + callCount++; + return {}; + }, + configurable: true + }); + with (object) { + assertEquals('object', x); + } + // Once for HasBinding + assertEquals(1, callCount); + + callCount = 0; + Object.defineProperty(object, Symbol.unscopables, { + get: function() { + callCount++; + return {x: true}; + }, + configurable: true + }); + with (object) { + assertEquals('local', x); + } + // Once for HasBinding + assertEquals(1, callCount); + + callCount = 0; + Object.defineProperty(object, Symbol.unscopables, { + get: function() { + callCount++; + return callCount == 1 ? {} : {x: true}; + }, + configurable: true + }); + with (object) { + x = 1; + } + // Once for HasBinding + assertEquals(1, callCount); + assertEquals(1, object.x); + assertEquals('local', x); + with (object) { + x = 2; + } + // One more HasBinding. + assertEquals(2, callCount); + assertEquals(1, object.x); + assertEquals(2, x); +} +runTest(TestUnscopablesGetter); + + +var global = this; +function TestUnscopablesGetter2() { + var x = 'local'; + + var globalProto = Object.getPrototypeOf(global); + var protos = [{}, [], function() {}, global]; + var objects = [{}, [], function() {}]; + + protos.forEach(function(proto) { + objects.forEach(function(object) { + Object.defineProperty(proto, 'x', { + get: function() { + assertEquals(object, this); + return 'proto'; + }, + configurable: true + }); + + object.__proto__ = proto; + Object.defineProperty(object, 'x', { + get: function() { + assertEquals(object, this); + return 'object'; + }, + configurable: true + }); + + with (object) { + assertEquals('object', x); + } + + object[Symbol.unscopables] = {x: true}; + with (object) { + assertEquals('local', x); + } + + delete proto[Symbol.unscopables]; + delete object[Symbol.unscopables]; + }); + }); + + delete global.x; + Object.setPrototypeOf(global, globalProto); +} +TestUnscopablesGetter2(); + + +function TestSetterOnBlacklisted(object, proto) { + var x = 'local'; + Object.defineProperty(proto, 'x', { + set: function(x) { + assertUnreachable(); + }, + get: function() { + return 'proto'; + }, + configurable: true + }); + Object.setPrototypeOf(object, proto); + Object.defineProperty(object, 'x', { + get: function() { + return this.x_; + }, + set: function(x) { + this.x_ = x; + }, + configurable: true + }); + object.x_ = 1; + + with (object) { + x = 2; + assertEquals(2, x); + } + + assertEquals(2, object.x); + + object[Symbol.unscopables] = {x: true}; + + with (object) { + x = 3; + assertEquals(3, x); + } + + assertEquals(2, object.x); +} +runTest(TestSetterOnBlacklisted); + + +function TestObjectsAsUnscopables(object, unscopables) { + var x = 1; + object.x = 2; + + with (object) { + assertEquals(2, x); + object[Symbol.unscopables] = unscopables; + assertEquals(2, x); + } +} +runTest(TestObjectsAsUnscopables); + + +function TestAccessorOnUnscopables(object) { + var x = 1; + object.x = 2; + + var calls = 0; + var unscopables = { + get x() { + calls++; + return calls === 1 ? true : undefined; + } + }; + + with (object) { + assertEquals(2, x); + object[Symbol.unscopables] = unscopables; + assertEquals(1, x); + assertEquals(2, x); + } + assertEquals(2, calls); +} +runTest(TestAccessorOnUnscopables); + + +function TestLengthUnscopables(object, proto) { + var length = 2; + with (object) { + assertEquals(1, length); + object[Symbol.unscopables] = {length: true}; + assertEquals(2, length); + delete object[Symbol.unscopables]; + assertEquals(1, length); + } +} +TestLengthUnscopables([1], Array.prototype); +TestLengthUnscopables(function(x) {}, Function.prototype); +TestLengthUnscopables(new String('x'), String.prototype); + + +function TestFunctionNameUnscopables(object) { + var name = 'local'; + with (object) { + assertEquals('f', name); + object[Symbol.unscopables] = {name: true}; + assertEquals('local', name); + delete object[Symbol.unscopables]; + assertEquals('f', name); + } +} +TestFunctionNameUnscopables(function f() {}); + + +function TestFunctionPrototypeUnscopables() { + var prototype = 'local'; + var f = function() {}; + var g = function() {}; + Object.setPrototypeOf(f, g); + var fp = f.prototype; + var gp = g.prototype; + with (f) { + assertEquals(fp, prototype); + f[Symbol.unscopables] = {prototype: true}; + assertEquals('local', prototype); + delete f[Symbol.unscopables]; + assertEquals(fp, prototype); + } +} +TestFunctionPrototypeUnscopables(function() {}); + + +function TestFunctionArgumentsUnscopables() { + var func = function() { + var arguments = 'local'; + var args = func.arguments; + with (func) { + assertEquals(args, arguments); + func[Symbol.unscopables] = {arguments: true}; + assertEquals('local', arguments); + delete func[Symbol.unscopables]; + assertEquals(args, arguments); + } + } + func(1); +} +TestFunctionArgumentsUnscopables(); + + +function TestArgumentsLengthUnscopables() { + var func = function() { + var length = 'local'; + with (arguments) { + assertEquals(1, length); + arguments[Symbol.unscopables] = {length: true}; + assertEquals('local', length); + } + } + func(1); +} +TestArgumentsLengthUnscopables(); + + +function TestFunctionCallerUnscopables() { + var func = function() { + var caller = 'local'; + with (func) { + assertEquals(TestFunctionCallerUnscopables, caller); + func[Symbol.unscopables] = {caller: true}; + assertEquals('local', caller); + delete func[Symbol.unscopables]; + assertEquals(TestFunctionCallerUnscopables, caller); + } + } + func(1); +} +TestFunctionCallerUnscopables(); + + +function TestGetUnscopablesGetterThrows() { + var object = { + get x() { + assertUnreachable(); + } + }; + function CustomError() {} + Object.defineProperty(object, Symbol.unscopables, { + get: function() { + throw new CustomError(); + } + }); + assertThrows(function() { + with (object) { + x; + } + }, CustomError); +} +TestGetUnscopablesGetterThrows(); + + +function TestGetUnscopablesGetterThrows2() { + var object = { + get x() { + assertUnreachable(); + } + }; + function CustomError() {} + + object[Symbol.unscopables] = { + get x() { + throw new CustomError(); + } + }; + assertThrows(function() { + with (object) { + x; + } + }, CustomError); +} +TestGetUnscopablesGetterThrows(); diff --git a/implementation-contributed/v8/mjsunit/harmony/hashbang-eval.js b/implementation-contributed/v8/mjsunit/harmony/hashbang-eval.js new file mode 100644 index 0000000000..c5040f7bee --- /dev/null +++ b/implementation-contributed/v8/mjsunit/harmony/hashbang-eval.js @@ -0,0 +1,11 @@ +// 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-hashbang + +// Hashbang syntax is not allowed in eval. +assertThrows("#!", SyntaxError); +assertThrows("#!\n", SyntaxError); +assertThrows("#!---IGNORED---", SyntaxError); +assertThrows("#!---IGNORED---\n", SyntaxError); diff --git a/implementation-contributed/v8/mjsunit/harmony/private-fields-static.js b/implementation-contributed/v8/mjsunit/harmony/private-fields-static.js new file mode 100644 index 0000000000..e4019cc32e --- /dev/null +++ b/implementation-contributed/v8/mjsunit/harmony/private-fields-static.js @@ -0,0 +1,356 @@ +// 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-private-fields --allow-natives-syntax + + +"use strict"; + +{ + class C { + static #a; + static getA() { return this.#a; } + } + + assertEquals(undefined, C.a); + assertEquals(undefined, C.getA()); + + let c = new C; + assertEquals(undefined, c.a); +} + +{ + class C { + static #a = 1; + static getA() { return this.#a; } + } + + assertEquals(undefined, C.a); + assertEquals(1, C.getA()); + + let c = new C; + assertEquals(undefined, c.a); +} + +{ + class C { + static #a = 1; + static #b = this.#a; + static getB() { return this.#b; } + } + + assertEquals(1, C.getB()); + + let c = new C; + assertEquals(undefined, c.getB); +} + +{ + class C { + static #a = 1; + static getA() { return this.#a; } + constructor() { + assertThrows(() => this.#a, TypeError); + C.#a = 2; + } + } + + assertEquals(1, C.getA()); + + let c = new C; + assertThrows(() => C.prototype.getA.call(c)); + assertEquals(2, C.getA()); +} + +{ + class C { + static #a = this; + static #b = () => this; + static getA() { return this.#a; } + static getB() { return this.#b; } + } + + assertSame(C, C.getA()); + assertSame(C, C.getB()()); +} + +{ + class C { + static #a = this; + static #b = function() { return this; }; + static getA() { return this.#a; } + static getB() { return this.#b; } + } + + assertSame(C, C.getA()); + assertSame(C, C.getB().call(C)); + assertSame(undefined, C.getB()()); +} + + +{ + class C { + static #a = function() { return 1 }; + static getA() {return this.#a;} + } + + assertEquals('#a', C.getA().name); +} + +{ + let d = function() { return new.target; } + class C { + static #c = d; + static getC() { return this.#c; } + } + + assertEquals(undefined, C.getC()()); + assertSame(new d, new (C.getC())); +} + +{ + class C { + static #a = 1; + static getA(instance) { return instance.#a; } + } + + class B { } + + assertEquals(undefined, C.a); + assertEquals(1, C.getA(C)); + assertThrows(() => C.getA(B), TypeError); +} + +{ + class A { + static #a = 1; + static getA() { return this.#a; } + } + + class B extends A {} + assertThrows(() => B.getA(), TypeError); +} + +{ + class A { + static #a = 1; + static getA() { return A.#a; } + } + + class B extends A {} + assertSame(1, B.getA()); +} + +{ + let prototypeLookup = false; + class A { + static set a(val) { + prototypeLookup = true; + } + + static get a() { return undefined; } + } + + class C extends A { + static #a = 1; + static getA() { return this.#a; } + } + + assertEquals(1, C.getA()); + assertEquals(false, prototypeLookup); +} + +{ + class A { + static a = 1; + } + + class B extends A { + static #b = this.a; + static getB() { return this.#b; } + } + + assertEquals(1, B.getB()); +} + +{ + class A { + static #a = 1; + static getA() { return this.#a; } + } + + class B extends A { + static getA() { return super.getA(); } + } + + assertThrows(() => B.getA(), TypeError); +} + +{ + class A { + static #a = 1; + static getA() { return this.#a;} + } + + class B extends A { + static #a = 2; + static get_A() { return this.#a;} + } + + assertEquals(1, A.getA()); + assertThrows(() => B.getA(), TypeError); + assertEquals(2, B.get_A()); +} + +{ + let foo = undefined; + class A { + static #a = (function() { foo = 1; })(); + } + + assertEquals(1, foo); +} + +{ + let foo = undefined; + class A extends class {} { + static #a = (function() { foo = 1; })(); + } + + assertEquals(1, foo); +} + +{ + function makeClass() { + return class { + static #a; + static setA(val) { this.#a = val; } + static getA() { return this.#a; } + } + } + + let classA = makeClass(); + let classB = makeClass(); + + assertEquals(undefined, classA.getA()); + assertEquals(undefined, classB.getA()); + + classA.setA(3); + assertEquals(3, classA.getA()); + assertEquals(undefined, classB.getA()); + + classB.setA(5); + assertEquals(3, classA.getA()); + assertEquals(5, classB.getA()); + + assertThrows(() => classA.getA.call(classB), TypeError); + assertThrows(() => classB.getA.call(classA), TypeError); +} + +{ + let value = undefined; + + new class { + static #a = 1; + static getA() { return this.#a; } + + constructor() { + new class C { + static #a = 2; + constructor() { + value = C.#a; + } + } + } + } + + assertEquals(2, value); +} + +{ + class A { + static #a = 1; + static b = class { + static getA() { return this.#a; } + static get_A(val) { return val.#a; } + } + } + + assertEquals(1, A.b.getA.call(A)); + assertEquals(1, A.b.get_A(A)); +} + +{ + assertThrows(() => class { static b = this.#a; static #a = 1 }, TypeError); +} + +{ + let symbol = Symbol(); + + class C { + static #a = 1; + static [symbol] = 1; + static getA() { return this.#a; } + static setA(val) { this.#a = val; } + } + + var p = new Proxy(C, { + get: function(target, name) { + if (typeof(arg) === 'symbol') { + assertFalse(%SymbolIsPrivate(name)); + } + return target[name]; + } + }); + + assertThrows(() => p.getA(), TypeError); + assertThrows(() => p.setA(1), TypeError); + assertEquals(1, p[symbol]); +} + +{ + class C { + static #b = Object.freeze(this); + static getA() { return this.#a; } + static #a = 1; + } + + assertEquals(1, C.getA()); +} + +{ + class C { + static #a = 1; + static getA() { return eval('this.#a'); } + } + + assertEquals(1, C.getA()); +} + +{ + var C; + eval('C = class { static #a = 1; static getA() { return eval(\'this.#a\'); }}'); + + assertEquals(1, C.getA()); +} + +{ + class C { + static #a = 1; + static getA() { return this.#a; } + static setA() { eval('this.#a = 4'); } + } + + assertEquals(1, C.getA()); + C.setA(); + assertEquals(4, C.getA()); +} + +{ + class C { + static getA() { return eval('this.#a'); } + } + + assertThrows(() => C.getA(), SyntaxError); +} diff --git a/implementation-contributed/v8/mjsunit/mjsunit.status b/implementation-contributed/v8/mjsunit/mjsunit.status index 90ea2c7cb2..884c7cca92 100644 --- a/implementation-contributed/v8/mjsunit/mjsunit.status +++ b/implementation-contributed/v8/mjsunit/mjsunit.status @@ -268,6 +268,7 @@ 'regress/regress-trap-allocation-memento': [SKIP], 'regress/regress-2249': [SKIP], 'regress/regress-4121': [SKIP], + 'regress/regress-6989': [SKIP], 'compare-known-objects-slow': [SKIP], 'compiler/array-multiple-receiver-maps': [SKIP], # Tests taking too long @@ -322,7 +323,7 @@ }], # 'gc_stress == True' ############################################################################## -['lite_mode == True', { +['lite_mode', { # Skip tests not suitable for lite_mode. # TODO(8596): We cache the templates in the feedback vector. In lite mode @@ -348,7 +349,38 @@ 'spread-large-string': [SKIP], 'spread-large-array': [SKIP], -}], # 'lite_mode == True' + # TODO(v8:7777): Re-enable once wasm is supported in jitless mode. + 'regress/wasm/*': [SKIP], + 'tools/compiler-trace-flags': [SKIP], + 'wasm/*': [SKIP], + + # Other tests that use asm / wasm / optimized code. + 'asm/asm-heap': [SKIP], + 'asm/asm-validation': [SKIP], + 'asm/call-stdlib': [SKIP], + 'asm/call-annotation': [SKIP], + 'asm/global-imports': [SKIP], + 'asm/regress-913822': [SKIP], + 'asm/return-types': [SKIP], + 'regress/regress-599719': [SKIP], + 'regress/regress-6196': [SKIP], + 'regress/regress-6700': [SKIP], + 'regress/regress-6838-2': [SKIP], + 'regress/regress-6838-3': [SKIP], + + # Timeouts in lite / jitless mode. + 'asm/embenchen/*': [SKIP], + + # Tests that generate code at runtime. + 'code-comments': [SKIP], + 'regress/regress-617526': [SKIP], + 'regress/regress-7893': [SKIP], + 'regress/regress-8377': [SKIP], + 'regress/regress-863810': [SKIP], + 'regress/regress-crbug-721835': [SKIP], + 'regress/regress-crbug-759327': [SKIP], + 'regress/regress-crbug-898974': [SKIP], +}], # 'lite_mode' ############################################################################## ['byteorder == big', { @@ -964,4 +996,11 @@ # crbug.com/v8/7741 'wasm/bigint': [SKIP], }], # arch in [arm, android_arm, android_ia32, ia32, ppc, s390, s390x, mipsel, mips] + +############################################################################## +['arch not in [x64, arm, arm64] or system != linux', { + # Unwinding info writer is only supported on x64, arm, and arm64 Linux + 'regress/regress-913844': [SKIP], +}], + ] diff --git a/implementation-contributed/v8/mjsunit/object-seal.js b/implementation-contributed/v8/mjsunit/object-seal.js index e69de29bb2..265e50abc3 100644 --- a/implementation-contributed/v8/mjsunit/object-seal.js +++ b/implementation-contributed/v8/mjsunit/object-seal.js @@ -0,0 +1,395 @@ +// 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. + +// Tests the Object.seal and Object.isSealed methods - ES 19.1.2.17 and +// ES 19.1.2.13 + +// Flags: --allow-natives-syntax --opt --noalways-opt + +// Test that we return obj if non-object is passed as argument +var non_objects = new Array(undefined, null, 1, -1, 0, 42.43, Symbol("test")); +for (var key in non_objects) { + assertSame(non_objects[key], Object.seal(non_objects[key])); +} + +// Test that isFrozen always returns true for non-objects +for (var key in non_objects) { + assertTrue(Object.isSealed(non_objects[key])); +} + +// Test normal data properties. +var obj = { x: 42, z: 'foobar' }; +var desc = Object.getOwnPropertyDescriptor(obj, 'x'); +assertTrue(desc.writable); +assertTrue(desc.configurable); +assertEquals(42, desc.value); + +desc = Object.getOwnPropertyDescriptor(obj, 'z'); +assertTrue(desc.writable); +assertTrue(desc.configurable); +assertEquals('foobar', desc.value); + +assertTrue(Object.isExtensible(obj)); +assertFalse(Object.isSealed(obj)); + +Object.seal(obj); + +// Make sure we are no longer extensible. +assertFalse(Object.isExtensible(obj)); +assertTrue(Object.isSealed(obj)); + +// We should not be frozen, since we are still able to +// update values. +assertFalse(Object.isFrozen(obj)); + +// We should not allow new properties to be added. +obj.foo = 42; +assertEquals(obj.foo, undefined); + +desc = Object.getOwnPropertyDescriptor(obj, 'x'); +assertTrue(desc.writable); +assertFalse(desc.configurable); +assertEquals(42, desc.value); + +desc = Object.getOwnPropertyDescriptor(obj, 'z'); +assertTrue(desc.writable); +assertFalse(desc.configurable); +assertEquals("foobar", desc.value); + +// Since writable is not affected by seal we should still be able to +// update the values. +obj.x = "43"; +assertEquals("43", obj.x); + +// Test on accessors. +var obj2 = {}; +function get() { return 43; }; +function set() {}; +Object.defineProperty(obj2, 'x', { get: get, set: set, configurable: true }); + +desc = Object.getOwnPropertyDescriptor(obj2, 'x'); +assertTrue(desc.configurable); +assertEquals(undefined, desc.value); +assertEquals(set, desc.set); +assertEquals(get, desc.get); + +assertTrue(Object.isExtensible(obj2)); +assertFalse(Object.isSealed(obj2)); +Object.seal(obj2); + +// Since this is an accessor property the object is now effectively both +// sealed and frozen (accessors has no writable attribute). +assertTrue(Object.isFrozen(obj2)); +assertFalse(Object.isExtensible(obj2)); +assertTrue(Object.isSealed(obj2)); + +desc = Object.getOwnPropertyDescriptor(obj2, 'x'); +assertFalse(desc.configurable); +assertEquals(undefined, desc.value); +assertEquals(set, desc.set); +assertEquals(get, desc.get); + +obj2.foo = 42; +assertEquals(obj2.foo, undefined); + +// Test seal on arrays. +var arr = new Array(42,43); + +desc = Object.getOwnPropertyDescriptor(arr, '0'); +assertTrue(desc.configurable); +assertTrue(desc.writable); +assertEquals(42, desc.value); + +desc = Object.getOwnPropertyDescriptor(arr, '1'); +assertTrue(desc.configurable); +assertTrue(desc.writable); +assertEquals(43, desc.value); + +assertTrue(Object.isExtensible(arr)); +assertFalse(Object.isSealed(arr)); +Object.seal(arr); +assertTrue(Object.isSealed(arr)); +assertFalse(Object.isExtensible(arr)); +// Since the values in the array is still writable this object +// is not frozen. +assertFalse(Object.isFrozen(arr)); + +desc = Object.getOwnPropertyDescriptor(arr, '0'); +assertFalse(desc.configurable); +assertTrue(desc.writable); +assertEquals(42, desc.value); + +desc = Object.getOwnPropertyDescriptor(arr, '1'); +assertFalse(desc.configurable); +assertTrue(desc.writable); +assertEquals(43, desc.value); + +arr[0] = 'foo'; + +// We should be able to overwrite the existing value. +assertEquals('foo', arr[0]); + + +// Test that isSealed returns the correct value even if configurable +// has been set to false on all properties manually and the extensible +// flag has also been set to false manually. +var obj3 = { x: 42, y: 'foo' }; + +assertFalse(Object.isFrozen(obj3)); + +Object.defineProperty(obj3, 'x', {configurable: false, writable: true}); +Object.defineProperty(obj3, 'y', {configurable: false, writable: false}); +Object.preventExtensions(obj3); + +assertTrue(Object.isSealed(obj3)); + + +// Make sure that an object that has a configurable property +// is not classified as sealed. +var obj4 = {}; +Object.defineProperty(obj4, 'x', {configurable: true, writable: false}); +Object.defineProperty(obj4, 'y', {configurable: false, writable: false}); +Object.preventExtensions(obj4); + +assertFalse(Object.isSealed(obj4)); + +// Make sure that Object.seal returns the sealed object. +var obj4 = {}; +assertTrue(obj4 === Object.seal(obj4)); + +// +// Test that built-in array functions can't modify a sealed array. +// +obj = [1, 2, 3]; +var objControl = [4, 5, 6]; + +// Allow these functions to set up monomorphic calls, using custom built-ins. +var push_call = function(a) { a.push(10); return a; } +var pop_call = function(a) { return a.pop(); } +for (var i = 0; i < 3; i++) { + push_call(obj); + pop_call(obj); +} + +Object.seal(obj); +assertThrows(function() { push_call(obj); }, TypeError); +assertThrows(function() { pop_call(obj); }, TypeError); + +// But the control object is fine at these sites. +assertDoesNotThrow(function() { push_call(objControl); }); +assertDoesNotThrow(function() { pop_call(objControl); }); + +assertDoesNotThrow(function() { obj.push(); }); +assertThrows(function() { obj.push(3); }, TypeError); +assertThrows(function() { obj.pop(); }, TypeError); +assertThrows(function() { obj.shift(3); }, TypeError); +assertDoesNotThrow(function() { obj.unshift(); }); +assertThrows(function() { obj.unshift(1); }, TypeError); +assertThrows(function() { obj.splice(0, 0, 100, 101, 102); }, TypeError); +assertDoesNotThrow(function() { obj.splice(0,0); }); + +assertDoesNotThrow(function() { objControl.push(3); }); +assertDoesNotThrow(function() { objControl.pop(); }); +assertDoesNotThrow(function() { objControl.shift(3); }); +assertDoesNotThrow(function() { objControl.unshift(); }); +assertDoesNotThrow(function() { objControl.splice(0, 0, 100, 101, 102); }); + +// Verify that crankshaft still does the right thing. +obj = [1, 2, 3]; + +push_call = function(a) { a.push(1000); return a; } +// Include a call site that doesn't have a custom built-in. +var shift_call = function(a) { a.shift(1000); return a; } +for (var i = 0; i < 3; i++) { + push_call(obj); + shift_call(obj); +} + +%OptimizeFunctionOnNextCall(push_call); +%OptimizeFunctionOnNextCall(shift_call); +push_call(obj); +shift_call(obj); +assertOptimized(push_call); +assertOptimized(shift_call); +Object.seal(obj); +assertThrows(function() { push_call(obj); }, TypeError); +assertThrows(function() { shift_call(obj); }, TypeError); +assertUnoptimized(push_call); +assertUnoptimized(shift_call); +assertDoesNotThrow(function() { push_call(objControl); }); +assertDoesNotThrow(function() { shift_call(objControl); }); + +// Verify special behavior of splice on sealed objects. +obj = [1,2,3]; +Object.seal(obj); +assertDoesNotThrow(function() { obj.splice(0,1,100); }); +assertEquals(100, obj[0]); +assertDoesNotThrow(function() { obj.splice(0,2,1,2); }); +assertDoesNotThrow(function() { obj.splice(1,2,1,2); }); +// Count of items to delete is clamped by length. +assertDoesNotThrow(function() { obj.splice(1,2000,1,2); }); +assertThrows(function() { obj.splice(0,0,1); }, TypeError); +assertThrows(function() { obj.splice(1,2000,1,2,3); }, TypeError); + +// Test that the enumerable attribute is unperturbed by sealing. +obj = { x: 42, y: 'foo' }; +Object.defineProperty(obj, 'y', {enumerable: false}); +Object.seal(obj); +assertTrue(Object.isSealed(obj)); +assertFalse(Object.isFrozen(obj)); +desc = Object.getOwnPropertyDescriptor(obj, 'x'); +assertTrue(desc.enumerable); +desc = Object.getOwnPropertyDescriptor(obj, 'y'); +assertFalse(desc.enumerable); + +// Fast properties should remain fast +obj = { x: 42, y: 'foo' }; +assertTrue(%HasFastProperties(obj)); +Object.seal(obj); +assertTrue(Object.isSealed(obj)); +assertFalse(Object.isFrozen(obj)); +assertTrue(%HasFastProperties(obj)); + +// Sealed objects should share maps where possible +obj = { prop1: 1, prop2: 2 }; +obj2 = { prop1: 3, prop2: 4 }; +assertTrue(%HaveSameMap(obj, obj2)); +Object.seal(obj); +Object.seal(obj2); +assertTrue(Object.isSealed(obj)); +assertTrue(Object.isSealed(obj2)); +assertFalse(Object.isFrozen(obj)); +assertFalse(Object.isFrozen(obj2)); +assertTrue(%HaveSameMap(obj, obj2)); + +// Sealed objects should share maps even when they have elements +obj = { prop1: 1, prop2: 2, 75: 'foo' }; +obj2 = { prop1: 3, prop2: 4, 150: 'bar' }; +assertTrue(%HaveSameMap(obj, obj2)); +Object.seal(obj); +Object.seal(obj2); +assertTrue(Object.isSealed(obj)); +assertTrue(Object.isSealed(obj2)); +assertFalse(Object.isFrozen(obj)); +assertFalse(Object.isFrozen(obj)); +assertTrue(%HaveSameMap(obj, obj2)); + +// Setting elements after sealing should not be allowed +obj = { prop: 'thing' }; +Object.seal(obj); +assertTrue(Object.isSealed(obj)); +assertFalse(Object.isFrozen(obj)); +obj[0] = 'hello'; +assertFalse(obj.hasOwnProperty(0)); + +// Sealing an object in dictionary mode should work +// Also testing that getter/setter properties work after sealing +obj = { }; +for (var i = 0; i < 100; ++i) { + obj['x' + i] = i; +} +var accessorDidRun = false; +Object.defineProperty(obj, 'accessor', { + get: function() { return 42 }, + set: function() { accessorDidRun = true }, + configurable: true, + enumerable: true +}); + +assertFalse(%HasFastProperties(obj)); +Object.seal(obj); +assertFalse(%HasFastProperties(obj)); +assertTrue(Object.isSealed(obj)); +assertFalse(Object.isFrozen(obj)); +assertFalse(Object.isExtensible(obj)); +for (var i = 0; i < 100; ++i) { + desc = Object.getOwnPropertyDescriptor(obj, 'x' + i); + assertFalse(desc.configurable); +} +assertEquals(42, obj.accessor); +assertFalse(accessorDidRun); +obj.accessor = 'ignored value'; +assertTrue(accessorDidRun); + +// Sealing arguments should work +var func = function(arg) { + Object.seal(arguments); + assertTrue(Object.isSealed(arguments)); +}; +func('hello', 'world'); +func('goodbye', 'world'); + +// Sealing sparse arrays +var sparseArr = [0, 1]; +sparseArr[10000] = 10000; +Object.seal(sparseArr); +assertTrue(Object.isSealed(sparseArr)); + +// Accessors on fast object should behavior properly after sealing +obj = {}; +Object.defineProperty(obj, 'accessor', { + get: function() { return 42 }, + set: function() { accessorDidRun = true }, + configurable: true, + enumerable: true +}); +assertTrue(%HasFastProperties(obj)); +Object.seal(obj); +assertTrue(Object.isSealed(obj)); +assertTrue(%HasFastProperties(obj)); +assertEquals(42, obj.accessor); +accessorDidRun = false; +obj.accessor = 'ignored value'; +assertTrue(accessorDidRun); + +// Test for regression in mixed accessor/data property objects. +// The strict function is one such object. +assertTrue(Object.isSealed(Object.seal(function(){"use strict";}))); + +// Also test a simpler case +obj = {}; +Object.defineProperty(obj, 'accessor2', { + get: function() { return 42 }, + set: function() { accessorDidRun = true }, + configurable: true, + enumerable: true +}); +obj.data = 'foo'; +assertTrue(%HasFastProperties(obj)); +Object.seal(obj); +assertTrue(%HasFastProperties(obj)); +assertTrue(Object.isSealed(obj)); + +function Sealed() {} +Object.seal(Sealed); +assertDoesNotThrow(function() { return new Sealed(); }); +Sealed.prototype.prototypeExists = true; +assertTrue((new Sealed()).prototypeExists); + +obj = new Int32Array(10) +Object.seal(obj); +assertTrue(Object.isSealed(obj)); diff --git a/implementation-contributed/v8/mjsunit/regress-918763.js b/implementation-contributed/v8/mjsunit/regress-918763.js new file mode 100644 index 0000000000..45916f015a --- /dev/null +++ b/implementation-contributed/v8/mjsunit/regress-918763.js @@ -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: --allow-natives-syntax + +function C() {} +C.__proto__ = null; + +function f(c) { return 0 instanceof c; } + +f(C); +%OptimizeFunctionOnNextCall(f); +assertThrows(() => f(0)); diff --git a/implementation-contributed/v8/mjsunit/regress/regress-8630.js b/implementation-contributed/v8/mjsunit/regress/regress-8630.js new file mode 100644 index 0000000000..f51807b4a5 --- /dev/null +++ b/implementation-contributed/v8/mjsunit/regress/regress-8630.js @@ -0,0 +1,32 @@ +// 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 + +// Parameters can't have parentheses (both patterns and identifiers) +assertThrows("( ({x: 1}) ) => {};", SyntaxError); +assertThrows("( (x) ) => {}", SyntaxError); +assertThrows("( ({x: 1}) = y ) => {}", SyntaxError); +assertThrows("( (x) = y ) => {}", SyntaxError); + +// Declarations can't have parentheses (both patterns and identifiers) +assertThrows("let [({x: 1})] = [];", SyntaxError); +assertThrows("let [(x)] = [];", SyntaxError); +assertThrows("let [({x: 1}) = y] = [];", SyntaxError); +assertThrows("let [(x) = y] = [];", SyntaxError); +assertThrows("var [({x: 1})] = [];", SyntaxError); +assertThrows("var [(x)] = [];", SyntaxError); +assertThrows("var [({x: 1}) = y] = [];", SyntaxError); +assertThrows("var [(x) = y] = [];", SyntaxError); + +// Patterns in can't have parentheses in assignments either +assertThrows("[({x: 1}) = y] = [];", SyntaxError); + +// Parentheses are fine around identifiers in assignments though, even inside a +// pattern +var x; +[(x)] = [2]; +assertEquals(x, 2); +[(x) = 3] = []; +assertEquals(x, 3); diff --git a/implementation-contributed/v8/mjsunit/regress/regress-8659.js b/implementation-contributed/v8/mjsunit/regress/regress-8659.js new file mode 100644 index 0000000000..636c667c79 --- /dev/null +++ b/implementation-contributed/v8/mjsunit/regress/regress-8659.js @@ -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("const [(x)] = []", SyntaxError); diff --git a/implementation-contributed/v8/mjsunit/regress/regress-913844.js b/implementation-contributed/v8/mjsunit/regress/regress-913844.js new file mode 100644 index 0000000000..3516f35126 --- /dev/null +++ b/implementation-contributed/v8/mjsunit/regress/regress-913844.js @@ -0,0 +1,7 @@ +// 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: --disable-in-process-stack-traces --perf-prof-unwinding-info --turbo-loop-rotation +for (var x = 0; x < 1000000; x++) +; diff --git a/implementation-contributed/v8/mjsunit/regress/regress-917215.js b/implementation-contributed/v8/mjsunit/regress/regress-917215.js new file mode 100644 index 0000000000..e8d7e10462 --- /dev/null +++ b/implementation-contributed/v8/mjsunit/regress/regress-917215.js @@ -0,0 +1,6 @@ +// 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. + +a: if (true) b: { break a; break b; } +else b: { break a; break b; } diff --git a/implementation-contributed/v8/mjsunit/regress/regress-917755.js b/implementation-contributed/v8/mjsunit/regress/regress-917755.js new file mode 100644 index 0000000000..49803ae2d3 --- /dev/null +++ b/implementation-contributed/v8/mjsunit/regress/regress-917755.js @@ -0,0 +1,12 @@ +// 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. + +{ + function a() {} +} + +{ + let a; + function a() {}; +} diff --git a/implementation-contributed/v8/mjsunit/regress/regress-917988.js b/implementation-contributed/v8/mjsunit/regress/regress-917988.js new file mode 100644 index 0000000000..e9a8458edd --- /dev/null +++ b/implementation-contributed/v8/mjsunit/regress/regress-917988.js @@ -0,0 +1,31 @@ +// 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. + +// Tests if class declarations in parameter list are correctly handled. +function v_2( +v_3 = class v_4 { + get [[] = ';']() { } +} +) { } +v_2(); + +// Test object inside a class in a parameter list +(function f( +v_3 = class v_4 { + get [{} = ';']() { } +} +) { })(); + +// Test destructuring of class in parameters +(function f( {p, q} = class C { get [[] = ';']() {} } ) {})(); + +// Test array destructuring of class in parameters +class C {}; +C[Symbol.iterator] = function() { + return { + next: function() { return { done: true }; }, + _first: true + }; +}; +(function f1([p, q] = class D extends C { get [[]]() {} }) { })(); diff --git a/implementation-contributed/v8/mjsunit/regress/regress-919340.js b/implementation-contributed/v8/mjsunit/regress/regress-919340.js new file mode 100644 index 0000000000..900bf6fde2 --- /dev/null +++ b/implementation-contributed/v8/mjsunit/regress/regress-919340.js @@ -0,0 +1,17 @@ +// 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 --opt + +var E = 'Σ'; +var PI = 123; +function f() { + print(E = 2, /b/.test(E) || /b/.test(E = 2)); + ((E = 3) * PI); +} + +f(); +f(); +%OptimizeFunctionOnNextCall(f); +f(); diff --git a/implementation-contributed/v8/mjsunit/regress/regress-919710.js b/implementation-contributed/v8/mjsunit/regress/regress-919710.js new file mode 100644 index 0000000000..11422958af --- /dev/null +++ b/implementation-contributed/v8/mjsunit/regress/regress-919710.js @@ -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("( let ) => { 'use strict'; let }", SyntaxError) diff --git a/implementation-contributed/v8/mjsunit/regress/regress-921382.js b/implementation-contributed/v8/mjsunit/regress/regress-921382.js new file mode 100644 index 0000000000..d7cce2b723 --- /dev/null +++ b/implementation-contributed/v8/mjsunit/regress/regress-921382.js @@ -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("(d * f * g) * e => 0", SyntaxError) diff --git a/implementation-contributed/v8/mjsunit/regress/regress-crbug-917076.js b/implementation-contributed/v8/mjsunit/regress/regress-crbug-917076.js new file mode 100644 index 0000000000..7c19c02204 --- /dev/null +++ b/implementation-contributed/v8/mjsunit/regress/regress-crbug-917076.js @@ -0,0 +1,20 @@ +// Copyright 2019 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Flags: --allow-natives-syntax + +let speciesCounter = 0; + +Object.defineProperty(Promise, Symbol.species, { + value: function(...args) { + speciesCounter++; + return new Promise(...args); + } +}); + +async function foo() { } + +assertPromiseResult(Promise.all([foo()]), () => { + assertEquals(3, speciesCounter); +}); diff --git a/implementation-contributed/v8/mjsunit/regress/regress-crbug-917980.js b/implementation-contributed/v8/mjsunit/regress/regress-crbug-917980.js new file mode 100644 index 0000000000..18dc782400 --- /dev/null +++ b/implementation-contributed/v8/mjsunit/regress/regress-crbug-917980.js @@ -0,0 +1,33 @@ +// 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 + +const constructors = [ + [Uint8Array, [0, 1]], + [Int8Array, [0, 1]], + [Uint16Array, [0, 1]], + [Int16Array, [0, 1]], + [Uint32Array, [0, 1]], + [Int32Array, [0, 1]], + [Float32Array, [0, 1]], + [Float64Array, [0, 1]], + [Uint8ClampedArray, [0, 1]], + [BigInt64Array, [0n, 1n]], + [BigUint64Array, [0n, 1n]] +]; + +let typedArray; + +const separator = { + toString() { + %ArrayBufferDetach(typedArray.buffer); + return '*'; + } +}; + +constructors.forEach(([constructor, arr]) => { + typedArray = new constructor(arr); + assertSame(typedArray.join(separator), '*'); +}); diff --git a/implementation-contributed/v8/mjsunit/regress/regress-crbug-920184.js b/implementation-contributed/v8/mjsunit/regress/regress-crbug-920184.js new file mode 100644 index 0000000000..c38f181750 --- /dev/null +++ b/implementation-contributed/v8/mjsunit/regress/regress-crbug-920184.js @@ -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: --verify-heap --enable-slow-asserts + +var Ctor = function() { + return []; +}; +var a = ["one", "two", "three"]; +a.constructor = {}; +a.constructor[Symbol.species] = Ctor; + +a.filter(function() { return true; }); diff --git a/implementation-contributed/v8/mjsunit/regress/regress-loop-var-assign-without-block-scope.js b/implementation-contributed/v8/mjsunit/regress/regress-loop-var-assign-without-block-scope.js new file mode 100644 index 0000000000..8c85c1380f --- /dev/null +++ b/implementation-contributed/v8/mjsunit/regress/regress-loop-var-assign-without-block-scope.js @@ -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: --allow-natives-syntax +function f() { + // Loop with a body that's not wrapped in a block. + for (i = 0; i < 2; i++) + var x = i, // var x that's assigned on each iteration + y = y||(()=>x), // single arrow function that returns x + z = (%OptimizeFunctionOnNextCall(y), y()); // optimize y on first iteration + return y() +}; +assertEquals(1, f()) diff --git a/implementation-contributed/v8/mjsunit/regress/regress-sloppy-block-function-hoisting-dynamic.js b/implementation-contributed/v8/mjsunit/regress/regress-sloppy-block-function-hoisting-dynamic.js new file mode 100644 index 0000000000..59758eda5e --- /dev/null +++ b/implementation-contributed/v8/mjsunit/regress/regress-sloppy-block-function-hoisting-dynamic.js @@ -0,0 +1,6 @@ +// 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. + +with({}) { eval("{function f(){f}}") }; +f() diff --git a/implementation-contributed/v8/mjsunit/regress/wasm/regress-905815.js b/implementation-contributed/v8/mjsunit/regress/wasm/regress-905815.js new file mode 100644 index 0000000000..7967d99756 --- /dev/null +++ b/implementation-contributed/v8/mjsunit/regress/wasm/regress-905815.js @@ -0,0 +1,27 @@ +// 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. + +load('test/mjsunit/wasm/wasm-constants.js'); +load('test/mjsunit/wasm/wasm-module-builder.js'); + +(function() { + const builder = new WasmModuleBuilder(); + builder.addType(makeSig([], [])); + builder.addType(makeSig([kWasmI32], [kWasmI32])); + builder.addFunction(undefined, 0 /* sig */) + .addBodyWithEnd([ + kExprEnd, // @1 + ]); + builder.addFunction(undefined, 1 /* sig */) + .addLocals({i32_count: 65}) + .addBodyWithEnd([ + kExprLoop, kWasmStmt, // @3 + kSimdPrefix, + kExprF32x4Min, + kExprI64UConvertI32, + kExprI64RemS, + kExprUnreachable, + kExprLoop, 0x02, // @10 + ]); +}) diff --git a/implementation-contributed/v8/mjsunit/regress/wasm/regress-917412.js b/implementation-contributed/v8/mjsunit/regress/wasm/regress-917412.js new file mode 100644 index 0000000000..fd7ab99020 --- /dev/null +++ b/implementation-contributed/v8/mjsunit/regress/wasm/regress-917412.js @@ -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. + +load('test/mjsunit/wasm/wasm-constants.js'); +load('test/mjsunit/wasm/wasm-module-builder.js'); + +const builder = new WasmModuleBuilder(); +const sig = builder.addType(makeSig([kWasmI32, kWasmI64], [])); +builder.addFunction(undefined, sig) + .addBody([ +kExprI32Const, 0, +kExprIf, kWasmI32, + kExprI32Const, 0, +kExprElse, + kExprI32Const, 1, + kExprEnd, +kExprTeeLocal, 0, +kExprGetLocal, 0, +kExprLoop, kWasmStmt, + kExprI64Const, 0x80, 0x80, 0x80, 0x70, + kExprSetLocal, 0x01, + kExprI32Const, 0x00, + kExprIf, kWasmI32, + kExprI32Const, 0x00, + kExprElse, + kExprI32Const, 0x00, + kExprEnd, + kExprBrIf, 0x00, + kExprUnreachable, + kExprEnd, +kExprUnreachable, +]); +builder.instantiate(); diff --git a/implementation-contributed/v8/mjsunit/regress/wasm/regress-917588.js b/implementation-contributed/v8/mjsunit/regress/wasm/regress-917588.js new file mode 100644 index 0000000000..cb07bb5280 --- /dev/null +++ b/implementation-contributed/v8/mjsunit/regress/wasm/regress-917588.js @@ -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. + +load('test/mjsunit/wasm/wasm-constants.js'); +load('test/mjsunit/wasm/wasm-module-builder.js'); + +const builder = new WasmModuleBuilder(); +const sig = builder.addType(makeSig([], [kWasmF64])); +builder.addFunction(undefined, sig) + .addLocals({f32_count: 5}).addLocals({f64_count: 3}) + .addBody([ +kExprBlock, kWasmF64, + kExprF64Const, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x3f, + kExprF64Const, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + kExprI32Const, 0, + kExprIf, kWasmI32, + kExprI32Const, 0, + kExprElse, + kExprI32Const, 1, + kExprEnd, + kExprBrIf, 0, + kExprUnreachable, +kExprEnd +]); +builder.instantiate(); diff --git a/implementation-contributed/v8/mjsunit/regress/wasm/regress-917588b.js b/implementation-contributed/v8/mjsunit/regress/wasm/regress-917588b.js new file mode 100644 index 0000000000..9d461cfd84 --- /dev/null +++ b/implementation-contributed/v8/mjsunit/regress/wasm/regress-917588b.js @@ -0,0 +1,55 @@ +// 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. + +load('test/mjsunit/wasm/wasm-constants.js'); +load('test/mjsunit/wasm/wasm-module-builder.js'); + +const builder = new WasmModuleBuilder(); +const sig0 = builder.addType(makeSig([kWasmF32], [kWasmI32])); +const sig1 = builder.addType(makeSig([kWasmI64, kWasmI32, kWasmI64, kWasmF32, kWasmI64], [kWasmF32])); +const sig2 = builder.addType(makeSig([kWasmF32], [kWasmF32])); +// Generate function 1 (out of 3). +builder.addFunction(undefined, sig0).addBody([kExprI32Const, 0x00]); +// Generate function 2 (out of 3). +builder.addFunction(undefined, sig1) + .addBody([ + // signature: f_lilfl + kExprBlock, kWasmF32, // @1 f32 + kExprI32Const, 0x00, + kExprIf, kWasmStmt, // @5 + kExprLoop, kWasmStmt, // @7 + kExprBlock, kWasmI32, // @9 i32 + kExprF32Const, 0x00, 0x00, 0x80, 0xc1, + kExprF32Const, 0x00, 0x00, 0x80, 0x45, + kExprCallFunction, 0x00, // function #0: i_f + kExprBrIf, 0x03, // depth=3 + kExprDrop, + kExprI32Const, 0xd8, 0x00, + kExprEnd, // @29 + kExprBrIf, 0x00, // depth=0 + kExprEnd, // @32 + kExprF32Const, 0x00, 0x00, 0x80, 0x3f, + kExprF32Const, 0x00, 0x00, 0x80, 0xc6, + kExprBlock, kWasmI32, // @43 i32 + kExprF32Const, 0x00, 0x00, 0x80, 0x3f, + kExprCallFunction, 0x02, // function #2: f_f + kExprDrop, + kExprI32Const, 0x68, + kExprEnd, // @55 + kExprBrIf, 0x01, // depth=1 + kExprI32Const, 0x00, + kExprSelect, + kExprDrop, + kExprUnreachable, + kExprElse, // @63 + kExprNop, + kExprEnd, // @65 + kExprF32Const, 0x00, 0x00, 0x69, 0x43, + kExprEnd // @71 +]); +// Generate function 3 (out of 3). +builder.addFunction(undefined, sig2).addBody([ + kExprF32Const, 0x00, 0x00, 0x80, 0x3f +]); +builder.instantiate(); diff --git a/implementation-contributed/v8/mjsunit/regress/wasm/regress-918149.js b/implementation-contributed/v8/mjsunit/regress/wasm/regress-918149.js new file mode 100644 index 0000000000..f19a26d2a3 --- /dev/null +++ b/implementation-contributed/v8/mjsunit/regress/wasm/regress-918149.js @@ -0,0 +1,12 @@ +// 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. + +load('test/mjsunit/wasm/wasm-constants.js'); +load('test/mjsunit/wasm/wasm-module-builder.js'); + +const builder = new WasmModuleBuilder(); +const sig = + builder.addType(makeSig([kWasmI32, kWasmI32, kWasmI32], [kWasmI64])); +builder.addFunction('main', sig).addBody([kExprI64Const, 1, kExprI64SExtendI8]); +builder.instantiate(); diff --git a/implementation-contributed/v8/mjsunit/regress/wasm/regress-918284.js b/implementation-contributed/v8/mjsunit/regress/wasm/regress-918284.js new file mode 100644 index 0000000000..05614edf3c --- /dev/null +++ b/implementation-contributed/v8/mjsunit/regress/wasm/regress-918284.js @@ -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. + +load('test/mjsunit/wasm/wasm-constants.js'); +load('test/mjsunit/wasm/wasm-module-builder.js'); + +const builder = new WasmModuleBuilder(); +builder.addFunction(undefined, kSig_i_i) + .addLocals({i32_count: 7}) + .addBody([ + kExprI32Const, 0, + kExprIf, kWasmI32, // @11 i32 + kExprI32Const, 0, + kExprElse, // @15 + kExprI32Const, 1, + kExprEnd, // @18 + kExprTeeLocal, 0, + kExprI32Popcnt +]); +builder.instantiate(); diff --git a/implementation-contributed/v8/mjsunit/regress/wasm/regress-918917.js b/implementation-contributed/v8/mjsunit/regress/wasm/regress-918917.js new file mode 100644 index 0000000000..725287ae74 --- /dev/null +++ b/implementation-contributed/v8/mjsunit/regress/wasm/regress-918917.js @@ -0,0 +1,22 @@ +// 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. + +load('test/mjsunit/wasm/wasm-constants.js'); +load('test/mjsunit/wasm/wasm-module-builder.js'); + +const builder = new WasmModuleBuilder(); +builder.addFunction(undefined, kSig_v_v) + .addLocals({i32_count: 1}).addLocals({f32_count: 1}).addLocals({f64_count: 1}) + .addBody([ +kExprGetLocal, 1, +kExprGetLocal, 2, +kExprGetLocal, 0, +kExprIf, kWasmI32, + kExprI32Const, 1, +kExprElse, + kExprUnreachable, + kExprEnd, +kExprUnreachable +]); +builder.instantiate(); diff --git a/implementation-contributed/v8/mjsunit/regress/wasm/regress-919308.js b/implementation-contributed/v8/mjsunit/regress/wasm/regress-919308.js new file mode 100644 index 0000000000..cb10662290 --- /dev/null +++ b/implementation-contributed/v8/mjsunit/regress/wasm/regress-919308.js @@ -0,0 +1,37 @@ +// 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. + +load('test/mjsunit/wasm/wasm-constants.js'); +load('test/mjsunit/wasm/wasm-module-builder.js'); + +const builder = new WasmModuleBuilder(); +builder.addFunction(undefined, kSig_i_i) + .addLocals({i32_count: 5}) + .addBody([ + kExprGetLocal, 0, // --> 1 + kExprIf, kWasmI32, + kExprGetLocal, 0, // --> 1 + kExprElse, + kExprUnreachable, + kExprEnd, + kExprIf, kWasmI32, + kExprGetLocal, 0, // --> 1 + kExprElse, + kExprUnreachable, + kExprEnd, + kExprIf, kWasmI32, + kExprI32Const, 0, + kExprGetLocal, 0, + kExprI32Sub, // --> -1 + kExprGetLocal, 0, + kExprGetLocal, 0, + kExprI32Sub, // --> 0 + kExprI32Sub, // --> -1 + kExprElse, + kExprUnreachable, + kExprEnd +]); +builder.addExport('main', 0); +const instance = builder.instantiate(); +assertEquals(-1, instance.exports.main(1)); diff --git a/implementation-contributed/v8/mjsunit/regress/wasm/regress-919533.js b/implementation-contributed/v8/mjsunit/regress/wasm/regress-919533.js new file mode 100644 index 0000000000..58273f666b --- /dev/null +++ b/implementation-contributed/v8/mjsunit/regress/wasm/regress-919533.js @@ -0,0 +1,25 @@ +// 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. + +load('test/mjsunit/wasm/wasm-constants.js'); +load('test/mjsunit/wasm/wasm-module-builder.js'); + +const builder = new WasmModuleBuilder(); +builder.addFunction(undefined, kSig_v_v).addBody([]); +builder.addFunction(undefined, kSig_i_i) + .addBody([ + kExprGetLocal, 0, + kExprGetLocal, 0, + // Stack now contains two copies of the first param register. + // Start a loop to create a merge point (values still in registers). + kExprLoop, kWasmStmt, + // The call spills all values. + kExprCallFunction, 0, + // Break to the loop. Now the spilled values need to be loaded back *into + // the same register*. + kExprBr, 0, + kExprEnd, + kExprDrop +]); +builder.instantiate(); diff --git a/implementation-contributed/v8/mjsunit/regress/wasm/regress-922432.js b/implementation-contributed/v8/mjsunit/regress/wasm/regress-922432.js new file mode 100644 index 0000000000..8f1ad11ebc --- /dev/null +++ b/implementation-contributed/v8/mjsunit/regress/wasm/regress-922432.js @@ -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. + +// Flags: --experimental-wasm-eh + +load("test/mjsunit/wasm/wasm-constants.js"); +load("test/mjsunit/wasm/wasm-module-builder.js"); + +(function TestTruncatedBrOnExnInLoop() { + let builder = new WasmModuleBuilder(); + let fun = builder.addFunction(undefined, kSig_v_v) + .addLocals({except_count: 1}) + .addBody([ + kExprLoop, kWasmStmt, + kExprGetLocal, 0, + kExprBrOnExn // Bytecode truncated here. + ]).exportFunc(); + fun.body.pop(); // Pop implicitly added kExprEnd from body. + assertThrows(() => builder.instantiate(), WebAssembly.CompileError); +})(); diff --git a/implementation-contributed/v8/mjsunit/testcfg.py b/implementation-contributed/v8/mjsunit/testcfg.py index e69de29bb2..901d8e90a4 100644 --- a/implementation-contributed/v8/mjsunit/testcfg.py +++ b/implementation-contributed/v8/mjsunit/testcfg.py @@ -0,0 +1,283 @@ +# Copyright 2008 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. + +from collections import OrderedDict +import itertools +import os +import re + +from testrunner.local import statusfile +from testrunner.local import testsuite +from testrunner.objects import testcase +from testrunner.outproc import base as outproc + +FILES_PATTERN = re.compile(r"//\s+Files:(.*)") +ENV_PATTERN = re.compile(r"//\s+Environment Variables:(.*)") +SELF_SCRIPT_PATTERN = re.compile(r"//\s+Env: TEST_FILE_NAME") +MODULE_PATTERN = re.compile(r"^// MODULE$", flags=re.MULTILINE) +NO_HARNESS_PATTERN = re.compile(r"^// NO HARNESS$", flags=re.MULTILINE) + + +# Flags known to misbehave when combining arbitrary mjsunit tests. Can also +# be compiled regular expressions. +COMBINE_TESTS_FLAGS_BLACKLIST = [ + '--check-handle-count', + '--enable-tracing', + re.compile('--experimental.*'), + '--expose-trigger-failure', + re.compile('--harmony.*'), + '--mock-arraybuffer-allocator', + '--print-ast', + re.compile('--trace.*'), + '--wasm-lazy-compilation', +] + +class TestSuite(testsuite.TestSuite): + def ListTests(self): + tests = [] + for dirname, dirs, files in os.walk(self.root, followlinks=True): + for dotted in [x for x in dirs if x.startswith('.')]: + dirs.remove(dotted) + dirs.sort() + files.sort() + for filename in files: + if (filename.endswith(".js") and + filename != "mjsunit.js" and + filename != "mjsunit_suppressions.js"): + fullpath = os.path.join(dirname, filename) + relpath = fullpath[len(self.root) + 1 : -3] + testname = relpath.replace(os.path.sep, "/") + test = self._create_test(testname) + tests.append(test) + return tests + + def _test_combiner_class(self): + return TestCombiner + + def _test_class(self): + return TestCase + + +class TestCase(testcase.D8TestCase): + def __init__(self, *args, **kwargs): + super(TestCase, self).__init__(*args, **kwargs) + + source = self.get_source() + + files_list = [] # List of file names to append to command arguments. + files_match = FILES_PATTERN.search(source); + # Accept several lines of 'Files:'. + while True: + if files_match: + files_list += files_match.group(1).strip().split() + files_match = FILES_PATTERN.search(source, files_match.end()) + else: + break + files = [ os.path.normpath(os.path.join(self.suite.root, '..', '..', f)) + for f in files_list ] + testfilename = os.path.join(self.suite.root, + self.path + self._get_suffix()) + if SELF_SCRIPT_PATTERN.search(source): + files = ( + ["-e", "TEST_FILE_NAME=\"%s\"" % testfilename.replace("\\", "\\\\")] + + files) + + if NO_HARNESS_PATTERN.search(source): + mjsunit_files = [] + else: + mjsunit_files = [os.path.join(self.suite.root, "mjsunit.js")] + + files_suffix = [] + if MODULE_PATTERN.search(source): + files_suffix.append("--module") + files_suffix.append(testfilename) + + self._source_files = files + self._source_flags = self._parse_source_flags(source) + self._mjsunit_files = mjsunit_files + self._files_suffix = files_suffix + self._env = self._parse_source_env(source) + + def _parse_source_env(self, source): + env_match = ENV_PATTERN.search(source) + env = {} + if env_match: + for env_pair in env_match.group(1).strip().split(): + var, value = env_pair.split('=') + env[var] = value + return env + + def _get_source_flags(self): + return self._source_flags + + def _get_files_params(self): + files = list(self._source_files) + if not self._test_config.no_harness: + files += self._mjsunit_files + files += self._files_suffix + if self._test_config.isolates: + files += ['--isolate'] + files + + return files + + def _get_cmd_env(self): + return self._env + + def _get_source_path(self): + return os.path.join(self.suite.root, self.path + self._get_suffix()) + + +class TestCombiner(testsuite.TestCombiner): + def get_group_key(self, test): + """Combine tests with the same set of flags. + Ignore: + 1. Some special cases where it's not obvious what to pass in the command. + 2. Tests with flags that can cause failure even inside try-catch wrapper. + 3. Tests that use async functions. Async functions can be scheduled after + exiting from try-catch wrapper and cause failure. + """ + if (len(test._files_suffix) > 1 or + test._env or + not test._mjsunit_files or + test._source_files): + return None + + source_flags = test._get_source_flags() + if ('--expose-trigger-failure' in source_flags or + '--throws' in source_flags): + return None + + source_code = test.get_source() + # Maybe we could just update the tests to await all async functions they + # call? + if 'async' in source_code: + return None + + # TODO(machenbach): Remove grouping if combining tests in a flag-independent + # way works well. + return 1 + + def _combined_test_class(self): + return CombinedTest + + +class CombinedTest(testcase.D8TestCase): + """Behaves like normal mjsunit tests except: + 1. Expected outcome is always PASS + 2. Instead of one file there is a try-catch wrapper with all combined tests + passed as arguments. + """ + def __init__(self, name, tests): + super(CombinedTest, self).__init__(tests[0].suite, '', name, + tests[0]._test_config) + self._tests = tests + + def _prepare_outcomes(self, force_update=True): + self._statusfile_outcomes = outproc.OUTCOMES_PASS_OR_TIMEOUT + self.expected_outcomes = outproc.OUTCOMES_PASS_OR_TIMEOUT + + def _get_shell_flags(self): + """In addition to standard set of shell flags it appends: + --disable-abortjs: %AbortJS can abort the test even inside + trycatch-wrapper, so we disable it. + --es-staging: We blacklist all harmony flags due to false positives, + but always pass the staging flag to cover the mature features. + --omit-quit: Calling quit() in JS would otherwise early terminate. + --quiet-load: suppress any stdout from load() function used by + trycatch-wrapper. + """ + return [ + '--test', + '--disable-abortjs', + '--es-staging', + '--omit-quit', + '--quiet-load', + ] + + def _get_cmd_params(self): + return ( + super(CombinedTest, self)._get_cmd_params() + + ['tools/testrunner/trycatch_loader.js', '--'] + + self._tests[0]._mjsunit_files + + ['--'] + + [t._files_suffix[0] for t in self._tests] + ) + + def _merge_flags(self, flags): + """Merges flags from a list of flags. + + Flag values not starting with '-' are merged with the preceeding flag, + e.g. --foo 1 will become --foo=1. All other flags remain the same. + + Returns: A generator of flags. + """ + if not flags: + return + # Iterate over flag pairs. ['-'] is a sentinel value for the last iteration. + for flag1, flag2 in itertools.izip(flags, flags[1:] + ['-']): + if not flag2.startswith('-'): + assert '=' not in flag1 + yield flag1 + '=' + flag2 + elif flag1.startswith('-'): + yield flag1 + + def _is_flag_blacklisted(self, flag): + for item in COMBINE_TESTS_FLAGS_BLACKLIST: + if isinstance(item, basestring): + if item == flag: + return True + elif item.match(flag): + return True + return False + + def _get_combined_flags(self, flags_gen): + """Combines all flags - dedupes, keeps order and filters some flags. + + Args: + flags_gen: Generator for flag lists. + Returns: A list of flags. + """ + merged_flags = self._merge_flags(list(itertools.chain(*flags_gen))) + unique_flags = OrderedDict((flag, True) for flag in merged_flags).keys() + return [ + flag for flag in unique_flags + if not self._is_flag_blacklisted(flag) + ] + + def _get_source_flags(self): + # Combine flags from all source files. + return self._get_combined_flags( + test._get_source_flags() for test in self._tests) + + def _get_statusfile_flags(self): + # Combine flags from all status file entries. + return self._get_combined_flags( + test._get_statusfile_flags() for test in self._tests) + + +def GetSuite(*args, **kwargs): + return TestSuite(*args, **kwargs) diff --git a/implementation-contributed/v8/test262/test262.status b/implementation-contributed/v8/test262/test262.status index deb63febad..fae6692cb8 100644 --- a/implementation-contributed/v8/test262/test262.status +++ b/implementation-contributed/v8/test262/test262.status @@ -142,38 +142,6 @@ 'language/eval-code/direct/var-env-lower-lex-catch-non-strict': [FAIL], # https://bugs.chromium.org/p/v8/issues/detail?id=4951 - 'language/expressions/assignment/dstr-array-elem-iter-rtrn-close-err': [FAIL], - 'language/expressions/assignment/dstr-array-elem-iter-thrw-close': [FAIL], - 'language/expressions/assignment/dstr-array-elem-iter-thrw-close-err': [FAIL], - 'language/expressions/assignment/dstr-array-elem-trlg-iter-list-thrw-close': [FAIL], - 'language/expressions/assignment/dstr-array-elem-trlg-iter-list-thrw-close-err': [FAIL], - 'language/expressions/assignment/dstr-array-elem-trlg-iter-rest-rtrn-close': [FAIL], - 'language/expressions/assignment/dstr-array-elem-trlg-iter-rest-rtrn-close-err': [FAIL], - 'language/expressions/assignment/dstr-array-elem-trlg-iter-rest-rtrn-close-null': [FAIL], - 'language/expressions/assignment/dstr-array-elem-trlg-iter-rest-thrw-close': [FAIL], - 'language/expressions/assignment/dstr-array-elem-trlg-iter-rest-thrw-close-err': [FAIL], - 'language/expressions/assignment/dstr-array-rest-iter-rtrn-close': [FAIL], - 'language/expressions/assignment/dstr-array-rest-iter-rtrn-close-err': [FAIL], - 'language/expressions/assignment/dstr-array-rest-iter-rtrn-close-null': [FAIL], - 'language/expressions/assignment/dstr-array-rest-iter-thrw-close': [FAIL], - 'language/expressions/assignment/dstr-array-rest-iter-thrw-close-err': [FAIL], - 'language/expressions/assignment/dstr-array-rest-lref-err': [FAIL], - 'language/statements/for-of/dstr-array-elem-iter-rtrn-close-err': [FAIL], - 'language/statements/for-of/dstr-array-elem-iter-thrw-close': [FAIL], - 'language/statements/for-of/dstr-array-elem-iter-thrw-close-err': [FAIL], - 'language/statements/for-of/dstr-array-elem-trlg-iter-list-thrw-close': [FAIL], - 'language/statements/for-of/dstr-array-elem-trlg-iter-list-thrw-close-err': [FAIL], - 'language/statements/for-of/dstr-array-elem-trlg-iter-rest-rtrn-close': [FAIL], - 'language/statements/for-of/dstr-array-elem-trlg-iter-rest-rtrn-close-err': [FAIL], - 'language/statements/for-of/dstr-array-elem-trlg-iter-rest-rtrn-close-null': [FAIL], - 'language/statements/for-of/dstr-array-elem-trlg-iter-rest-thrw-close': [FAIL], - 'language/statements/for-of/dstr-array-elem-trlg-iter-rest-thrw-close-err': [FAIL], - 'language/statements/for-of/dstr-array-rest-iter-rtrn-close': [FAIL], - 'language/statements/for-of/dstr-array-rest-iter-rtrn-close-err': [FAIL], - 'language/statements/for-of/dstr-array-rest-iter-rtrn-close-null': [FAIL], - 'language/statements/for-of/dstr-array-rest-iter-thrw-close': [FAIL], - 'language/statements/for-of/dstr-array-rest-iter-thrw-close-err': [FAIL], - 'language/statements/for-of/dstr-array-rest-lref-err': [FAIL], 'language/expressions/assignment/destructuring/iterator-destructuring-property-reference-target-evaluation-order': [FAIL], 'language/expressions/assignment/destructuring/keyed-destructuring-property-reference-target-evaluation-order': [FAIL], @@ -420,19 +388,6 @@ # https://bugs.chromium.org/p/v8/issues/detail?id=5116 'built-ins/TypedArray/prototype/fill/fill-values-conversion-operations-consistent-nan': [PASS, FAIL], - # https://bugs.chromium.org/p/v8/issues/detail?id=5135 - 'annexB/language/eval-code/direct/func-block-decl-eval-func-block-scoping': [FAIL], - 'annexB/language/eval-code/direct/func-if-decl-else-decl-a-eval-func-block-scoping': [FAIL], - 'annexB/language/eval-code/direct/func-if-decl-else-decl-b-eval-func-block-scoping': [FAIL], - 'annexB/language/eval-code/direct/func-if-decl-else-stmt-eval-func-block-scoping': [FAIL], - 'annexB/language/eval-code/direct/func-if-decl-no-else-eval-func-block-scoping': [FAIL], - 'annexB/language/eval-code/direct/func-if-stmt-else-decl-eval-func-block-scoping': [FAIL], - 'annexB/language/eval-code/direct/func-switch-case-eval-func-block-scoping': [FAIL], - 'annexB/language/eval-code/direct/func-switch-dflt-eval-func-block-scoping': [FAIL], - - # https://bugs.chromium.org/p/v8/issues/detail?id=5139 - 'annexB/built-ins/Date/prototype/setYear/year-number-relative': [FAIL], - # https://bugs.chromium.org/p/v8/issues/detail?id=4698 'language/expressions/call/tco-call-args': [SKIP], 'language/expressions/call/tco-cross-realm-class-construct': [SKIP], @@ -479,16 +434,6 @@ 'built-ins/TypedArrayConstructors/internals/Set/key-is-out-of-bounds': [FAIL], 'built-ins/TypedArrayConstructors/internals/Set/BigInt/key-is-out-of-bounds': [FAIL], - # https://bugs.chromium.org/p/v8/issues/detail?id=5112 - 'annexB/language/eval-code/direct/func-block-decl-eval-func-no-skip-try': [FAIL], - 'annexB/language/eval-code/direct/func-if-decl-else-decl-a-eval-func-no-skip-try': [FAIL], - 'annexB/language/eval-code/direct/func-if-decl-else-decl-b-eval-func-no-skip-try': [FAIL], - 'annexB/language/eval-code/direct/func-if-decl-else-stmt-eval-func-no-skip-try': [FAIL], - 'annexB/language/eval-code/direct/func-if-decl-no-else-eval-func-no-skip-try': [FAIL], - 'annexB/language/eval-code/direct/func-if-stmt-else-decl-eval-func-no-skip-try': [FAIL], - 'annexB/language/eval-code/direct/func-switch-case-eval-func-no-skip-try': [FAIL], - 'annexB/language/eval-code/direct/func-switch-dflt-eval-func-no-skip-try': [FAIL], - # SharedArrayBuffer tests that require flags 'built-ins/SharedArrayBuffer/*': ['--harmony-sharedarraybuffer'], 'built-ins/Atomics/*': ['--harmony-sharedarraybuffer'], @@ -561,13 +506,15 @@ 'language/expressions/call/eval-spread-empty-leading': [FAIL], 'language/expressions/call/eval-spread-empty-trailing': [FAIL], + # https://bugs.chromium.org/p/v8/issues/detail?id=8398 + 'intl402/supportedLocalesOf-returned-array-elements-are-frozen': [FAIL], + 'intl402/ListFormat/constructor/supportedLocalesOf/result-type': [FAIL], + 'intl402/RelativeTimeFormat/constructor/supportedLocalesOf/result-type': [FAIL], + 'intl402/Segmenter/constructor/supportedLocalesOf/result-type': [FAIL], + # https://bugs.chromium.org/p/v8/issues/detail?id=7472 'intl402/NumberFormat/currency-digits': [FAIL], - # https://bugs.chromium.org/p/v8/issues/detail?id=7474 - 'intl402/NumberFormat/prototype/format/format-fraction-digits': [FAIL], - 'intl402/NumberFormat/prototype/format/format-significant-digits': [FAIL], - # https://bugs.chromium.org/p/v8/issues/detail?id=7482 'intl402/DateTimeFormat/prototype/resolvedOptions/resolved-locale-with-hc-unicode': [FAIL], @@ -577,9 +524,6 @@ # https://bugs.chromium.org/p/v8/issues/detail?id=7669 'intl402/Intl/getCanonicalLocales/canonicalized-tags': [FAIL], - # https://github.com/tc39/ecma402/issues/223 - 'intl402/Collator/missing-unicode-ext-value-defaults-to-true': [FAIL], - # https://bugs.chromium.org/p/v8/issues/detail?id=8260 'intl402/Locale/constructor-non-iana-canon': [FAIL], @@ -592,17 +536,6 @@ # https://bugs.chromium.org/p/v8/issues/detail?id=8246 'intl402/Locale/constructor-tag': [FAIL], - # https://bugs.chromium.org/p/v8/issues/detail?id=8244 - 'intl402/Locale/constructor-getter-order': [FAIL], - 'intl402/Locale/constructor-locale-object': [FAIL], - 'intl402/Locale/constructor-options-language-grandfathered': [FAIL], - 'intl402/Locale/constructor-options-language-invalid': [FAIL], - 'intl402/Locale/constructor-options-region-invalid': [FAIL], - 'intl402/Locale/constructor-options-region-valid': [FAIL], - 'intl402/Locale/constructor-options-script-invalid': [FAIL], - 'intl402/Locale/constructor-options-script-valid': [FAIL], - 'intl402/Locale/getters': [FAIL], - # https://bugs.chromium.org/p/v8/issues/detail?id=8243 'intl402/Locale/extensions-private': [FAIL], 'intl402/Locale/getters-privateuse': [FAIL], @@ -615,6 +548,9 @@ 'intl402/Locale/getters-grandfathered': [FAIL], 'intl402/Locale/likely-subtags-grandfathered': [FAIL], + # https://bugs.chromium.org/p/v8/issues/detail?id=8613 + 'intl402/RelativeTimeFormat/prototype/resolvedOptions/order': [FAIL], + # https://bugs.chromium.org/p/v8/issues/detail?id=6705 'built-ins/Object/assign/strings-and-symbol-order': [FAIL], @@ -624,9 +560,6 @@ 'language/expressions/async-generator/generator-created-after-decl-inst': [FAIL], 'language/statements/async-generator/generator-created-after-decl-inst': [FAIL], - # https://bugs.chromium.org/p/v8/issues/detail?id=8099 - 'intl402/NumberFormat/prototype/format/format-negative-numbers': [FAIL], - # await tests that require flags 'language/expressions/await/async-generator-interleaved': ['--harmony-await-optimization'], 'language/expressions/await/await-monkey-patched-promise': ['--harmony-await-optimization'], @@ -646,7 +579,6 @@ # https://bugs.chromium.org/p/v8/issues/detail?id=8258 'intl402/Locale/constructor-options-language-valid-undefined': [FAIL], - 'intl402/Locale/constructor-options-throwing-getters': [FAIL], 'intl402/NumberFormat/prototype/format/format-fraction-digits-precision': [FAIL], 'intl402/NumberFormat/prototype/format/format-significant-digits-precision': [FAIL], -- GitLab