diff options
Diffstat (limited to 'deps/v8/test/mjsunit/es6')
125 files changed, 7735 insertions, 1043 deletions
diff --git a/deps/v8/test/mjsunit/es6/array-concat-revoked-proxy-1.js b/deps/v8/test/mjsunit/es6/array-concat-revoked-proxy-1.js new file mode 100644 index 0000000000..2dfddc3504 --- /dev/null +++ b/deps/v8/test/mjsunit/es6/array-concat-revoked-proxy-1.js @@ -0,0 +1,19 @@ +// Copyright 2016 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +(function testConcatRevokedProxyToArrayInPrototype() { + "use strict"; + var handler = { + get(_, name) { + if (name === Symbol.isConcatSpreadable) { + p.revoke(); + } + return target[name]; + } + } + + var p = Proxy.revocable([], handler); + var target = { __proto__: p.proxy }; + assertThrows(function() { [].concat(target); }, TypeError); +})(); diff --git a/deps/v8/test/mjsunit/es6/array-concat-revoked-proxy-2.js b/deps/v8/test/mjsunit/es6/array-concat-revoked-proxy-2.js new file mode 100644 index 0000000000..f91eb655bf --- /dev/null +++ b/deps/v8/test/mjsunit/es6/array-concat-revoked-proxy-2.js @@ -0,0 +1,19 @@ +// Copyright 2016 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +(function testConcatRevokedProxyToArray() { + "use strict"; + var handler = { + get(_, name) { + if (name === Symbol.isConcatSpreadable) { + p.revoke(); + } + return target[name]; + } + } + + var target = []; + var p = Proxy.revocable(target, handler); + assertThrows(function() { [].concat(p.proxy); }, TypeError); +})(); diff --git a/deps/v8/test/mjsunit/es6/array-concat.js b/deps/v8/test/mjsunit/es6/array-concat.js index fe320d6858..f57c10e03e 100644 --- a/deps/v8/test/mjsunit/es6/array-concat.js +++ b/deps/v8/test/mjsunit/es6/array-concat.js @@ -1,7 +1,6 @@ // 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. - (function testArrayConcatArity() { "use strict"; assertEquals(1, Array.prototype.concat.length); @@ -20,6 +19,15 @@ assertEquals(false, desc.enumerable); })(); +(function testNonConcatSpreadableArray() { + "use strict" + var array = [1, 2, 3]; + assertEquals(array, [].concat(array)); + assertEquals(array, array.concat([])); + array[Symbol.isConcatSpreadable] = false; + assertEquals([[1,2,3]], [].concat(array)); + assertEquals([[1,2,3]], array.concat([])); +})(); (function testConcatArrayLike() { "use strict"; @@ -864,3 +872,25 @@ logger.get = function(t, trap, r) { assertThrows(() => [].concat(obj), TypeError); assertThrows(() => Array.prototype.concat.apply(obj), TypeError); })(); + +(function testConcatRevokedProxy() { + "use strict"; + var target = []; + var handler = { + get(_, name) { + if (name === Symbol.isConcatSpreadable) { + p.revoke(); + } + return target[name]; + } + } + + p = Proxy.revocable(target, handler); + target = {}; + target.__proto__ = p.proxy; + assertThrows(function() { [].concat({ __proto__: p.proxy }); }, TypeError); + + target = []; + var p = Proxy.revocable(target, handler); + assertThrows(function() { [].concat(p.proxy); }, TypeError); +})(); diff --git a/deps/v8/test/mjsunit/es6/array-prototype-values.js b/deps/v8/test/mjsunit/es6/array-prototype-values.js index 64162c47c8..b7c4e78e33 100644 --- a/deps/v8/test/mjsunit/es6/array-prototype-values.js +++ b/deps/v8/test/mjsunit/es6/array-prototype-values.js @@ -13,3 +13,4 @@ assertTrue(valuesDesc.configurable); assertTrue(valuesDesc.writable); assertFalse(valuesDesc.enumerable); assertTrue(Array.prototype[Symbol.unscopables].values); +assertThrows(() => new Array.prototype[Symbol.iterator], TypeError); diff --git a/deps/v8/test/mjsunit/es6/array-species-constructor-accessor.js b/deps/v8/test/mjsunit/es6/array-species-constructor-accessor.js new file mode 100644 index 0000000000..7ebf328a8a --- /dev/null +++ b/deps/v8/test/mjsunit/es6/array-species-constructor-accessor.js @@ -0,0 +1,28 @@ +// Copyright 2016 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Flags: --allow-natives-syntax + +// Overwriting the constructor of an instance updates the protector + +let x = []; + +assertEquals(Array, x.map(()=>{}).constructor); +assertEquals(Array, x.filter(()=>{}).constructor); +assertEquals(Array, x.slice().constructor); +assertEquals(Array, x.splice().constructor); +assertEquals(Array, x.concat([1]).constructor); +assertEquals(1, x.concat([1])[0]); + +class MyArray extends Array { } + +Object.defineProperty(x, 'constructor', {get() { return MyArray; }}); +assertFalse(%SpeciesProtector()); + +assertEquals(MyArray, x.map(()=>{}).constructor); +assertEquals(MyArray, x.filter(()=>{}).constructor); +assertEquals(MyArray, x.slice().constructor); +assertEquals(MyArray, x.splice().constructor); +assertEquals(MyArray, x.concat([1]).constructor); +assertEquals(1, x.concat([1])[0]); diff --git a/deps/v8/test/mjsunit/es6/array-species-constructor-delete.js b/deps/v8/test/mjsunit/es6/array-species-constructor-delete.js new file mode 100644 index 0000000000..fff22a2a8c --- /dev/null +++ b/deps/v8/test/mjsunit/es6/array-species-constructor-delete.js @@ -0,0 +1,29 @@ +// Copyright 2016 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Flags: --allow-natives-syntax + +// Overwriting the constructor of an instance updates the protector + +let x = []; + +assertEquals(Array, x.map(()=>{}).constructor); +assertEquals(Array, x.filter(()=>{}).constructor); +assertEquals(Array, x.slice().constructor); +assertEquals(Array, x.splice().constructor); +assertEquals(Array, x.concat([1]).constructor); +assertEquals(1, x.concat([1])[0]); + +class MyArray extends Array { } + +Object.prototype.constructor = MyArray; +delete Array.prototype.constructor; +assertFalse(%SpeciesProtector()); + +assertEquals(MyArray, x.map(()=>{}).constructor); +assertEquals(MyArray, x.filter(()=>{}).constructor); +assertEquals(MyArray, x.slice().constructor); +assertEquals(MyArray, x.splice().constructor); +assertEquals(MyArray, x.concat([1]).constructor); +assertEquals(1, x.concat([1])[0]); diff --git a/deps/v8/test/mjsunit/es6/array-species-constructor.js b/deps/v8/test/mjsunit/es6/array-species-constructor.js new file mode 100644 index 0000000000..0d888f46ee --- /dev/null +++ b/deps/v8/test/mjsunit/es6/array-species-constructor.js @@ -0,0 +1,28 @@ +// Copyright 2016 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Flags: --allow-natives-syntax + +// Overwriting the constructor of an instance updates the protector + +let x = []; + +assertEquals(Array, x.map(()=>{}).constructor); +assertEquals(Array, x.filter(()=>{}).constructor); +assertEquals(Array, x.slice().constructor); +assertEquals(Array, x.splice().constructor); +assertEquals(Array, x.concat([1]).constructor); +assertEquals(1, x.concat([1])[0]); + +class MyArray extends Array { } + +x.constructor = MyArray; +assertFalse(%SpeciesProtector()); + +assertEquals(MyArray, x.map(()=>{}).constructor); +assertEquals(MyArray, x.filter(()=>{}).constructor); +assertEquals(MyArray, x.slice().constructor); +assertEquals(MyArray, x.splice().constructor); +assertEquals(MyArray, x.concat([1]).constructor); +assertEquals(1, x.concat([1])[0]); diff --git a/deps/v8/test/mjsunit/es6/array-species-delete.js b/deps/v8/test/mjsunit/es6/array-species-delete.js new file mode 100644 index 0000000000..16a2fa26f9 --- /dev/null +++ b/deps/v8/test/mjsunit/es6/array-species-delete.js @@ -0,0 +1,29 @@ +// Copyright 2016 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Flags: --allow-natives-syntax + +// Overwriting the constructor of an instance updates the protector + +let x = []; + +assertEquals(Array, x.map(()=>{}).constructor); +assertEquals(Array, x.filter(()=>{}).constructor); +assertEquals(Array, x.slice().constructor); +assertEquals(Array, x.splice().constructor); +assertEquals(Array, x.concat([1]).constructor); +assertEquals(1, x.concat([1])[0]); + +class MyArray extends Array { } + +Object.prototype[Symbol.species] = MyArray; +delete Array[Symbol.species]; +assertFalse(%SpeciesProtector()); + +assertEquals(MyArray, x.map(()=>{}).constructor); +assertEquals(MyArray, x.filter(()=>{}).constructor); +assertEquals(MyArray, x.slice().constructor); +assertEquals(MyArray, x.splice().constructor); +assertEquals(MyArray, x.concat([1]).constructor); +assertEquals(1, x.concat([1])[0]); diff --git a/deps/v8/test/mjsunit/es6/array-species-modified.js b/deps/v8/test/mjsunit/es6/array-species-modified.js new file mode 100644 index 0000000000..58feb31669 --- /dev/null +++ b/deps/v8/test/mjsunit/es6/array-species-modified.js @@ -0,0 +1,28 @@ +// Copyright 2016 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Flags: --allow-natives-syntax + +// Overwriting Array[Symbol.species] updates the protector + +let x = []; + +assertEquals(Array, x.map(()=>{}).constructor); +assertEquals(Array, x.filter(()=>{}).constructor); +assertEquals(Array, x.slice().constructor); +assertEquals(Array, x.splice().constructor); +assertEquals(Array, x.concat([1]).constructor); +assertEquals(1, x.concat([1])[0]); + +class MyArray extends Array { } + +Object.defineProperty(Array, Symbol.species, {value: MyArray}); +assertFalse(%SpeciesProtector()); + +assertEquals(MyArray, x.map(()=>{}).constructor); +assertEquals(MyArray, x.filter(()=>{}).constructor); +assertEquals(MyArray, x.slice().constructor); +assertEquals(MyArray, x.splice().constructor); +assertEquals(MyArray, x.concat([1]).constructor); +assertEquals(1, x.concat([1])[0]); diff --git a/deps/v8/test/mjsunit/es6/array-species-neg-zero.js b/deps/v8/test/mjsunit/es6/array-species-neg-zero.js new file mode 100644 index 0000000000..d60b8ba00f --- /dev/null +++ b/deps/v8/test/mjsunit/es6/array-species-neg-zero.js @@ -0,0 +1,23 @@ +// Copyright 2016 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +/** + * 9.4.2.3 ArraySpeciesCreate(originalArray, length) + * + * 1. Assert: length is an integer Number ≥ 0. + * 2. If length is −0, let length be +0. + * [...] + */ + +var x = []; +var deleteCount; + +x.constructor = function() {}; +x.constructor[Symbol.species] = function(param) { + deleteCount = param; +}; + +x.splice(0, -0); + +assertEquals(0, deleteCount); diff --git a/deps/v8/test/mjsunit/es6/array-species-parent-constructor.js b/deps/v8/test/mjsunit/es6/array-species-parent-constructor.js new file mode 100644 index 0000000000..b4fb1d56e3 --- /dev/null +++ b/deps/v8/test/mjsunit/es6/array-species-parent-constructor.js @@ -0,0 +1,28 @@ +// Copyright 2016 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Flags: --allow-natives-syntax + +// Overwriting Array.prototype.constructor updates the protector + +let x = []; + +assertEquals(Array, x.map(()=>{}).constructor); +assertEquals(Array, x.filter(()=>{}).constructor); +assertEquals(Array, x.slice().constructor); +assertEquals(Array, x.splice().constructor); +assertEquals(Array, x.concat([1]).constructor); +assertEquals(1, x.concat([1])[0]); + +class MyArray extends Array { } + +Array.prototype.constructor = MyArray; +assertFalse(%SpeciesProtector()); + +assertEquals(MyArray, x.map(()=>{}).constructor); +assertEquals(MyArray, x.filter(()=>{}).constructor); +assertEquals(MyArray, x.slice().constructor); +assertEquals(MyArray, x.splice().constructor); +assertEquals(MyArray, x.concat([1]).constructor); +assertEquals(1, x.concat([1])[0]); diff --git a/deps/v8/test/mjsunit/es6/array-species-proto.js b/deps/v8/test/mjsunit/es6/array-species-proto.js new file mode 100644 index 0000000000..6b55881cd6 --- /dev/null +++ b/deps/v8/test/mjsunit/es6/array-species-proto.js @@ -0,0 +1,28 @@ +// Copyright 2016 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Flags: --allow-natives-syntax + +// Overwriting an array instance's __proto__ updates the protector + +let x = []; + +assertEquals(Array, x.map(()=>{}).constructor); +assertEquals(Array, x.filter(()=>{}).constructor); +assertEquals(Array, x.slice().constructor); +assertEquals(Array, x.splice().constructor); +assertEquals(Array, x.concat([1]).constructor); +assertEquals(1, x.concat([1])[0]); + +class MyArray extends Array { } + +x.__proto__ = MyArray.prototype; +assertTrue(%SpeciesProtector()); + +assertEquals(MyArray, x.map(()=>{}).constructor); +assertEquals(MyArray, x.filter(()=>{}).constructor); +assertEquals(MyArray, x.slice().constructor); +assertEquals(MyArray, x.splice().constructor); +assertEquals(MyArray, x.concat([1]).constructor); +assertEquals(1, x.concat([1])[0]); diff --git a/deps/v8/test/mjsunit/es6/array-species.js b/deps/v8/test/mjsunit/es6/array-species.js new file mode 100644 index 0000000000..25edf55104 --- /dev/null +++ b/deps/v8/test/mjsunit/es6/array-species.js @@ -0,0 +1,171 @@ +// 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 the ES2015 @@species feature + +'use strict'; + +// Subclasses of Array construct themselves under map, etc + +class MyArray extends Array { } + +assertEquals(MyArray, new MyArray().map(()=>{}).constructor); +assertEquals(MyArray, new MyArray().filter(()=>{}).constructor); +assertEquals(MyArray, new MyArray().slice().constructor); +assertEquals(MyArray, new MyArray().splice().constructor); +assertEquals(MyArray, new MyArray().concat([1]).constructor); +assertEquals(1, new MyArray().concat([1])[0]); + +// Subclasses can override @@species to return the another class + +class MyOtherArray extends Array { + static get [Symbol.species]() { return MyArray; } +} + +assertEquals(MyArray, new MyOtherArray().map(()=>{}).constructor); +assertEquals(MyArray, new MyOtherArray().filter(()=>{}).constructor); +assertEquals(MyArray, new MyOtherArray().slice().constructor); +assertEquals(MyArray, new MyOtherArray().splice().constructor); +assertEquals(MyArray, new MyOtherArray().concat().constructor); + +// Array methods on non-arrays return arrays + +class MyNonArray extends Array { + static get [Symbol.species]() { return MyObject; } +} + +class MyObject { } + +assertEquals(MyObject, + Array.prototype.map.call(new MyNonArray(), ()=>{}).constructor); +assertEquals(MyObject, + Array.prototype.filter.call(new MyNonArray(), ()=>{}).constructor); +assertEquals(MyObject, + Array.prototype.slice.call(new MyNonArray()).constructor); +assertEquals(MyObject, + Array.prototype.splice.call(new MyNonArray()).constructor); +assertEquals(MyObject, + Array.prototype.concat.call(new MyNonArray()).constructor); + +assertEquals(undefined, + Array.prototype.map.call(new MyNonArray(), ()=>{}).length); +assertEquals(undefined, + Array.prototype.filter.call(new MyNonArray(), ()=>{}).length); +assertEquals(undefined, + Array.prototype.concat.call(new MyNonArray(), ()=>{}).length); +// slice and splice actually do explicitly define the length for some reason +assertEquals(0, Array.prototype.slice.call(new MyNonArray()).length); +assertEquals(0, Array.prototype.splice.call(new MyNonArray()).length); + +// Cross-realm Arrays build same-realm arrays + +var realm = Realm.create(); +assertEquals(Array, + Array.prototype.map.call( + Realm.eval(realm, "[]"), ()=>{}).constructor); +assertFalse(Array === Realm.eval(realm, "[]").map(()=>{}).constructor); +assertFalse(Array === Realm.eval(realm, "[].map(()=>{}).constructor")); +assertEquals(Array, + Array.prototype.concat.call( + Realm.eval(realm, "[]")).constructor); + +// Defaults when constructor or @@species is missing or non-constructor + +class MyDefaultArray extends Array { + static get [Symbol.species]() { return undefined; } +} +assertEquals(Array, new MyDefaultArray().map(()=>{}).constructor); + +class MyOtherDefaultArray extends Array { } +assertEquals(MyOtherDefaultArray, + new MyOtherDefaultArray().map(()=>{}).constructor); +MyOtherDefaultArray.prototype.constructor = undefined; +assertEquals(Array, new MyOtherDefaultArray().map(()=>{}).constructor); +assertEquals(Array, new MyOtherDefaultArray().concat().constructor); + +// Exceptions propagated when getting constructor @@species throws + +class SpeciesError extends Error { } +class ConstructorError extends Error { } +class MyThrowingArray extends Array { + static get [Symbol.species]() { throw new SpeciesError; } +} +assertThrows(() => new MyThrowingArray().map(()=>{}), SpeciesError); +Object.defineProperty(MyThrowingArray.prototype, 'constructor', { + get() { throw new ConstructorError; } +}); +assertThrows(() => new MyThrowingArray().map(()=>{}), ConstructorError); + +// Previously unexpected errors from setting properties in arrays throw + +class FrozenArray extends Array { + constructor(...args) { + super(...args); + Object.freeze(this); + } +} +assertThrows(() => new FrozenArray([1]).map(()=>0), TypeError); +assertThrows(() => new FrozenArray([1]).filter(()=>true), TypeError); +assertThrows(() => new FrozenArray([1]).slice(0, 1), TypeError); +assertThrows(() => new FrozenArray([1]).splice(0, 1), TypeError); +assertThrows(() => new FrozenArray([]).concat([1]), TypeError); + +// Verify call counts and constructor parameters + +var count; +var params; +class MyObservedArray extends Array { + constructor(...args) { + super(...args); + params = args; + } + static get [Symbol.species]() { + count++ + return this; + } +} + +count = 0; +params = undefined; +assertEquals(MyObservedArray, + new MyObservedArray().map(()=>{}).constructor); +assertEquals(1, count); +assertArrayEquals([0], params); + +count = 0; +params = undefined; +assertEquals(MyObservedArray, + new MyObservedArray().filter(()=>{}).constructor); +assertEquals(1, count); +assertArrayEquals([0], params); + +count = 0; +params = undefined; +assertEquals(MyObservedArray, + new MyObservedArray().concat().constructor); +assertEquals(1, count); +assertArrayEquals([0], params); + +count = 0; +params = undefined; +assertEquals(MyObservedArray, + new MyObservedArray().slice().constructor); +assertEquals(1, count); +assertArrayEquals([0], params); + +count = 0; +params = undefined; +assertEquals(MyObservedArray, + new MyObservedArray().splice().constructor); +assertEquals(1, count); +assertArrayEquals([0], params); + +// @@species constructor can be a Proxy, and the realm access doesn't +// crash + +class MyProxyArray extends Array { } +let ProxyArray = new Proxy(MyProxyArray, {}); +MyProxyArray.constructor = ProxyArray; + +assertEquals(MyProxyArray, new ProxyArray().map(()=>{}).constructor); diff --git a/deps/v8/test/mjsunit/es6/arraybuffer-species.js b/deps/v8/test/mjsunit/es6/arraybuffer-species.js new file mode 100644 index 0000000000..1ac6efbe26 --- /dev/null +++ b/deps/v8/test/mjsunit/es6/arraybuffer-species.js @@ -0,0 +1,34 @@ +// 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. + +// ArrayBuffer.prototype.slice makes subclass and checks length + +class MyArrayBuffer extends ArrayBuffer { } +assertEquals(MyArrayBuffer, new MyArrayBuffer(0).slice().constructor); + +class MyShortArrayBuffer extends ArrayBuffer { + constructor(length) { super(length - 1); } +} +assertThrows(() => new MyShortArrayBuffer(5).slice(0, 4), TypeError); + +class SingletonArrayBuffer extends ArrayBuffer { + constructor(...args) { + if (SingletonArrayBuffer.cached) return SingletonArrayBuffer.cached; + super(...args); + SingletonArrayBuffer.cached = this; + } +} +assertThrows(() => new SingletonArrayBuffer(5).slice(0, 4), TypeError); + +class NonArrayBuffer extends ArrayBuffer { + constructor() { + return {}; + } +} +assertThrows(() => new NonArrayBuffer(5).slice(0, 4), TypeError); + +// Species fallback is ArrayBuffer +class UndefinedArrayBuffer extends ArrayBuffer { } +UndefinedArrayBuffer.prototype.constructor = undefined; +assertEquals(ArrayBuffer, new UndefinedArrayBuffer(0).slice().constructor); diff --git a/deps/v8/test/mjsunit/es6/block-conflicts-sloppy.js b/deps/v8/test/mjsunit/es6/block-conflicts-sloppy.js new file mode 100644 index 0000000000..b2ebfce6c9 --- /dev/null +++ b/deps/v8/test/mjsunit/es6/block-conflicts-sloppy.js @@ -0,0 +1,174 @@ +// Copyright 2011 the V8 project 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 for conflicting variable bindings. + +function CheckException(e) { + var string = e.toString(); + assertTrue(string.indexOf("has already been declared") >= 0 || + string.indexOf("redeclaration") >= 0); + return 'Conflict'; +} + + +function TestGlobal(s,e) { + try { + return eval(s + e); + } catch (x) { + return CheckException(x); + } +} + + +function TestFunction(s,e) { + try { + return eval("(function(){" + s + " return " + e + "})")(); + } catch (x) { + return CheckException(x); + } +} + + +function TestBlock(s,e) { + try { + return eval("(function(){ {" + s + "} return " + e + "})")(); + } catch (x) { + return CheckException(x); + } +} + +function TestAll(expected,s,opt_e) { + var e = ""; + var msg = s; + if (opt_e) { e = opt_e; msg += opt_e; } + // TODO(littledan): Add tests using Realm.eval to ensure that global eval + // works as expected. + assertEquals(expected === 'LocalConflict' ? 'NoConflict' : expected, + TestGlobal(s,e), "global:'" + msg + "'"); + assertEquals(expected === 'LocalConflict' ? 'NoConflict' : expected, + TestFunction(s,e), "function:'" + msg + "'"); + assertEquals(expected === 'LocalConflict' ? 'Conflict' : expected, + TestBlock(s,e), "block:'" + msg + "'"); +} + + +function TestConflict(s) { + TestAll('Conflict', s); + TestAll('Conflict', 'eval("' + s + '");'); +} + +function TestNoConflict(s) { + TestAll('NoConflict', s, "'NoConflict'"); + TestAll('NoConflict', 'eval("' + s + '");', "'NoConflict'"); +} + +function TestLocalConflict(s) { + TestAll('LocalConflict', s, "'NoConflict'"); + TestAll('NoConflict', 'eval("' + s + '");', "'NoConflict'"); +} + +var letbinds = [ "let x;", + "let x = 0;", + "let x = undefined;", + "let x = function() {};", + "let x, y;", + "let y, x;", + "const x = 0;", + "const x = undefined;", + "const x = function() {};", + "const x = 2, y = 3;", + "const y = 4, x = 5;", + "class x { }", + ]; +function forCompatible(bind) { + return !bind.startsWith('class'); +} +var varbinds = [ "var x;", + "var x = 0;", + "var x = undefined;", + "var x = function() {};", + "var x, y;", + "var y, x;", + ]; +var funbind = "function x() {}"; + +for (var l = 0; l < letbinds.length; ++l) { + // Test conflicting let/var bindings. + for (var v = 0; v < varbinds.length; ++v) { + // Same level. + TestConflict(letbinds[l] + varbinds[v]); + TestConflict(varbinds[v] + letbinds[l]); + // Different level. + TestConflict(letbinds[l] + '{' + varbinds[v] + '}'); + TestConflict('{' + varbinds[v] +'}' + letbinds[l]); + TestNoConflict(varbinds[v] + '{' + letbinds[l] + '}'); + TestNoConflict('{' + letbinds[l] + '}' + varbinds[v]); + // For loop. + if (forCompatible(letbinds[l])) { + TestConflict('for (' + letbinds[l] + '0;) {' + varbinds[v] + '}'); + } + TestNoConflict('for (' + varbinds[v] + '0;) {' + letbinds[l] + '}'); + } + + // Test conflicting let/let bindings. + for (var k = 0; k < letbinds.length; ++k) { + // Same level. + TestConflict(letbinds[l] + letbinds[k]); + TestConflict(letbinds[k] + letbinds[l]); + // Different level. + TestNoConflict(letbinds[l] + '{ ' + letbinds[k] + '}'); + TestNoConflict('{' + letbinds[k] +'} ' + letbinds[l]); + // For loop. + if (forCompatible(letbinds[l])) { + TestNoConflict('for (' + letbinds[l] + '0;) {' + letbinds[k] + '}'); + } + if (forCompatible(letbinds[k])) { + TestNoConflict('for (' + letbinds[k] + '0;) {' + letbinds[l] + '}'); + } + } + + // Test conflicting function/let bindings. + // Same level. + TestConflict(letbinds[l] + funbind); + TestConflict(funbind + letbinds[l]); + // Different level. + TestNoConflict(letbinds[l] + '{' + funbind + '}'); + TestNoConflict('{' + funbind + '}' + letbinds[l]); + TestNoConflict(funbind + '{' + letbinds[l] + '}'); + TestNoConflict('{' + letbinds[l] + '}' + funbind); + // For loop. + if (forCompatible(letbinds[l])) { + TestNoConflict('for (' + letbinds[l] + '0;) {' + funbind + '}'); + } + + // Test conflicting parameter/let bindings. + TestConflict('(function(x) {' + letbinds[l] + '})();'); +} + +// Test conflicting function/var bindings. +for (var v = 0; v < varbinds.length; ++v) { + // Same level. + TestLocalConflict(varbinds[v] + funbind); + TestLocalConflict(funbind + varbinds[v]); + // Different level. + TestLocalConflict(funbind + '{' + varbinds[v] + '}'); + TestLocalConflict('{' + varbinds[v] +'}' + funbind); + TestNoConflict(varbinds[v] + '{' + funbind + '}'); + TestNoConflict('{' + funbind + '}' + varbinds[v]); + // For loop. + TestNoConflict('for (' + varbinds[v] + '0;) {' + funbind + '}'); +} + +// Test conflicting catch/var bindings. +for (var v = 0; v < varbinds.length; ++v) { + TestNoConflict('try {} catch(x) {' + varbinds[v] + '}'); +} + +// Test conflicting parameter/var bindings. +for (var v = 0; v < varbinds.length; ++v) { + TestNoConflict('(function (x) {' + varbinds[v] + '})();'); +} + +// Test conflicting parameter/function bindings. +TestNoConflict('(function (x) {' + funbind + '})();'); diff --git a/deps/v8/test/mjsunit/es6/block-conflicts.js b/deps/v8/test/mjsunit/es6/block-conflicts.js index 0e3d4e5a2a..bca3cb4ea5 100644 --- a/deps/v8/test/mjsunit/es6/block-conflicts.js +++ b/deps/v8/test/mjsunit/es6/block-conflicts.js @@ -170,8 +170,5 @@ for (var v = 0; v < varbinds.length; ++v) { TestNoConflict('(function (x) {' + varbinds[v] + '})();'); } -// Test conflicting catch/function bindings. -TestNoConflict('try {} catch(x) {' + funbind + '}'); - // Test conflicting parameter/function bindings. TestNoConflict('(function (x) {' + funbind + '})();'); diff --git a/deps/v8/test/mjsunit/es6/block-const-assign-sloppy.js b/deps/v8/test/mjsunit/es6/block-const-assign-sloppy.js new file mode 100644 index 0000000000..99024ef7cb --- /dev/null +++ b/deps/v8/test/mjsunit/es6/block-const-assign-sloppy.js @@ -0,0 +1,156 @@ +// Copyright 2011 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. + +// Test that we throw early syntax errors in harmony mode +// when using an immutable binding in an assigment or with +// prefix/postfix decrement/increment operators. + +const decls = [ + // Const declaration. + function(use) { return "const c = 1; " + use + ";" }, TypeError, + function(use) { return "const x = 0, c = 1; " + use + ";" }, TypeError, + function(use) { return "const c = 1, x = (" + use + ");" }, TypeError, + function(use) { return use + "; const c = 1;" }, ReferenceError, + function(use) { return use + "; const x = 0, c = 1;" }, ReferenceError, + function(use) { return "const x = (" + use + "), c = 1;" }, ReferenceError, + function(use) { return "const c = (" + use + ");" }, ReferenceError, + + // Function expression. + function(use) { return "(function c() { " + use + "; })();"; }, TypeError, + // TODO(rossberg): Once we have default parameters, test using 'c' there. + + // Class expression. + function(use) { + return "new class c { constructor() { " + use + " } };"; + }, TypeError, + function(use) { + return "(new class c { m() { " + use + " } }).m();"; + }, TypeError, + function(use) { + return "(new class c { get a() { " + use + " } }).a;"; + }, TypeError, + function(use) { + return "(new class c { set a(x) { " + use + " } }).a = 0;"; + }, TypeError, + function(use) { + return "(class c { static m() { " + use + " } }).s();"; + }, TypeError, + function(use) { + return "(class c extends (" + use + ") {});"; + }, ReferenceError, + function(use) { + return "(class c { [" + use + "]() {} });"; + }, ReferenceError, + function(use) { + return "(class c { get [" + use + "]() {} });"; + }, ReferenceError, + function(use) { + return "(class c { set [" + use + "](x) {} });"; + }, ReferenceError, + function(use) { + return "(class c { static [" + use + "]() {} });"; + }, ReferenceError, + + // For loop. + function(use) { + return "for (const c = 0; " + use + ";) {}" + }, TypeError, + function(use) { + return "for (const x = 0, c = 0; " + use + ";) {}" + }, TypeError, + function(use) { + return "for (const c = 0; ; " + use + ") {}" + }, TypeError, + function(use) { + return "for (const x = 0, c = 0; ; " + use + ") {}" + }, TypeError, + function(use) { + return "for (const c = 0; ;) { " + use + "; }" + }, TypeError, + function(use) { + return "for (const x = 0, c = 0; ;) { " + use + "; }" + }, TypeError, + function(use) { + return "for (const c in {a: 1}) { " + use + "; }" + }, TypeError, + function(use) { + return "for (const c of [1]) { " + use + "; }" + }, TypeError, + function(use) { + return "for (const x = (" + use + "), c = 0; ;) {}" + }, ReferenceError, + function(use) { + return "for (const c = (" + use + "); ;) {}" + }, ReferenceError, +] + +let uses = [ + 'c = 1', + 'c += 1', + '++c', + 'c--', +]; + +let declcontexts = [ + function(decl) { return decl; }, + function(decl) { return "eval(\'" + decl + "\')"; }, + function(decl) { return "{ " + decl + " }"; }, + function(decl) { return "(function() { " + decl + " })()"; }, +]; + +let usecontexts = [ + function(use) { return use; }, + function(use) { return "eval(\"" + use + "\")"; }, + function(use) { return "(function() { " + use + " })()"; }, + function(use) { return "(function() { eval(\"" + use + "\"); })()"; }, + function(use) { return "eval(\"(function() { " + use + "; })\")()"; }, +]; + +function Test(program, error) { + program = "'use strict'; " + program; + try { + print(program, " // throw " + error.name); + eval(program); + } catch (e) { + assertInstanceof(e, error); + if (e === TypeError) { + assertTrue(e.toString().indexOf("Assignment to constant variable") >= 0); + } + return; + } + assertUnreachable(); +} + +for (var d = 0; d < decls.length; d += 2) { + for (var u = 0; u < uses.length; ++u) { + for (var o = 0; o < declcontexts.length; ++o) { + for (var i = 0; i < usecontexts.length; ++i) { + Test(declcontexts[o](decls[d](usecontexts[i](uses[u]))), decls[d + 1]); + } + } + } +} diff --git a/deps/v8/test/mjsunit/es6/block-early-errors.js b/deps/v8/test/mjsunit/es6/block-early-errors.js deleted file mode 100644 index 4af6521f64..0000000000 --- a/deps/v8/test/mjsunit/es6/block-early-errors.js +++ /dev/null @@ -1,54 +0,0 @@ -// Copyright 2011 the V8 project authors. All rights reserved. -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following -// disclaimer in the documentation and/or other materials provided -// with the distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived -// from this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// Flags: --no-harmony-sloppy-let - -function CheckException(e) { - var string = e.toString(); - assertInstanceof(e, SyntaxError); -} - -function Check(str) { - try { - eval("(function () { " + str + " })"); - assertUnreachable(); - } catch (e) { - CheckException(e); - } - try { - eval("(function () { { " + str + " } })"); - assertUnreachable(); - } catch (e) { - CheckException(e); - } -} - -// Check for early syntax errors when using let -// declarations outside of strict mode. -Check("let x;"); -Check("let x = 1;"); -Check("let x, y;"); diff --git a/deps/v8/test/mjsunit/es6/block-eval-var-over-let.js b/deps/v8/test/mjsunit/es6/block-eval-var-over-let.js new file mode 100644 index 0000000000..e16d7a02a6 --- /dev/null +++ b/deps/v8/test/mjsunit/es6/block-eval-var-over-let.js @@ -0,0 +1,155 @@ +// Copyright 2015 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Var-let conflict in a function throws, even if the var is in an eval + +// Throws at the top level of a function +assertThrows(function() { + let x = 1; + eval('var x'); +}, SyntaxError); + +// If the eval is in its own block scope, throws +assertThrows(function() { + let y = 1; + { eval('var y'); } +}, SyntaxError); + +// If the let is in its own block scope, with the eval, throws +assertThrows(function() { + { + let x = 1; + eval('var x'); + } +}, SyntaxError); + +// Legal if the let is no longer visible +assertDoesNotThrow(function() { + { + let x = 1; + } + eval('var x'); +}); + +// All the same works for const: +// Throws at the top level of a function +assertThrows(function() { + const x = 1; + eval('var x'); +}, SyntaxError); + +// If the eval is in its own block scope, throws +assertThrows(function() { + const y = 1; + { eval('var y'); } +}, SyntaxError); + +// If the const is in its own block scope, with the eval, throws +assertThrows(function() { + { + const x = 1; + eval('var x'); + } +}, SyntaxError); + +// Legal if the const is no longer visible +assertDoesNotThrow(function() { + { + const x = 1; + } + eval('var x'); +}); + +// The same should work for lexical function declarations: +// If the const is in its own block scope, with the eval, throws +assertThrows(function() { + { + function x() {} + eval('var x'); + } +}, SyntaxError); + +// If the eval is in its own block scope, throws +assertThrows(function() { + { + function y() {} + { eval('var y'); } + } +}, SyntaxError); + +// In global scope +let caught = false; +try { + let z = 1; + eval('var z'); +} catch (e) { + caught = true; +} +assertTrue(caught); + +// Let declarations beyond a function boundary don't conflict +caught = false; +try { + let a = 1; + (function() { + eval('var a'); + })(); +} catch (e) { + caught = true; +} +assertFalse(caught); + +// var across with doesn't conflict +caught = false; +try { + (function() { + with ({x: 1}) { + eval("var x"); + } + })(); +} catch (e) { + caught = true; +} +assertFalse(caught); + +// var can still conflict with let across a with +caught = false; +try { + (function() { + let x; + with ({x: 1}) { + eval("var x"); + } + })(); +} catch (e) { + caught = true; +} +assertTrue(caught); + +// Functions declared in eval also conflict +caught = false +try { + (function() { + { + let x = 1; + eval('function x() {}'); + } + })(); +} catch (e) { + caught = true; +} +assertTrue(caught); + +caught = false +try { + (function() { + { + let x = 1; + eval('{ function x() {} }'); + } + })(); +} catch (e) { + caught = true; +} +assertFalse(caught); diff --git a/deps/v8/test/mjsunit/es6/block-for-sloppy.js b/deps/v8/test/mjsunit/es6/block-for-sloppy.js new file mode 100644 index 0000000000..4f0f63faa3 --- /dev/null +++ b/deps/v8/test/mjsunit/es6/block-for-sloppy.js @@ -0,0 +1,199 @@ +// Copyright 2011 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. + +function props(x) { + var array = []; + for (let p in x) array.push(p); + return array.sort(); +} + +assertEquals(0, props({}).length); +assertEquals(1, props({x:1}).length); +assertEquals(2, props({x:1, y:2}).length); + +assertArrayEquals(["x"], props({x:1})); +assertArrayEquals(["x", "y"], props({x:1, y:2})); +assertArrayEquals(["x", "y", "zoom"], props({x:1, y:2, zoom:3})); + +assertEquals(0, props([]).length); +assertEquals(1, props([1]).length); +assertEquals(2, props([1,2]).length); + +assertArrayEquals(["0"], props([1])); +assertArrayEquals(["0", "1"], props([1,2])); +assertArrayEquals(["0", "1", "2"], props([1,2,3])); + +var o = {}; +var a = []; +let i = "outer_i"; +let s = "outer_s"; +for (let i = 0x0020; i < 0x01ff; i+=2) { + let s = 'char:' + String.fromCharCode(i); + a.push(s); + o[s] = i; +} +assertArrayEquals(a, props(o)); +assertEquals(i, "outer_i"); +assertEquals(s, "outer_s"); + +var a = []; +assertEquals(0, props(a).length); +a[Math.pow(2,30)-1] = 0; +assertEquals(1, props(a).length); +a[Math.pow(2,31)-1] = 0; +assertEquals(2, props(a).length); +a[1] = 0; +assertEquals(3, props(a).length); + +var result = ''; +for (let p in {a : [0], b : 1}) { result += p; } +assertEquals('ab', result); + +var result = ''; +for (let p in {a : {v:1}, b : 1}) { result += p; } +assertEquals('ab', result); + +var result = ''; +for (let p in { get a() {}, b : 1}) { result += p; } +assertEquals('ab', result); + +var result = ''; +for (let p in { get a() {}, set a(x) {}, b : 1}) { result += p; } +assertEquals('ab', result); + + +// Check that there is exactly one variable without initializer +// in a for-in statement with let variables. +assertThrows("function foo() { 'use strict'; for (let in {}) { } }", SyntaxError); +assertThrows("function foo() { 'use strict'; for (let x = 3 in {}) { } }", SyntaxError); +assertThrows("function foo() { 'use strict'; for (let x, y in {}) { } }", SyntaxError); +assertThrows("function foo() { 'use strict'; for (let x = 3, y in {}) { } }", SyntaxError); +assertThrows("function foo() { 'use strict'; for (let x, y = 4 in {}) { } }", SyntaxError); +assertThrows("function foo() { 'use strict'; for (let x = 3, y = 4 in {}) { } }", SyntaxError); + + +// In a normal for statement the iteration variable is +// freshly allocated for each iteration. +function closures1() { + let a = []; + for (let i = 0; i < 5; ++i) { + a.push(function () { return i; }); + } + for (let j = 0; j < 5; ++j) { + assertEquals(j, a[j]()); + } +} +closures1(); + + +function closures2() { + let a = [], b = []; + for (let i = 0, j = 10; i < 5; ++i, ++j) { + a.push(function () { return i; }); + b.push(function () { return j; }); + } + for (let k = 0; k < 5; ++k) { + assertEquals(k, a[k]()); + assertEquals(k + 10, b[k]()); + } +} +closures2(); + + +function closure_in_for_init() { + let a = []; + for (let i = 0, f = function() { return i }; i < 5; ++i) { + a.push(f); + } + for (let k = 0; k < 5; ++k) { + assertEquals(0, a[k]()); + } +} +closure_in_for_init(); + + +function closure_in_for_cond() { + let a = []; + for (let i = 0; a.push(function () { return i; }), i < 5; ++i) { } + for (let k = 0; k < 5; ++k) { + assertEquals(k, a[k]()); + } +} +closure_in_for_cond(); + + +function closure_in_for_next() { + let a = []; + for (let i = 0; i < 5; a.push(function () { return i; }), ++i) { } + for (let k = 0; k < 5; ++k) { + assertEquals(k + 1, a[k]()); + } +} +closure_in_for_next(); + + +// In a for-in statement the iteration variable is fresh +// for each iteration. +function closures3(x) { + let a = []; + for (let p in x) { + a.push(function () { return p; }); + } + let k = 0; + for (let q in x) { + assertEquals(q, a[k]()); + ++k; + } +} +closures3({a : [0], b : 1, c : {v : 1}, get d() {}, set e(x) {}}); + +// Check normal for statement completion values. +assertEquals(1, eval("for (let i = 0; i < 10; i++) { 1; }")); +assertEquals(9, eval("for (let i = 0; i < 10; i++) { i; }")); +assertEquals(undefined, eval("for (let i = 0; false;) { }")); +assertEquals(undefined, eval("for (const i = 0; false;) { }")); +assertEquals(undefined, eval("for (let i = 0; i < 10; i++) { }")); +assertEquals(undefined, eval("for (let i = 0; false;) { i; }")); +assertEquals(undefined, eval("for (const i = 0; false;) { i; }")); +assertEquals(undefined, eval("for (let i = 0; true;) { break; }")); +assertEquals(undefined, eval("for (const i = 0; true;) { break; }")); +assertEquals(undefined, eval("for (let i = 0; i < 10; i++) { continue; }")); +assertEquals(undefined, eval("for (let i = 0; true;) { break; i; }")); +assertEquals(undefined, eval("for (const i = 0; true;) { break; i; }")); +assertEquals(undefined, eval("for (let i = 0; i < 10; i++) { continue; i; }")); +assertEquals(0, eval("for (let i = 0; true;) { i; break; }")); +assertEquals(0, eval("for (const i = 0; true;) { i; break; }")); +assertEquals(9, eval("for (let i = 0; i < 10; i++) { i; continue; }")); +assertEquals( + undefined, eval("for (let i = 0; true; i++) { i; if (i >= 3) break; }")); +assertEquals( + undefined, eval("for (let i = 0; true; i++) { if (i >= 3) break; i; }")); +assertEquals( + undefined, eval("for (let i = 0; i < 10; i++) { if (i >= 3) continue; i; }")); +assertEquals(undefined, eval("foo: for (let i = 0; true;) { break foo; }")); +assertEquals(undefined, eval("foo: for (const i = 0; true;) { break foo; }")); +assertEquals(3, eval("foo: for (let i = 3; true;) { i; break foo; }")); diff --git a/deps/v8/test/mjsunit/es6/block-leave-sloppy.js b/deps/v8/test/mjsunit/es6/block-leave-sloppy.js new file mode 100644 index 0000000000..1313026bf8 --- /dev/null +++ b/deps/v8/test/mjsunit/es6/block-leave-sloppy.js @@ -0,0 +1,222 @@ +// Copyright 2011 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. + +// We want to test the context chain shape. In each of the tests cases +// below, the outer with is to force a runtime lookup of the identifier 'x' +// to actually verify that the inner context has been discarded. A static +// lookup of 'x' might accidentally succeed. + +{ + let x = 2; + L: { + let x = 3; + assertEquals(3, x); + break L; + assertTrue(false); + } + assertEquals(2, x); +} + +do { + let x = 4; + assertEquals(4,x); + { + let x = 5; + assertEquals(5, x); + continue; + assertTrue(false); + } +} while (false); + +var caught = false; +try { + { + let xx = 18; + throw 25; + assertTrue(false); + } +} catch (e) { + caught = true; + assertEquals(25, e); + (function () { + try { + // NOTE: This checks that the block scope containing xx has been + // removed from the context chain. + eval('xx'); + assertTrue(false); // should not reach here + } catch (e2) { + assertTrue(e2 instanceof ReferenceError); + } + })(); +} +assertTrue(caught); + + +(function(x) { + label: { + let x = 'inner'; + break label; + } + assertEquals('outer', eval('x')); +})('outer'); + + +(function(x) { + label: { + let x = 'middle'; + { + let x = 'inner'; + break label; + } + } + assertEquals('outer', eval('x')); +})('outer'); + + +(function(x) { + for (var i = 0; i < 10; ++i) { + let x = 'inner' + i; + continue; + } + assertEquals('outer', eval('x')); +})('outer'); + + +(function(x) { + label: for (var i = 0; i < 10; ++i) { + let x = 'middle' + i; + for (var j = 0; j < 10; ++j) { + let x = 'inner' + j; + continue label; + } + } + assertEquals('outer', eval('x')); +})('outer'); + + +(function(x) { + try { + let x = 'inner'; + throw 0; + } catch (e) { + assertEquals('outer', eval('x')); + } +})('outer'); + + +(function(x) { + try { + let x = 'middle'; + { + let x = 'inner'; + throw 0; + } + } catch (e) { + assertEquals('outer', eval('x')); + } +})('outer'); + + +try { + (function(x) { + try { + let x = 'inner'; + throw 0; + } finally { + assertEquals('outer', eval('x')); + } + })('outer'); +} catch (e) { + if (e instanceof MjsUnitAssertionError) throw e; +} + + +try { + (function(x) { + try { + let x = 'middle'; + { + let x = 'inner'; + throw 0; + } + } finally { + assertEquals('outer', eval('x')); + } + })('outer'); +} catch (e) { + if (e instanceof MjsUnitAssertionError) throw e; +} + + +// Verify that the context is correctly set in the stack frame after exiting +// from eval. +function f() {} + +(function(x) { + label: { + let x = 'inner'; + break label; + } + f(); // The context could be restored from the stack after the call. + assertEquals('outer', eval('x')); +})('outer'); + + +(function(x) { + for (var i = 0; i < 10; ++i) { + let x = 'inner'; + continue; + } + f(); + assertEquals('outer', eval('x')); +})('outer'); + + +(function(x) { + try { + let x = 'inner'; + throw 0; + } catch (e) { + f(); + assertEquals('outer', eval('x')); + } +})('outer'); + + +try { + (function(x) { + try { + let x = 'inner'; + throw 0; + } finally { + f(); + assertEquals('outer', eval('x')); + } + })('outer'); +} catch (e) { + if (e instanceof MjsUnitAssertionError) throw e; +} diff --git a/deps/v8/test/mjsunit/es6/block-let-contextual-sloppy.js b/deps/v8/test/mjsunit/es6/block-let-contextual-sloppy.js index ac7bca107e..8282d779a1 100644 --- a/deps/v8/test/mjsunit/es6/block-let-contextual-sloppy.js +++ b/deps/v8/test/mjsunit/es6/block-let-contextual-sloppy.js @@ -2,8 +2,6 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// Flags: --harmony-sloppy --harmony-sloppy-let - // let is usable as a variable with var, but not let or ES6 const (function (){ diff --git a/deps/v8/test/mjsunit/es6/block-let-crankshaft-sloppy.js b/deps/v8/test/mjsunit/es6/block-let-crankshaft-sloppy.js new file mode 100644 index 0000000000..b5e81f7850 --- /dev/null +++ b/deps/v8/test/mjsunit/es6/block-let-crankshaft-sloppy.js @@ -0,0 +1,482 @@ +// Copyright 2011 the V8 project authors. All rights reserved. +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following +// disclaimer in the documentation and/or other materials provided +// with the distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Flags: --allow-natives-syntax + +// Check that the following functions are optimizable. +var functions = [ f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, + f15, f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, + f27, f28, f29, f30, f31, f32, f33]; + +for (var i = 0; i < functions.length; ++i) { + var func = functions[i]; + print("Testing:"); + print(func); + for (var j = 0; j < 10; ++j) { + func(12); + } + %OptimizeFunctionOnNextCall(func); + func(12); + assertOptimized(func); +} + +function f1() { } + +function f2(x) { } + +function f3() { + let x; +} + +function f4() { + function foo() { + } +} + +function f5() { + let x = 1; +} + +function f6() { + const x = 1; +} + +function f7(x) { + return x; +} + +function f8() { + let x; + return x; +} + +function f9() { + function x() { + } + return x; +} + +function f10(x) { + x = 1; +} + +function f11() { + let x; + x = 1; +} + +function f12() { + function x() {}; + x = 1; +} + +function f13(x) { + (function() { x; }); +} + +function f14() { + let x; + (function() { x; }); +} + +function f15() { + function x() { + } + (function() { x; }); +} + +function f16() { + let x = 1; + (function() { x; }); +} + +function f17() { + const x = 1; + (function() { x; }); +} + +function f18(x) { + return x; + (function() { x; }); +} + +function f19() { + let x; + return x; + (function() { x; }); +} + +function f20() { + function x() { + } + return x; + (function() { x; }); +} + +function f21(x) { + x = 1; + (function() { x; }); +} + +function f22() { + let x; + x = 1; + (function() { x; }); +} + +function f23() { + function x() { } + x = 1; + (function() { x; }); +} + +function f24() { + let x = 1; + { + let x = 2; + { + let x = 3; + assertEquals(3, x); + } + assertEquals(2, x); + } + assertEquals(1, x); +} + +function f25() { + { + let x = 2; + L: { + let x = 3; + assertEquals(3, x); + break L; + assertTrue(false); + } + assertEquals(2, x); + } + assertTrue(true); +} + +function f26() { + { + let x = 1; + L: { + let x = 2; + { + let x = 3; + assertEquals(3, x); + break L; + assertTrue(false); + } + assertTrue(false); + } + assertEquals(1, x); + } +} + + +function f27() { + do { + let x = 4; + assertEquals(4,x); + { + let x = 5; + assertEquals(5, x); + continue; + assertTrue(false); + } + } while (false); +} + +function f28() { + label: for (var i = 0; i < 10; ++i) { + let x = 'middle' + i; + for (var j = 0; j < 10; ++j) { + let x = 'inner' + j; + continue label; + } + } +} + +function f29() { + // Verify that the context is correctly set in the stack frame after exiting + // from with. + + let x = 'outer'; + label: { + let x = 'inner'; + break label; + } + f(); // The context could be restored from the stack after the call. + assertEquals('outer', x); + + function f() { + assertEquals('outer', x); + }; +} + +function f30() { + let x = 'outer'; + for (var i = 0; i < 10; ++i) { + let x = 'inner'; + continue; + } + f(); + assertEquals('outer', x); + + function f() { + assertEquals('outer', x); + }; +} + +function f31() { + { + let x = 'outer'; + label: for (var i = 0; assertEquals('outer', x), i < 10; ++i) { + let x = 'middle' + i; + { + let x = 'inner' + j; + continue label; + } + } + assertEquals('outer', x); + } +} + +var c = true; + +function f32() { + { + let x = 'outer'; + L: { + { + let x = 'inner'; + if (c) { + break L; + } + } + foo(); + } + } + + function foo() { + return 'bar'; + } +} + +function f33() { + { + let x = 'outer'; + L: { + { + let x = 'inner'; + if (c) { + break L; + } + foo(); + } + } + } + + function foo() { + return 'bar'; + } +} + +function TestThrow() { + function f() { + let x = 'outer'; + { + let x = 'inner'; + throw x; + } + } + for (var i = 0; i < 5; i++) { + try { + f(); + } catch (e) { + assertEquals('inner', e); + } + } + %OptimizeFunctionOnNextCall(f); + try { + f(); + } catch (e) { + assertEquals('inner', e); + } + assertOptimized(f); +} + +TestThrow(); + +// Test that temporal dead zone semantics for function and block scoped +// let bindings are handled by the optimizing compiler. + +function TestFunctionLocal(s) { + 'use strict'; + var func = eval("(function baz(){" + s + "; })"); + print("Testing:"); + print(func); + for (var i = 0; i < 5; ++i) { + try { + func(); + assertUnreachable(); + } catch (e) { + assertInstanceof(e, ReferenceError); + } + } + %OptimizeFunctionOnNextCall(func); + try { + func(); + assertUnreachable(); + } catch (e) { + assertInstanceof(e, ReferenceError); + } +} + +function TestFunctionContext(s) { + 'use strict'; + var func = eval("(function baz(){ " + s + "; (function() { x; }); })"); + print("Testing:"); + print(func); + for (var i = 0; i < 5; ++i) { + print(i); + try { + func(); + assertUnreachable(); + } catch (e) { + assertInstanceof(e, ReferenceError); + } + } + print("optimize"); + %OptimizeFunctionOnNextCall(func); + try { + print("call"); + func(); + assertUnreachable(); + } catch (e) { + print("catch"); + assertInstanceof(e, ReferenceError); + } +} + +function TestBlockLocal(s) { + 'use strict'; + var func = eval("(function baz(){ { " + s + "; } })"); + print("Testing:"); + print(func); + for (var i = 0; i < 5; ++i) { + try { + func(); + assertUnreachable(); + } catch (e) { + assertInstanceof(e, ReferenceError); + } + } + %OptimizeFunctionOnNextCall(func); + try { + func(); + assertUnreachable(); + } catch (e) { + assertInstanceof(e, ReferenceError); + } +} + +function TestBlockContext(s) { + 'use strict'; + var func = eval("(function baz(){ { " + s + "; (function() { x; }); } })"); + print("Testing:"); + print(func); + for (var i = 0; i < 5; ++i) { + print(i); + try { + func(); + assertUnreachable(); + } catch (e) { + assertInstanceof(e, ReferenceError); + } + } + print("optimize"); + %OptimizeFunctionOnNextCall(func); + try { + print("call"); + func(); + assertUnreachable(); + } catch (e) { + print("catch"); + assertInstanceof(e, ReferenceError); + } +} + +function TestAll(s) { + TestFunctionLocal(s); + TestFunctionContext(s); + TestBlockLocal(s); + TestBlockContext(s); +} + +// Use before initialization in declaration statement. +TestAll('let x = x + 1'); +TestAll('let x = x += 1'); +TestAll('let x = x++'); +TestAll('let x = ++x'); +TestAll('const x = x + 1'); + +// Use before initialization in prior statement. +TestAll('x + 1; let x;'); +TestAll('x = 1; let x;'); +TestAll('x += 1; let x;'); +TestAll('++x; let x;'); +TestAll('x++; let x;'); +TestAll('let y = x; const x = 1;'); + + +function f(x) { + let y = x + 42; + return y; +} + +function g(x) { + { + let y = x + 42; + return y; + } +} + +for (var i=0; i<10; i++) { + f(i); + g(i); +} + +%OptimizeFunctionOnNextCall(f); +%OptimizeFunctionOnNextCall(g); + +f(12); +g(12); + +assertTrue(%GetOptimizationStatus(f) != 2); +assertTrue(%GetOptimizationStatus(g) != 2); diff --git a/deps/v8/test/mjsunit/es6/block-let-declaration-sloppy.js b/deps/v8/test/mjsunit/es6/block-let-declaration-sloppy.js new file mode 100644 index 0000000000..ea0e39bd07 --- /dev/null +++ b/deps/v8/test/mjsunit/es6/block-let-declaration-sloppy.js @@ -0,0 +1,172 @@ +// Copyright 2011 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. + +// Test let declarations in various settings. + +// Global +let x; +let y = 2; +const z = 4; +class c { static foo() { return 1; } } + +// Block local +{ + let y; + let x = 3; + const z = 5; + class c { static foo() { return 2; } } +} + +assertEquals(undefined, x); +assertEquals(2,y); +assertEquals(4,z); +assertEquals(1, c.foo()); + +if (true) { + let y; + assertEquals(undefined, y); +} + +// Invalid declarations are early errors in harmony mode and thus should trigger +// an exception in eval code during parsing, before even compiling or executing +// the code. Thus the generated function is not called here. +function TestLocalThrows(str, expect) { + assertThrows("(function(arg){ 'use strict'; " + str + "})", expect); +} + +function TestLocalDoesNotThrow(str) { + assertDoesNotThrow("(function(arg){ 'use strict'; " + str + "})()"); +} + +// Test let declarations in statement positions. +TestLocalThrows("if (true) let x;", SyntaxError); +TestLocalThrows("if (true) {} else let x;", SyntaxError); +TestLocalThrows("do let x; while (false)", SyntaxError); +TestLocalThrows("while (false) let x;", SyntaxError); +TestLocalThrows("label: let x;", SyntaxError); +TestLocalThrows("for (;false;) let x;", SyntaxError); +TestLocalDoesNotThrow("switch (true) { case true: let x; }"); +TestLocalDoesNotThrow("switch (true) { default: let x; }"); + +// Test const declarations with initialisers in statement positions. +TestLocalThrows("if (true) const x = 1;", SyntaxError); +TestLocalThrows("if (true) {} else const x = 1;", SyntaxError); +TestLocalThrows("do const x = 1; while (false)", SyntaxError); +TestLocalThrows("while (false) const x = 1;", SyntaxError); +TestLocalThrows("label: const x = 1;", SyntaxError); +TestLocalThrows("for (;false;) const x = 1;", SyntaxError); +TestLocalDoesNotThrow("switch (true) { case true: const x = 1; }"); +TestLocalDoesNotThrow("switch (true) { default: const x = 1; }"); + +// Test const declarations without initialisers. +TestLocalThrows("const x;", SyntaxError); +TestLocalThrows("const x = 1, y;", SyntaxError); +TestLocalThrows("const x, y = 1;", SyntaxError); + +// Test const declarations without initialisers in statement positions. +TestLocalThrows("if (true) const x;", SyntaxError); +TestLocalThrows("if (true) {} else const x;", SyntaxError); +TestLocalThrows("do const x; while (false)", SyntaxError); +TestLocalThrows("while (false) const x;", SyntaxError); +TestLocalThrows("label: const x;", SyntaxError); +TestLocalThrows("for (;false;) const x;", SyntaxError); +TestLocalThrows("switch (true) { case true: const x; }", SyntaxError); +TestLocalThrows("switch (true) { default: const x; }", SyntaxError); + +// Test var declarations in statement positions. +TestLocalDoesNotThrow("if (true) var x;"); +TestLocalDoesNotThrow("if (true) {} else var x;"); +TestLocalDoesNotThrow("do var x; while (false)"); +TestLocalDoesNotThrow("while (false) var x;"); +TestLocalDoesNotThrow("label: var x;"); +TestLocalDoesNotThrow("for (;false;) var x;"); +TestLocalDoesNotThrow("switch (true) { case true: var x; }"); +TestLocalDoesNotThrow("switch (true) { default: var x; }"); + +// Test class declarations with initialisers in statement positions. +TestLocalThrows("if (true) class x { };", SyntaxError); +TestLocalThrows("if (true) {} else class x { };", SyntaxError); +TestLocalThrows("do class x { }; while (false)", SyntaxError); +TestLocalThrows("while (false) class x { };", SyntaxError); +TestLocalThrows("label: class x { };", SyntaxError); +TestLocalThrows("for (;false;) class x { };", SyntaxError); +TestLocalDoesNotThrow("switch (true) { case true: class x { }; }"); +TestLocalDoesNotThrow("switch (true) { default: class x { }; }"); + +// Test that redeclarations of functions are only allowed in outermost scope. +TestLocalThrows("{ let f; var f; }"); +TestLocalThrows("{ var f; let f; }"); +TestLocalThrows("{ function f() {} let f; }"); +TestLocalThrows("{ let f; function f() {} }"); +TestLocalThrows("{ function f() {} var f; }"); +TestLocalThrows("{ var f; function f() {} }"); +TestLocalThrows("{ function f() {} class f {} }"); +TestLocalThrows("{ class f {}; function f() {} }"); +TestLocalThrows("{ function f() {} function f() {} }"); +TestLocalThrows("function f() {} let f;"); +TestLocalThrows("let f; function f() {}"); +TestLocalThrows("function f() {} class f {}"); +TestLocalThrows("class f {}; function f() {}"); +TestLocalDoesNotThrow("function arg() {}"); +TestLocalDoesNotThrow("function f() {} var f;"); +TestLocalDoesNotThrow("var f; function f() {}"); +TestLocalDoesNotThrow("function f() {} function f() {}"); + +function g(f) { + function f() { return 1 } + return f() +} +assertEquals(1, g(function() { return 2 })) + + +// Test function declarations in source element and +// sloppy statement positions. +function f() { + // Sloppy source element positions. + function g0() { + "use strict"; + // Strict source element positions. + function h() { } + { + function h1() { } + } + } + { + function g1() { } + } +} +f(); + +// Test function declarations in statement position in strict mode. +TestLocalThrows("function f() { if (true) function g() {} }", SyntaxError); +TestLocalThrows("function f() { if (true) {} else function g() {} }", SyntaxError); +TestLocalThrows("function f() { do function g() {} while (false) }", SyntaxError); +TestLocalThrows("function f() { while (false) function g() {} }", SyntaxError); +TestLocalThrows("function f() { label: function g() {} }", SyntaxError); +TestLocalThrows("function f() { for (;false;) function g() {} }", SyntaxError); +TestLocalDoesNotThrow("function f() { switch (true) { case true: function g() {} } }"); +TestLocalDoesNotThrow("function f() { switch (true) { default: function g() {} } }"); diff --git a/deps/v8/test/mjsunit/es6/block-let-semantics-sloppy.js b/deps/v8/test/mjsunit/es6/block-let-semantics-sloppy.js new file mode 100644 index 0000000000..4102ec8f5f --- /dev/null +++ b/deps/v8/test/mjsunit/es6/block-let-semantics-sloppy.js @@ -0,0 +1,191 @@ +// Copyright 2011 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. + +// Test temporal dead zone semantics of let bound variables in +// function and block scopes. + +function TestFunctionLocal(s) { + try { + eval("(function(){" + s + "; })")(); + } catch (e) { + assertInstanceof(e, ReferenceError); + return; + } + assertUnreachable(); +} + +function TestBlockLocal(s,e) { + try { + eval("(function(){ {" + s + ";} })")(); + } catch (e) { + assertInstanceof(e, ReferenceError); + return; + } + assertUnreachable(); +} + + +function TestAll(s) { + TestBlockLocal(s); + TestFunctionLocal(s); +} + +// Use before initialization in declaration statement. +TestAll('let x = x + 1'); +TestAll('let x = x += 1'); +TestAll('let x = x++'); +TestAll('let x = ++x'); +TestAll('const x = x + 1'); + +// Use before initialization in prior statement. +TestAll('x + 1; let x;'); +TestAll('x = 1; let x;'); +TestAll('x += 1; let x;'); +TestAll('++x; let x;'); +TestAll('x++; let x;'); +TestAll('let y = x; const x = 1;'); +TestAll('let y = x; class x {}'); + +TestAll('f(); let x; function f() { return x + 1; }'); +TestAll('f(); let x; function f() { x = 1; }'); +TestAll('f(); let x; function f() { x += 1; }'); +TestAll('f(); let x; function f() { ++x; }'); +TestAll('f(); let x; function f() { x++; }'); +TestAll('f(); const x = 1; function f() { return x; }'); +TestAll('f(); class x { }; function f() { return x; }'); + +TestAll('f()(); let x; function f() { return function() { return x + 1; } }'); +TestAll('f()(); let x; function f() { return function() { x = 1; } }'); +TestAll('f()(); let x; function f() { return function() { x += 1; } }'); +TestAll('f()(); let x; function f() { return function() { ++x; } }'); +TestAll('f()(); let x; function f() { return function() { x++; } }'); +TestAll('f()(); const x = 1; function f() { return function() { return x; } }'); +TestAll('f()(); class x { }; function f() { return function() { return x; } }'); + +for (var kw of ['let x = 2', 'const x = 2', 'class x { }']) { + // Use before initialization with a dynamic lookup. + TestAll(`eval("x"); ${kw};`); + TestAll(`eval("x + 1;"); ${kw};`); + TestAll(`eval("x = 1;"); ${kw};`); + TestAll(`eval("x += 1;"); ${kw};`); + TestAll(`eval("++x;"); ${kw};`); + TestAll(`eval("x++;"); ${kw};`); + + // Use before initialization with check for eval-shadowed bindings. + TestAll(`function f() { eval("var y = 2;"); x + 1; }; f(); ${kw};`); + TestAll(`function f() { eval("var y = 2;"); x = 1; }; f(); ${kw};`); + TestAll(`function f() { eval("var y = 2;"); x += 1; }; f(); ${kw};`); + TestAll(`function f() { eval("var y = 2;"); ++x; }; f(); ${kw};`); + TestAll(`function f() { eval("var y = 2;"); x++; }; f(); ${kw};`); +} + +// Test that variables introduced by function declarations are created and +// initialized upon entering a function / block scope. +function f() { + { + assertEquals(2, g1()); + assertEquals(2, eval("g1()")); + + // block scoped function declaration + function g1() { + return 2; + } + } + + assertEquals(3, g2()); + assertEquals(3, eval("g2()")); + // function scoped function declaration + function g2() { + return 3; + } +} +f(); + +// Test that a function declaration introduces a block scoped variable +// and no function hoisting if there is a conflict. +TestFunctionLocal('{ function k() { return 0; } }; k(); let k;'); + +// Test that a function declaration sees the scope it resides in. +function f2() { + let m, n, o, p; + { + m = g; + function g() { + return a; + } + let a = 1; + } + assertEquals(1, m()); + + try { + throw 2; + } catch(b) { + n = h; + function h() { + return b + c; + } + let c = 3; + } + assertEquals(5, n()); + + { + o = i; + function i() { + return d; + } + let d = 4; + } + assertEquals(4, o()); + + try { + throw 5; + } catch(e) { + p = j; + function j() { + return e + f; + } + let f = 6; + } + assertEquals(11, p()); +} +f2(); + +// Test that resolution of let bound variables works with scopes that call eval. +function outer() { + function middle() { + function inner() { + return x; + } + eval("1 + 1"); + return x + inner(); + } + + let x = 1; + return middle(); +} + +assertEquals(2, outer()); diff --git a/deps/v8/test/mjsunit/es6/block-non-strict-errors.js b/deps/v8/test/mjsunit/es6/block-non-strict-errors.js deleted file mode 100644 index db7f558905..0000000000 --- a/deps/v8/test/mjsunit/es6/block-non-strict-errors.js +++ /dev/null @@ -1,42 +0,0 @@ -// Copyright 2014 the V8 project authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -// Flags: --no-harmony-sloppy-let --no-harmony-sloppy-function -// Flags: --no-harmony-sloppy - -function CheckError(source) { - var exception = null; - try { - eval(source); - } catch (e) { - exception = e; - } - assertNotNull(exception); - assertEquals( - "Block-scoped declarations (let, const, function, class) not yet supported outside strict mode", - exception.message); -} - - -function CheckOk(source) { - eval(source); -} - -CheckError("let x = 1;"); -CheckError("{ let x = 1; }"); -CheckError("function f() { let x = 1; }"); -CheckError("for (let x = 1; x < 1; x++) {}"); -CheckError("for (let x of []) {}"); -CheckError("for (let x in []) {}"); -CheckError("class C {}"); -CheckError("class C extends Array {}"); -CheckError("(class {});"); -CheckError("(class extends Array {});"); -CheckError("(class C {});"); -CheckError("(class C exends Array {});"); - -CheckOk("let = 1;"); -CheckOk("{ let = 1; }"); -CheckOk("function f() { let = 1; }"); -CheckOk("for (let = 1; let < 1; let++) {}"); diff --git a/deps/v8/test/mjsunit/es6/block-scope-class.js b/deps/v8/test/mjsunit/es6/block-scope-class.js index 351feaa90e..7bbd49d338 100644 --- a/deps/v8/test/mjsunit/es6/block-scope-class.js +++ b/deps/v8/test/mjsunit/es6/block-scope-class.js @@ -4,8 +4,6 @@ // Test for conflicting variable bindings. -// Flags: --harmony-sloppy --harmony-sloppy-function - function AssertEqualsStrictAndSloppy(value, code) { assertEquals(value, eval("(function() {" + code + "})()")); assertEquals(value, eval("(function() { 'use strict'; " + code + "})()")); diff --git a/deps/v8/test/mjsunit/es6/block-scoping-sloppy.js b/deps/v8/test/mjsunit/es6/block-scoping-sloppy.js new file mode 100644 index 0000000000..f5c5a6326b --- /dev/null +++ b/deps/v8/test/mjsunit/es6/block-scoping-sloppy.js @@ -0,0 +1,309 @@ +// Copyright 2011 the V8 project authors. All rights reserved. +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following +// disclaimer in the documentation and/or other materials provided +// with the distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Flags: --allow-natives-syntax +// Test functionality of block scopes. + +// Hoisting of var declarations. +function f1() { + { + var x = 1; + var y; + } + assertEquals(1, x) + assertEquals(undefined, y) +} +for (var j = 0; j < 5; ++j) f1(); +%OptimizeFunctionOnNextCall(f1); +f1(); +assertTrue(%GetOptimizationStatus(f1) != 2); + +// Dynamic lookup in and through block contexts. +function f2(one) { + var x = one + 1; + let y = one + 2; + const u = one + 4; + class a { static foo() { return one + 6; } } + { + let z = one + 3; + const v = one + 5; + class b { static foo() { return one + 7; } } + assertEquals(1, eval('one')); + assertEquals(2, eval('x')); + assertEquals(3, eval('y')); + assertEquals(4, eval('z')); + assertEquals(5, eval('u')); + assertEquals(6, eval('v')); + assertEquals(7, eval('a.foo()')); + assertEquals(8, eval('b.foo()')); + } +} + +f2(1); + +// Lookup in and through block contexts. +function f3(one) { + var x = one + 1; + let y = one + 2; + const u = one + 4; + class a { static foo() { return one + 6; } } + { + let z = one + 3; + const v = one + 5; + class b { static foo() { return one + 7; } } + assertEquals(1, one); + assertEquals(2, x); + assertEquals(3, y); + assertEquals(4, z); + assertEquals(5, u); + assertEquals(6, v); + assertEquals(7, a.foo()); + assertEquals(8, b.foo()); + } +} +for (var j = 0; j < 5; ++j) f3(1); +%OptimizeFunctionOnNextCall(f3); +f3(1); + + + +// Dynamic lookup from closure. +function f4(one) { + var x = one + 1; + let y = one + 2; + const u = one + 4; + class a { static foo() { return one + 6; } } + { + let z = one + 3; + const v = one + 5; + class b { static foo() { return one + 7; } } + function f() { + assertEquals(1, eval('one')); + assertEquals(2, eval('x')); + assertEquals(3, eval('y')); + assertEquals(4, eval('z')); + assertEquals(5, eval('u')); + assertEquals(6, eval('v')); + assertEquals(7, eval('a.foo()')); + assertEquals(8, eval('b.foo()')); + } + f(); + } +} +f4(1); + + +// Lookup from closure. +function f5(one) { + var x = one + 1; + let y = one + 2; + const u = one + 4; + class a { static foo() { return one + 6; } } + { + let z = one + 3; + const v = one + 5; + class b { static foo() { return one + 7; } } + function f() { + assertEquals(1, one); + assertEquals(2, x); + assertEquals(3, y); + assertEquals(4, z); + assertEquals(5, u); + assertEquals(6, v); + assertEquals(7, a.foo()); + assertEquals(8, b.foo()); + } + f(); + } +} +f5(1); + + +// Return from block. +function f6() { + let x = 1; + const u = 3; + { + let y = 2; + const v = 4; + return x + y; + } +} +assertEquals(3, f6(6)); + + +// Variable shadowing and lookup. +function f7(a) { + let b = 1; + var c = 1; + var d = 1; + const e = 1; + class f { static foo() { return 1; } } + { // let variables shadowing argument, let, const, class and var variables + let a = 2; + let b = 2; + let c = 2; + let e = 2; + let f = 2; + assertEquals(2,a); + assertEquals(2,b); + assertEquals(2,c); + assertEquals(2,e); + assertEquals(2,f); + } + { // const variables shadowing argument, let, const and var variables + const a = 2; + const b = 2; + const c = 2; + const e = 2; + const f = 2; + assertEquals(2,a); + assertEquals(2,b); + assertEquals(2,c); + assertEquals(2,e); + assertEquals(2,f); + } + { // class variables shadowing argument, let, const and var variables + class a { static foo() { return 2; } } + class b { static foo() { return 2; } } + class c { static foo() { return 2; } } + class d { static foo() { return 2; } } + class e { static foo() { return 2; } } + class f { static foo() { return 2; } } + assertEquals(2,a.foo()); + assertEquals(2,b.foo()); + assertEquals(2,c.foo()); + assertEquals(2,e.foo()); + assertEquals(2,f.foo()); + } + try { + throw 'stuff1'; + } catch (a) { + assertEquals('stuff1',a); + // catch variable shadowing argument + a = 2; + assertEquals(2,a); + { + // let variable shadowing catch variable + let a = 3; + assertEquals(3,a); + try { + throw 'stuff2'; + } catch (a) { + assertEquals('stuff2',a); + // catch variable shadowing let variable + a = 4; + assertEquals(4,a); + } + assertEquals(3,a); + } + assertEquals(2,a); + } + try { + throw 'stuff3'; + } catch (c) { + // catch variable shadowing var variable + assertEquals('stuff3',c); + { + // const variable shadowing catch variable + const c = 3; + assertEquals(3,c); + } + assertEquals('stuff3',c); + try { + throw 'stuff4'; + } catch(c) { + assertEquals('stuff4',c); + // catch variable shadowing catch variable + c = 3; + assertEquals(3,c); + } + (function(c) { + // argument shadowing catch variable + c = 3; + assertEquals(3,c); + })(); + assertEquals('stuff3', c); + (function() { + // var variable shadowing catch variable + var c = 3; + })(); + assertEquals('stuff3', c); + c = 2; + } + assertEquals(1,c); + (function(a,b,c,e,f) { + // arguments shadowing argument, let, const, class and var variable + a = 2; + b = 2; + c = 2; + e = 2; + f = 2; + assertEquals(2,a); + assertEquals(2,b); + assertEquals(2,c); + assertEquals(2,e); + assertEquals(2,f); + // var variable shadowing var variable + var d = 2; + })(1,1); + assertEquals(1,a); + assertEquals(1,b); + assertEquals(1,c); + assertEquals(1,d); + assertEquals(1,e); + assertEquals(1,f.foo()); +} +f7(1); + + +// Ensure let and const variables are block local +// and var variables function local. +function f8() { + var let_accessors = []; + var var_accessors = []; + var const_accessors = []; + var class_accessors = []; + for (var i = 0; i < 10; i++) { + let x = i; + var y = i; + const z = i; + class a { static foo() { return x; } } + let_accessors[i] = function() { return x; } + var_accessors[i] = function() { return y; } + const_accessors[i] = function() { return z; } + class_accessors[i] = function() { return a; } + } + for (var j = 0; j < 10; j++) { + y = j + 10; + assertEquals(j, let_accessors[j]()); + assertEquals(y, var_accessors[j]()); + assertEquals(j, const_accessors[j]()); + assertEquals(j, class_accessors[j]().foo()); + } +} +f8(); diff --git a/deps/v8/test/mjsunit/es6/block-scoping-top-level-sloppy.js b/deps/v8/test/mjsunit/es6/block-scoping-top-level-sloppy.js new file mode 100644 index 0000000000..2a3b903f9e --- /dev/null +++ b/deps/v8/test/mjsunit/es6/block-scoping-top-level-sloppy.js @@ -0,0 +1,33 @@ +// Copyright 2015 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Flags: --min-preparse-length=0 + +let xxx = 1; +let f = undefined; +{ + let inner_x = xxx; + f = function() { return inner_x; }; +} + +assertSame(1, f()); + +xxx = 42; +{ + f = function() { return inner_x1; }; + let inner_x1 = xxx; +} + +assertSame(42, f()); + +xxx = 31; +{ + let inner_x1 = xxx; + try { + throw new Error(); + } catch (e) { + f = function() { return inner_x1; }; + } +} +assertSame(31, f()); diff --git a/deps/v8/test/mjsunit/es6/block-sloppy-function.js b/deps/v8/test/mjsunit/es6/block-sloppy-function.js new file mode 100644 index 0000000000..8cb9a4deda --- /dev/null +++ b/deps/v8/test/mjsunit/es6/block-sloppy-function.js @@ -0,0 +1,656 @@ +// 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 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()); + `); +}(); + +// This test is incorrect BUG(v8:5168). The commented assertions are correct. +(function evalHoistingThroughSimpleCatch() { + try { + throw 0; + } catch (f) { + eval(`{ function f() { + return 4; + } }`); + + // assertEquals(0, f); + assertEquals(4, f()); + } + + // assertEquals(4, f()); + assertEquals(undefined, f); +})(); + +// This test is incorrect BUG(v8:5168). The commented assertions are correct. +(function evalHoistingThroughWith() { + with ({f: 0}) { + eval(`{ function f() { + return 4; + } }`); + + // assertEquals(0, f); + assertEquals(4, f()); + } + + // assertEquals(4, f()); + assertEquals(undefined, 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/deps/v8/test/mjsunit/es6/catch-parameter-redeclaration.js b/deps/v8/test/mjsunit/es6/catch-parameter-redeclaration.js new file mode 100644 index 0000000000..0f8f9c86e7 --- /dev/null +++ b/deps/v8/test/mjsunit/es6/catch-parameter-redeclaration.js @@ -0,0 +1,112 @@ +// Copyright 2016 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +function checkIsRedeclarationError(code) { + try { + eval(` +checkIsRedeclarationError : { + break checkIsRedeclarationError; +${code} +} +`); + assertUnreachable(); + } catch(e) { + assertInstanceof(e, SyntaxError ); + assertTrue( e.toString().indexOf("has already been declared") >= 0 ); + } +} + +function checkIsNotRedeclarationError(code) { + assertDoesNotThrow(()=>eval(` +checkIsNotRedeclarationError_label : { + break checkIsNotRedeclarationError_label; +${code} +} +`)); +} + + +let lexical_e = [ + 'let e', + 'let f, g, e', + 'let [f] = [], [] = [], e = e, h', + 'let {e} = 0', + 'let {f, e} = 0', + 'let {f, g} = 0, {e} = 0', + 'let {f = 0, e = 1} = 0', + 'let [e] = 0', + 'let [f, e] = 0', + 'let {f:e} = 0', + 'let [[[], e]] = 0', + 'const e = 0', + 'const f = 0, g = 0, e = 0', + 'const {e} = 0', + 'const [e] = 0', + 'const {f:e} = 0', + 'const [[[], e]] = 0', + 'function e(){}', + 'function* e(){}', +]; + +let not_lexical_e = [ + 'var e', + 'var f, e', + 'var {e} = 0', + 'let {} = 0', + 'let {e:f} = 0', + '{ function e(){} }' +]; + +// Check that lexical declarations cannot override a simple catch parameter +for (let declaration of lexical_e) { + checkIsRedeclarationError(` +try { + throw 0; +} catch(e) { + ${declaration} +} +`); +} + +// Check that lexical declarations cannot override a complex catch parameter +for (let declaration of lexical_e) { + checkIsRedeclarationError(` +try { + throw 0; +} catch({e}) { + ${declaration} +} +`); +} + +// Check that non-lexical declarations can override a simple catch parameter +for (let declaration of not_lexical_e) { + checkIsNotRedeclarationError(` +try { + throw 0; +} catch(e) { + ${declaration} +} +`); +} + +// Check that the above error does not occur if a declaration scope is between +// the catch and the loop. +for (let declaration of lexical_e) { + checkIsNotRedeclarationError(` +try { + throw 0; +} catch(e) { + (()=>{${declaration}})(); +} +`); + + checkIsNotRedeclarationError(` +try { + throw 0; +} catch(e) { + (function(){${declaration}})(); +} +`); +} diff --git a/deps/v8/test/mjsunit/es6/class-computed-property-names-super.js b/deps/v8/test/mjsunit/es6/class-computed-property-names-super.js index cb9f25157c..b5a2ac995e 100644 --- a/deps/v8/test/mjsunit/es6/class-computed-property-names-super.js +++ b/deps/v8/test/mjsunit/es6/class-computed-property-names-super.js @@ -2,7 +2,6 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// Flags: --harmony-sloppy // Flags: --allow-natives-syntax diff --git a/deps/v8/test/mjsunit/es6/class-property-name-eval-arguments.js b/deps/v8/test/mjsunit/es6/class-property-name-eval-arguments.js index 72ff60fd3e..bbd05cc355 100644 --- a/deps/v8/test/mjsunit/es6/class-property-name-eval-arguments.js +++ b/deps/v8/test/mjsunit/es6/class-property-name-eval-arguments.js @@ -2,8 +2,6 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// Flags: --harmony-sloppy - (function Method() { class C { diff --git a/deps/v8/test/mjsunit/es6/classes-derived-return-type.js b/deps/v8/test/mjsunit/es6/classes-derived-return-type.js index 8283bcb227..3f81a340ff 100644 --- a/deps/v8/test/mjsunit/es6/classes-derived-return-type.js +++ b/deps/v8/test/mjsunit/es6/classes-derived-return-type.js @@ -2,8 +2,6 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// Flags: --harmony-sloppy - class Base {} diff --git a/deps/v8/test/mjsunit/es6/classes-subclass-builtins.js b/deps/v8/test/mjsunit/es6/classes-subclass-builtins.js index 7669ef3a8a..dca514c294 100644 --- a/deps/v8/test/mjsunit/es6/classes-subclass-builtins.js +++ b/deps/v8/test/mjsunit/es6/classes-subclass-builtins.js @@ -2,8 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// Flags: --allow-natives-syntax --harmony-regexp-subclass -// Flags: --expose-gc +// Flags: --allow-natives-syntax --expose-gc "use strict"; diff --git a/deps/v8/test/mjsunit/es6/classes.js b/deps/v8/test/mjsunit/es6/classes.js index 4dabda8e44..fb77dbb8e4 100644 --- a/deps/v8/test/mjsunit/es6/classes.js +++ b/deps/v8/test/mjsunit/es6/classes.js @@ -2,8 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// Flags: --harmony-sloppy --harmony-function-name --allow-natives-syntax -// Flags: --harmony-do-expressions +// Flags: --allow-natives-syntax --harmony-do-expressions (function TestBasics() { var C = class C {} diff --git a/deps/v8/test/mjsunit/es6/completion.js b/deps/v8/test/mjsunit/es6/completion.js index 7559514421..988e9709bb 100644 --- a/deps/v8/test/mjsunit/es6/completion.js +++ b/deps/v8/test/mjsunit/es6/completion.js @@ -2,8 +2,6 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// Flags: --harmony-sloppy-let - function assertUndef(x) { assertEquals(undefined, x); diff --git a/deps/v8/test/mjsunit/es6/debug-blockscopes.js b/deps/v8/test/mjsunit/es6/debug-blockscopes.js index 193ad705cb..bf04a0a4aa 100644 --- a/deps/v8/test/mjsunit/es6/debug-blockscopes.js +++ b/deps/v8/test/mjsunit/es6/debug-blockscopes.js @@ -52,6 +52,7 @@ function listener(event, exec_state, event_data, data) { listener_delegate(exec_state); } } catch (e) { + print(e, e.stack); exception = e; } } @@ -147,10 +148,8 @@ function CheckScopeContent(content, number, exec_state) { if (!scope.scopeObject().property('arguments').isUndefined()) { scope_size--; } - // Skip property with empty name. - if (!scope.scopeObject().property('').isUndefined()) { - scope_size--; - } + // Temporary variables introduced by the parser have not been materialized. + assertTrue(scope.scopeObject().property('').isUndefined()); if (count != scope_size) { print('Names found in scope:'); @@ -380,16 +379,12 @@ function for_loop_1() { listener_delegate = function(exec_state) { CheckScopeChain([debug.ScopeType.Block, - debug.ScopeType.Block, debug.ScopeType.Local, debug.ScopeType.Script, debug.ScopeType.Global], exec_state); CheckScopeContent({x:'y'}, 0, exec_state); // The function scope contains a temporary iteration variable, but it is // hidden to the debugger. - // TODO(adamk): This variable is only used to provide a TDZ for the enumerable - // expression and should not be visible to the debugger. - CheckScopeContent({x:undefined}, 1, exec_state); }; for_loop_1(); EndTest(); @@ -409,7 +404,6 @@ function for_loop_2() { listener_delegate = function(exec_state) { CheckScopeChain([debug.ScopeType.Block, debug.ScopeType.Block, - debug.ScopeType.Block, debug.ScopeType.Local, debug.ScopeType.Script, debug.ScopeType.Global], exec_state); @@ -417,9 +411,6 @@ listener_delegate = function(exec_state) { CheckScopeContent({x:'y'}, 1, exec_state); // The function scope contains a temporary iteration variable, hidden to the // debugger. - // TODO(adamk): This variable is only used to provide a TDZ for the enumerable - // expression and should not be visible to the debugger. - CheckScopeContent({x:undefined}, 2, exec_state); }; for_loop_2(); EndTest(); @@ -436,13 +427,11 @@ function for_loop_3() { listener_delegate = function(exec_state) { CheckScopeChain([debug.ScopeType.Block, - debug.ScopeType.Block, debug.ScopeType.Local, debug.ScopeType.Script, debug.ScopeType.Global], exec_state); CheckScopeContent({x:3}, 0, exec_state); - CheckScopeContent({x:3}, 1, exec_state); - CheckScopeContent({}, 2, exec_state); + CheckScopeContent({}, 1, exec_state); }; for_loop_3(); EndTest(); @@ -461,14 +450,12 @@ function for_loop_4() { listener_delegate = function(exec_state) { CheckScopeChain([debug.ScopeType.Block, debug.ScopeType.Block, - debug.ScopeType.Block, debug.ScopeType.Local, debug.ScopeType.Script, debug.ScopeType.Global], exec_state); CheckScopeContent({x:5}, 0, exec_state); CheckScopeContent({x:3}, 1, exec_state); - CheckScopeContent({x:3}, 2, exec_state); - CheckScopeContent({}, 3, exec_state); + CheckScopeContent({}, 2, exec_state); }; for_loop_4(); EndTest(); @@ -485,13 +472,11 @@ function for_loop_5() { listener_delegate = function(exec_state) { CheckScopeChain([debug.ScopeType.Block, - debug.ScopeType.Block, debug.ScopeType.Local, debug.ScopeType.Script, debug.ScopeType.Global], exec_state); CheckScopeContent({x:3,y:5}, 0, exec_state); - CheckScopeContent({x:3,y:5}, 1, exec_state); - CheckScopeContent({}, 2, exec_state); + CheckScopeContent({}, 1, exec_state); }; for_loop_5(); EndTest(); diff --git a/deps/v8/test/mjsunit/es6/debug-exception-generators.js b/deps/v8/test/mjsunit/es6/debug-exception-generators.js new file mode 100644 index 0000000000..b2e7e82964 --- /dev/null +++ b/deps/v8/test/mjsunit/es6/debug-exception-generators.js @@ -0,0 +1,49 @@ +// Copyright 2016 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Flags: --expose-debug-as debug + +Debug = debug.Debug + +var exception = null; +var log = []; + +function listener(event, exec_state, event_data, data) { + if (event != Debug.DebugEvent.Exception) return; + try { + var line = exec_state.frame(0).sourceLineText(); + var match = /Exception (\w)/.exec(line); + assertNotNull(match); + assertEquals(match[1], event_data.exception()); + log.push(match[1]); + } catch (e) { + exception = e; + } +} + + +function* g() { + try { + throw "a"; // Ordinary throw. Exception a + } catch (e) {} + try { + yield 1; // Caught internally. Exception b + } catch (e) {} + yield 2; + yield 3; // Caught externally. Exception c + yield 4; +} + +Debug.setListener(listener); +Debug.setBreakOnException(); +var g_obj = g(); +assertEquals(1, g_obj.next().value); +assertEquals(2, g_obj.throw("b").value); +assertEquals(3, g_obj.next().value); +assertThrows(() => g_obj.throw("c")); +assertThrows(() => g_obj.throw("d")); // Closed generator. Exception d +Debug.setListener(null); +Debug.clearBreakOnException(); +assertEquals(["a", "b", "c", "d"], log); +assertNull(exception); diff --git a/deps/v8/test/mjsunit/es6/debug-promises/async-task-event.js b/deps/v8/test/mjsunit/es6/debug-promises/async-task-event.js index 88030a2e73..0b0fa1e64f 100644 --- a/deps/v8/test/mjsunit/es6/debug-promises/async-task-event.js +++ b/deps/v8/test/mjsunit/es6/debug-promises/async-task-event.js @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// Flags: --expose-debug-as debug +// Flags: --expose-debug-as debug --allow-natives-syntax Debug = debug.Debug; @@ -16,8 +16,8 @@ var expected = [ "didHandle #1", "willHandle #2", "then #2", - "enqueue #3", "didHandle #2", + "enqueue #3", "willHandle #3", "didHandle #3" ]; @@ -58,4 +58,6 @@ p.then(function() { }); resolver(); +%RunMicrotasks(); + assertNull(exception); diff --git a/deps/v8/test/mjsunit/es6/debug-promises/evaluate-across-microtasks.js b/deps/v8/test/mjsunit/es6/debug-promises/evaluate-across-microtasks.js new file mode 100644 index 0000000000..73718eec7b --- /dev/null +++ b/deps/v8/test/mjsunit/es6/debug-promises/evaluate-across-microtasks.js @@ -0,0 +1,66 @@ +// Copyright 2014 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Flags: --expose-debug-as debug --allow-natives-syntax + +var Debug = debug.Debug; +var listenerComplete = false; +var exception = null; +var count = 0; +var log = []; +var done = false; + +function LogX(x) { + var stored_count = count; + return function() { + log.push(`[${stored_count}] ${x}`); + }; +} + +function DebuggerStatement() { + log.push(`[${count}] debugger`); + if (count++ < 3) { + debugger; + } +} + +function listener(event, exec_state, event_data, data) { + if (event != Debug.DebugEvent.Break) return; + try { + var p = Promise.resolve(); + var q = p.then(LogX("then 1")); + p.then(LogX("then 2")); + q.then(LogX("then 3")); + q.then(DebuggerStatement); + var r = q.then(() => { throw 1; }); + r.catch(LogX("catch")); + listenerComplete = true; + } catch (e) { + exception = e; + print(e, e.stack); + quit(1); + }; +}; + +// Add the debug event listener. +Debug.setListener(listener); + +DebuggerStatement(); +LogX("start")(); + +// Make sure that the debug event listener was invoked. +assertTrue(listenerComplete); + +%RunMicrotasks(); + +var expectation = + [ "[0] debugger", "[1] start", "[1] then 1", + "[1] then 2", "[1] then 3", "[1] debugger", + "[2] then 1", "[2] then 2", "[1] catch", + "[2] then 3", "[2] debugger", "[3] then 1", + "[3] then 2", "[2] catch", "[3] then 3", + "[3] debugger", "[3] catch", + ]; + +assertEquals(expectation, log); diff --git a/deps/v8/test/mjsunit/es6/debug-promises/events.js b/deps/v8/test/mjsunit/es6/debug-promises/events.js deleted file mode 100644 index 3fcb22ff27..0000000000 --- a/deps/v8/test/mjsunit/es6/debug-promises/events.js +++ /dev/null @@ -1,122 +0,0 @@ -// Copyright 2014 the V8 project authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -// Flags: --allow-natives-syntax --expose-debug-as debug - -Debug = debug.Debug; - -var eventsExpected = 16; -var exception = null; -var result = []; - -function updatePromise(promise, parentPromise, status, value) { - var i; - for (i = 0; i < result.length; ++i) { - if (result[i].promise === promise) { - result[i].parentPromise = parentPromise || result[i].parentPromise; - result[i].status = status || result[i].status; - result[i].value = value || result[i].value; - break; - } - } - assertTrue(i < result.length); -} - -function listener(event, exec_state, event_data, data) { - if (event != Debug.DebugEvent.PromiseEvent) return; - try { - eventsExpected--; - assertTrue(event_data.promise().isPromise()); - if (event_data.status() === 0) { - // New promise. - assertEquals("pending", event_data.promise().status()); - result.push({ promise: event_data.promise().value(), status: 0 }); - assertTrue(exec_state.frame(0).sourceLineText().indexOf("// event") > 0); - } else if (event_data.status() !== undefined) { - // Resolve/reject promise. - updatePromise(event_data.promise().value(), - undefined, - event_data.status(), - event_data.value().value()); - } else { - // Chain promises. - assertTrue(event_data.parentPromise().isPromise()); - updatePromise(event_data.promise().value(), - event_data.parentPromise().value()); - assertTrue(exec_state.frame(0).sourceLineText().indexOf("// event") > 0); - } - } catch (e) { - print(e + e.stack) - exception = e; - } -} - -Debug.setListener(listener); - -function resolver(resolve, reject) { resolve(); } - -var p1 = new Promise(resolver); // event -var p2 = p1.then().then(); // event -var p3 = new Promise(function(resolve, reject) { // event - reject("rejected"); -}); -var p4 = p3.then(); // event -var p5 = p1.then(); // event - -function assertAsync(b, s) { - if (b) { - print(s, "succeeded"); - } else { - %AbortJS(s + " FAILED!"); - } -} - -function testDone(iteration) { - function checkResult() { - if (eventsExpected === 0) { - assertAsync(result.length === 6, "result.length"); - - assertAsync(result[0].promise === p1, "result[0].promise"); - assertAsync(result[0].parentPromise === undefined, - "result[0].parentPromise"); - assertAsync(result[0].status === 1, "result[0].status"); - assertAsync(result[0].value === undefined, "result[0].value"); - - assertAsync(result[1].parentPromise === p1, - "result[1].parentPromise"); - assertAsync(result[1].status === 1, "result[1].status"); - - assertAsync(result[2].promise === p2, "result[2].promise"); - - assertAsync(result[3].promise === p3, "result[3].promise"); - assertAsync(result[3].parentPromise === undefined, - "result[3].parentPromise"); - assertAsync(result[3].status === -1, "result[3].status"); - assertAsync(result[3].value === "rejected", "result[3].value"); - - assertAsync(result[4].promise === p4, "result[4].promise"); - assertAsync(result[4].parentPromise === p3, - "result[4].parentPromise"); - assertAsync(result[4].status === -1, "result[4].status"); - assertAsync(result[4].value === "rejected", "result[4].value"); - - assertAsync(result[5].promise === p5, "result[5].promise"); - assertAsync(result[5].parentPromise === p1, - "result[5].parentPromise"); - assertAsync(result[5].status === 1, "result[5].status"); - - assertAsync(exception === null, "exception === null"); - Debug.setListener(null); - } else if (iteration > 10) { - %AbortJS("Not all events were received!"); - } else { - testDone(iteration + 1); - } - } - - var iteration = iteration || 0; - %EnqueueMicrotask(checkResult); -} - -testDone(); diff --git a/deps/v8/test/mjsunit/es6/debug-promises/reentry.js b/deps/v8/test/mjsunit/es6/debug-promises/reentry.js index a97ce81012..cc98ed9efd 100644 --- a/deps/v8/test/mjsunit/es6/debug-promises/reentry.js +++ b/deps/v8/test/mjsunit/es6/debug-promises/reentry.js @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// Flags: --expose-debug-as debug --promise-extra +// Flags: --expose-debug-as debug // Test reentry of special try catch for Promises. @@ -12,6 +12,6 @@ Debug.setBreakOnUncaughtException(); Debug.setListener(function(event, exec_state, event_data, data) { }); var p = new Promise(function(resolve, reject) { resolve(); }); -var q = p.chain(function() { +var q = p.then(function() { new Promise(function(resolve, reject) { resolve(); }); }); diff --git a/deps/v8/test/mjsunit/es6/debug-promises/reject-after-resolve.js b/deps/v8/test/mjsunit/es6/debug-promises/reject-after-resolve.js index ed4b2c435e..5ec2da50e9 100644 --- a/deps/v8/test/mjsunit/es6/debug-promises/reject-after-resolve.js +++ b/deps/v8/test/mjsunit/es6/debug-promises/reject-after-resolve.js @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// Flags: --expose-debug-as debug --allow-natives-syntax --promise-extra +// Flags: --expose-debug-as debug --allow-natives-syntax // Test debug events when we listen to uncaught exceptions and // the Promise is rejected in a chained closure after it has been resolved. @@ -17,7 +17,7 @@ var p = new Promise(function(resolve, reject) { resolve(reject); }); -var q = p.chain( +var q = p.then( function(value) { assertEquals(["resolve", "end main"], log); value(new Error("reject")); diff --git a/deps/v8/test/mjsunit/es6/debug-promises/reject-caught-all.js b/deps/v8/test/mjsunit/es6/debug-promises/reject-caught-all.js index e1a653889d..8d348ce6b6 100644 --- a/deps/v8/test/mjsunit/es6/debug-promises/reject-caught-all.js +++ b/deps/v8/test/mjsunit/es6/debug-promises/reject-caught-all.js @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// Flags: --expose-debug-as debug --allow-natives-syntax --promise-extra +// Flags: --expose-debug-as debug --allow-natives-syntax // Test debug events when we listen to all exceptions and // there is a catch handler for the to-be-rejected Promise. @@ -18,7 +18,7 @@ var p = new Promise(function(resolve, reject) { resolve(); }); -var q = p.chain( +var q = p.then( function(value) { log.push("reject"); return Promise.reject(new Error("reject")); diff --git a/deps/v8/test/mjsunit/es6/debug-promises/reject-caught-late.js b/deps/v8/test/mjsunit/es6/debug-promises/reject-caught-late.js index 922449261b..44eb76728f 100644 --- a/deps/v8/test/mjsunit/es6/debug-promises/reject-caught-late.js +++ b/deps/v8/test/mjsunit/es6/debug-promises/reject-caught-late.js @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// Flags: --expose-debug-as debug --allow-natives-syntax --promise-extra +// Flags: --expose-debug-as debug --allow-natives-syntax // Test debug events when we only listen to uncaught exceptions, the Promise // is rejected, and a catch handler is installed right before the rejection. @@ -14,7 +14,7 @@ var p = new Promise(function(resolve, reject) { resolve(); }); -var q = p.chain( +var q = p.then( function() { q.catch(function(e) { assertEquals("caught", e.message); diff --git a/deps/v8/test/mjsunit/es6/debug-promises/reject-caught-uncaught.js b/deps/v8/test/mjsunit/es6/debug-promises/reject-caught-uncaught.js index afb46fea8f..b2fe8b0a45 100644 --- a/deps/v8/test/mjsunit/es6/debug-promises/reject-caught-uncaught.js +++ b/deps/v8/test/mjsunit/es6/debug-promises/reject-caught-uncaught.js @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// Flags: --expose-debug-as debug --allow-natives-syntax --promise-extra +// Flags: --expose-debug-as debug --allow-natives-syntax // Test debug events when we only listen to uncaught exceptions and // there is a catch handler for the to-be-rejected Promise. @@ -14,7 +14,7 @@ var p = new Promise(function(resolve, reject) { resolve(); }); -var q = p.chain( +var q = p.then( function() { return Promise.reject(Error("caught reject")); }); diff --git a/deps/v8/test/mjsunit/es6/debug-promises/reject-uncaught-all.js b/deps/v8/test/mjsunit/es6/debug-promises/reject-uncaught-all.js index 63e3b8678d..0c5ecc5f3a 100644 --- a/deps/v8/test/mjsunit/es6/debug-promises/reject-uncaught-all.js +++ b/deps/v8/test/mjsunit/es6/debug-promises/reject-uncaught-all.js @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// Flags: --expose-debug-as debug --allow-natives-syntax --promise-extra +// Flags: --expose-debug-as debug --allow-natives-syntax // Test debug events when we listen to all exceptions and // there is a catch handler for the to-be-rejected Promise. @@ -18,7 +18,7 @@ var p = new Promise(function(resolve, reject) { resolve(); }); -var q = p.chain( +var q = p.then( function() { log.push("reject"); return Promise.reject(new Error("uncaught reject")); diff --git a/deps/v8/test/mjsunit/es6/debug-promises/reject-uncaught-uncaught.js b/deps/v8/test/mjsunit/es6/debug-promises/reject-uncaught-uncaught.js index b542bc69dd..e5e560b3db 100644 --- a/deps/v8/test/mjsunit/es6/debug-promises/reject-uncaught-uncaught.js +++ b/deps/v8/test/mjsunit/es6/debug-promises/reject-uncaught-uncaught.js @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// Flags: --expose-debug-as debug --allow-natives-syntax --promise-extra +// Flags: --expose-debug-as debug --allow-natives-syntax // Test debug events when we only listen to uncaught exceptions and // there is no catch handler for the to-be-rejected Promise. @@ -18,7 +18,7 @@ var p = new Promise(function(resolve, reject) { resolve(); }); -var q = p.chain( +var q = p.then( function() { log.push("reject"); return Promise.reject(Error("uncaught reject")); // event diff --git a/deps/v8/test/mjsunit/es6/debug-promises/reject-with-invalid-reject.js b/deps/v8/test/mjsunit/es6/debug-promises/reject-with-invalid-reject.js index 8775df687d..6aaf882ce8 100644 --- a/deps/v8/test/mjsunit/es6/debug-promises/reject-with-invalid-reject.js +++ b/deps/v8/test/mjsunit/es6/debug-promises/reject-with-invalid-reject.js @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// Flags: --expose-debug-as debug --allow-natives-syntax --promise-extra +// Flags: --expose-debug-as debug --allow-natives-syntax // Test debug events when a Promise is rejected, which is caught by a custom // promise, which has a number for reject closure. We expect an Exception debug @@ -28,7 +28,7 @@ function MyPromise(resolver) { MyPromise.prototype = new Promise(function() {}); p.constructor = MyPromise; -var q = p.chain( +var q = p.then( function() { log.push("reject caught"); return Promise.reject(new Error("caught")); diff --git a/deps/v8/test/mjsunit/es6/debug-promises/reject-with-throw-in-reject.js b/deps/v8/test/mjsunit/es6/debug-promises/reject-with-throw-in-reject.js index b6c06df49e..47e335d968 100644 --- a/deps/v8/test/mjsunit/es6/debug-promises/reject-with-throw-in-reject.js +++ b/deps/v8/test/mjsunit/es6/debug-promises/reject-with-throw-in-reject.js @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// Flags: --expose-debug-as debug --allow-natives-syntax --promise-extra +// Flags: --expose-debug-as debug --allow-natives-syntax // Test debug events when a Promise is rejected, which is caught by a // custom promise, which throws a new exception in its reject handler. @@ -33,7 +33,7 @@ function MyPromise(resolver) { MyPromise.prototype = new Promise(function() {}); p.constructor = MyPromise; -var q = p.chain( +var q = p.then( function() { log.push("reject caught"); return Promise.reject(new Error("caught")); diff --git a/deps/v8/test/mjsunit/es6/debug-promises/reject-with-undefined-reject.js b/deps/v8/test/mjsunit/es6/debug-promises/reject-with-undefined-reject.js index d058d41b96..1595372396 100644 --- a/deps/v8/test/mjsunit/es6/debug-promises/reject-with-undefined-reject.js +++ b/deps/v8/test/mjsunit/es6/debug-promises/reject-with-undefined-reject.js @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// Flags: --expose-debug-as debug --allow-natives-syntax --promise-extra +// Flags: --expose-debug-as debug --allow-natives-syntax // Test debug events when a Promise is rejected, which is caught by a custom // promise, which has undefined for reject closure. We expect an Exception @@ -28,7 +28,7 @@ function MyPromise(resolver) { MyPromise.prototype = new Promise(function() {}); p.constructor = MyPromise; -var q = p.chain( +var q = p.then( function() { log.push("reject caught"); return Promise.reject(new Error("caught")); diff --git a/deps/v8/test/mjsunit/es6/debug-promises/resolve-after-aborted-try-finally.js b/deps/v8/test/mjsunit/es6/debug-promises/resolve-after-aborted-try-finally.js deleted file mode 100644 index 918ae2a2e8..0000000000 --- a/deps/v8/test/mjsunit/es6/debug-promises/resolve-after-aborted-try-finally.js +++ /dev/null @@ -1,32 +0,0 @@ -// Copyright 2014 the V8 project authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -// Flags: --expose-debug-as debug --allow-natives-syntax - -// Test debug events when we listen to all exceptions and -// there is a catch handler for the exception thrown in a Promise. -// We expect a normal Exception debug event to be triggered. - -Debug = debug.Debug; - -var events = []; - -function listener(event, exec_state, event_data, data) { - if (event == Debug.DebugEvent.PromiseEvent) events.push(event_data.status()); -} - -Debug.setListener(listener); - -var p = new Promise(function(resolve, reject) { - do { - try { - throw new Error("reject"); - } finally { - break; // No rethrow. - } - } while (false); - resolve(); -}); - -assertEquals([0 /* create */, 1 /* resolve */], events); diff --git a/deps/v8/test/mjsunit/es6/debug-promises/resolve-after-try-catch.js b/deps/v8/test/mjsunit/es6/debug-promises/resolve-after-try-catch.js deleted file mode 100644 index 298201f103..0000000000 --- a/deps/v8/test/mjsunit/es6/debug-promises/resolve-after-try-catch.js +++ /dev/null @@ -1,29 +0,0 @@ -// Copyright 2014 the V8 project authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -// Flags: --expose-debug-as debug --allow-natives-syntax - -// Test debug events when we listen to all exceptions and -// there is a catch handler for the exception thrown in a Promise. -// We expect a normal Exception debug event to be triggered. - -Debug = debug.Debug; - -var events = []; - -function listener(event, exec_state, event_data, data) { - if (event == Debug.DebugEvent.PromiseEvent) events.push(event_data.status()); -} - -Debug.setListener(listener); - -var p = new Promise(function (resolve, reject) { - try { - throw new Error("reject"); - } catch (e) { - } - resolve(); -}); - -assertEquals([0 /* create */, 1 /* resolve */], events); diff --git a/deps/v8/test/mjsunit/es6/debug-promises/rethrow-in-try-finally.js b/deps/v8/test/mjsunit/es6/debug-promises/rethrow-in-try-finally.js deleted file mode 100644 index b1e2ff98e1..0000000000 --- a/deps/v8/test/mjsunit/es6/debug-promises/rethrow-in-try-finally.js +++ /dev/null @@ -1,30 +0,0 @@ -// Copyright 2014 the V8 project authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -// Flags: --expose-debug-as debug --allow-natives-syntax - -// Test debug events when we listen to all exceptions and -// there is a catch handler for the exception thrown in a Promise. -// We expect a normal Exception debug event to be triggered. - -Debug = debug.Debug; - -var events = []; - -function listener(event, exec_state, event_data, data) { - if (event == Debug.DebugEvent.PromiseEvent) events.push(event_data.status()); -} - -Debug.setListener(listener); - -var p = new Promise(function(resolve, reject) { - try { - throw new Error("reject"); - } finally { - // Implicit rethrow. - } - resolve(); -}); - -assertEquals([0 /* create */, -1 /* rethrown */], events); diff --git a/deps/v8/test/mjsunit/es6/debug-promises/stepin-constructor.js b/deps/v8/test/mjsunit/es6/debug-promises/stepin-constructor.js index 906969e105..6914ae0036 100644 --- a/deps/v8/test/mjsunit/es6/debug-promises/stepin-constructor.js +++ b/deps/v8/test/mjsunit/es6/debug-promises/stepin-constructor.js @@ -21,9 +21,9 @@ function listener(event, exec_state, event_data, data) { Debug.setListener(listener); function resolver(resolve, reject) { - 1; - 2; - 3; + print(1); + print(2); + print(3); resolve(); } @@ -35,9 +35,9 @@ Debug.setListener(null); var expected_breaks = [ "debugger;", "var p = new Promise(resolver);", - "1;", - "2;", - "3;", + "print(1);", + "print(2);", + "print(3);", "resolve();", "}", "Debug.setListener(null);" diff --git a/deps/v8/test/mjsunit/es6/debug-promises/throw-caught-all.js b/deps/v8/test/mjsunit/es6/debug-promises/throw-caught-all.js index 3b7c48c1cf..8b932490b2 100644 --- a/deps/v8/test/mjsunit/es6/debug-promises/throw-caught-all.js +++ b/deps/v8/test/mjsunit/es6/debug-promises/throw-caught-all.js @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// Flags: --expose-debug-as debug --allow-natives-syntax --promise-extra +// Flags: --expose-debug-as debug --allow-natives-syntax // Test debug events when we listen to all exceptions and // there is a catch handler for the exception thrown in a Promise. @@ -18,7 +18,7 @@ var p = new Promise(function(resolve, reject) { resolve(); }); -var q = p.chain( +var q = p.then( function() { log.push("throw"); throw new Error("caught"); diff --git a/deps/v8/test/mjsunit/es6/debug-promises/throw-caught-late.js b/deps/v8/test/mjsunit/es6/debug-promises/throw-caught-late.js index aa7e584320..0399e5cc34 100644 --- a/deps/v8/test/mjsunit/es6/debug-promises/throw-caught-late.js +++ b/deps/v8/test/mjsunit/es6/debug-promises/throw-caught-late.js @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// Flags: --expose-debug-as debug --allow-natives-syntax --promise-extra +// Flags: --expose-debug-as debug --allow-natives-syntax // Test debug events when we only listen to uncaught exceptions, the Promise // throws, and a catch handler is installed right before throwing. @@ -14,7 +14,7 @@ var p = new Promise(function(resolve, reject) { resolve(); }); -var q = p.chain( +var q = p.then( function() { q.catch(function(e) { assertEquals("caught", e.message); diff --git a/deps/v8/test/mjsunit/es6/debug-promises/throw-caught-uncaught.js b/deps/v8/test/mjsunit/es6/debug-promises/throw-caught-uncaught.js index a424ccc9f7..8e1524d519 100644 --- a/deps/v8/test/mjsunit/es6/debug-promises/throw-caught-uncaught.js +++ b/deps/v8/test/mjsunit/es6/debug-promises/throw-caught-uncaught.js @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// Flags: --expose-debug-as debug --allow-natives-syntax --promise-extra +// Flags: --expose-debug-as debug --allow-natives-syntax // Test debug events when we only listen to uncaught exceptions and // there is a catch handler for the exception thrown in a Promise. @@ -14,7 +14,7 @@ var p = new Promise(function(resolve, reject) { resolve(); }); -var q = p.chain( +var q = p.then( function() { throw new Error("caught throw"); }); diff --git a/deps/v8/test/mjsunit/es6/debug-promises/throw-finally-caught-all.js b/deps/v8/test/mjsunit/es6/debug-promises/throw-finally-caught-all.js new file mode 100644 index 0000000000..eb823f518f --- /dev/null +++ b/deps/v8/test/mjsunit/es6/debug-promises/throw-finally-caught-all.js @@ -0,0 +1,72 @@ +// Copyright 2016 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Flags: --expose-debug-as debug --allow-natives-syntax + +// Test debug events when we listen to all exceptions and +// there is a catch handler for the exception thrown in a Promise, first +// caught by a try-finally, and immediately rethrown. +// We expect a normal Exception debug event to be triggered. + +Debug = debug.Debug; + +var expected_events = 1; +var log = []; + +var p = new Promise(function(resolve, reject) { + log.push("resolve"); + resolve(); +}); + +var q = p.then( + function() { + log.push("throw"); + try { + throw new Error("caught"); + } finally { + } + }); + +q.catch( + function(e) { + assertEquals("caught", e.message); + }); + +function listener(event, exec_state, event_data, data) { + try { + if (event == Debug.DebugEvent.Exception) { + expected_events--; + assertTrue(expected_events >= 0); + assertEquals("caught", event_data.exception().message); + assertSame(q, event_data.promise()); + assertFalse(event_data.uncaught()); + } + } catch (e) { + %AbortJS(e + "\n" + e.stack); + } +} + +Debug.setBreakOnException(); +Debug.setListener(listener); + +log.push("end main"); + +function testDone(iteration) { + function checkResult() { + try { + assertTrue(iteration < 10); + if (expected_events === 0) { + assertEquals(["resolve", "end main", "throw"], log); + } else { + testDone(iteration + 1); + } + } catch (e) { + %AbortJS(e + "\n" + e.stack); + } + } + + %EnqueueMicrotask(checkResult); +} + +testDone(0); diff --git a/deps/v8/test/mjsunit/es6/debug-promises/throw-uncaught-all.js b/deps/v8/test/mjsunit/es6/debug-promises/throw-uncaught-all.js index bfe0bedbac..3a73ac9fff 100644 --- a/deps/v8/test/mjsunit/es6/debug-promises/throw-uncaught-all.js +++ b/deps/v8/test/mjsunit/es6/debug-promises/throw-uncaught-all.js @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// Flags: --expose-debug-as debug --allow-natives-syntax --promise-extra +// Flags: --expose-debug-as debug --allow-natives-syntax // Test debug events when we listen to all exceptions and // there is no catch handler for the exception thrown in a Promise. @@ -18,7 +18,7 @@ var p = new Promise(function(resolve, reject) { resolve(); }); -var q = p.chain( +var q = p.then( function() { log.push("throw"); throw new Error("uncaught"); // event diff --git a/deps/v8/test/mjsunit/es6/debug-promises/throw-uncaught-uncaught.js b/deps/v8/test/mjsunit/es6/debug-promises/throw-uncaught-uncaught.js index 8dff592f33..24239f26f3 100644 --- a/deps/v8/test/mjsunit/es6/debug-promises/throw-uncaught-uncaught.js +++ b/deps/v8/test/mjsunit/es6/debug-promises/throw-uncaught-uncaught.js @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// Flags: --expose-debug-as debug --allow-natives-syntax --promise-extra +// Flags: --expose-debug-as debug --allow-natives-syntax // Test debug events when we only listen to uncaught exceptions and // there is a catch handler for the exception thrown in a Promise. @@ -18,7 +18,7 @@ var p = new Promise(function(resolve, reject) { resolve(); }); -var q = p.chain( +var q = p.then( function() { log.push("throw"); throw new Error("uncaught"); // event diff --git a/deps/v8/test/mjsunit/es6/debug-promises/throw-with-throw-in-reject.js b/deps/v8/test/mjsunit/es6/debug-promises/throw-with-throw-in-reject.js index 5cf49f2fae..622dd2573e 100644 --- a/deps/v8/test/mjsunit/es6/debug-promises/throw-with-throw-in-reject.js +++ b/deps/v8/test/mjsunit/es6/debug-promises/throw-with-throw-in-reject.js @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// Flags: --expose-debug-as debug --allow-natives-syntax --promise-extra +// Flags: --expose-debug-as debug --allow-natives-syntax // Test debug events when an exception is thrown inside a Promise, which is // caught by a custom promise, which throws a new exception in its reject @@ -12,7 +12,7 @@ Debug = debug.Debug; -var expected_events = 2; +var expected_events = 1; var log = []; var p = new Promise(function(resolve, reject) { @@ -34,7 +34,7 @@ MyPromise.prototype = new Promise(function() {}); MyPromise.__proto__ = Promise; p.constructor = MyPromise; -var q = p.chain( +var q = p.then( function() { log.push("throw caught"); throw new Error("caught"); // event @@ -45,12 +45,10 @@ function listener(event, exec_state, event_data, data) { if (event == Debug.DebugEvent.Exception) { expected_events--; assertTrue(expected_events >= 0); - if (expected_events == 1) { + if (expected_events == 0) { assertEquals(["resolve", "construct", "end main", "throw caught"], log); assertEquals("caught", event_data.exception().message); - } else if (expected_events == 0) { - assertEquals("reject", event_data.exception().message); } else { assertUnreachable(); } diff --git a/deps/v8/test/mjsunit/es6/debug-scope-default-param-with-eval.js b/deps/v8/test/mjsunit/es6/debug-scope-default-param-with-eval.js new file mode 100644 index 0000000000..d4dc93f2c5 --- /dev/null +++ b/deps/v8/test/mjsunit/es6/debug-scope-default-param-with-eval.js @@ -0,0 +1,61 @@ +// Copyright 2016 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Flags: --expose-debug-as debug + +// Test that the parameter initialization block scope set up for +// sloppy eval is visible to the debugger. + +var Debug = debug.Debug; +var exception = null; +var break_count = 0; + +function call_for_break() { + return 5; +} + +function test(x = eval("var y = 7; debugger; y") + call_for_break()) { + return x; +} + +function listener(event, exec_state, event_data, data) { + if (event != Debug.DebugEvent.Break) return; + try { + var frame = exec_state.frame(0); + var block_scope; + if (break_count++ == 0) { + // Inside eval. + assertEquals([ debug.ScopeType.Eval, + debug.ScopeType.Block, + debug.ScopeType.Closure, + debug.ScopeType.Script, + debug.ScopeType.Global ], + frame.allScopes().map(s => s.scopeType())); + exec_state.prepareStep(Debug.StepAction.StepOut); + block_scope = frame.scope(1); + } else { + // Outside of eval. + assertEquals([ debug.ScopeType.Block, + debug.ScopeType.Local, + debug.ScopeType.Script, + debug.ScopeType.Global ], + frame.allScopes().map(s => s.scopeType())); + block_scope = frame.scope(0); + } + assertTrue(block_scope.scopeObject().propertyNames().includes('y')); + assertEquals(7, block_scope.scopeObject().property('y').value().value()); + } catch (e) { + print(e); + exception = e; + } +} + +Debug.setListener(listener); + +assertEquals(12, test()); + +Debug.setListener(null); + +assertNull(exception); +assertEquals(2, break_count); diff --git a/deps/v8/test/mjsunit/es6/debug-step-into-regexp-subclass.js b/deps/v8/test/mjsunit/es6/debug-step-into-regexp-subclass.js index 599fe05715..5e5eb47d7f 100644 --- a/deps/v8/test/mjsunit/es6/debug-step-into-regexp-subclass.js +++ b/deps/v8/test/mjsunit/es6/debug-step-into-regexp-subclass.js @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// Flags: --expose-debug-as debug --harmony-regexp-subclass +// Flags: --expose-debug-as debug Debug = debug.Debug diff --git a/deps/v8/test/mjsunit/es6/debug-stepin-microtasks.js b/deps/v8/test/mjsunit/es6/debug-stepin-microtasks.js index 6a7c5536dc..e541f0f4b4 100644 --- a/deps/v8/test/mjsunit/es6/debug-stepin-microtasks.js +++ b/deps/v8/test/mjsunit/es6/debug-stepin-microtasks.js @@ -2,7 +2,6 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// Flags: --harmony-object-observe // Flags: --allow-natives-syntax --expose-debug-as debug Debug = debug.Debug @@ -46,6 +45,7 @@ Promise.resolve(42) .then(Boolean) // Should skip stepping into native. .then(promise2) .catch(promise3) + .then(promise4) .catch(function(e) { %AbortJS("FAIL: uncaught exception " + e); }); @@ -60,36 +60,16 @@ function promise2() { } function promise3() { - installObservers(); // Break 4. StepOver. - return break_count; // Break 5. -} // Break 6. - -function installObservers() { - var dummy = {}; - Object.observe(dummy, observer1); - Object.observe(dummy, Object); // Should skip stepping into native. - Object.observe(dummy, Boolean); // Should skip stepping into native. - Object.observe(dummy, observer2); - dummy.foo = 1; -} - -function observer1() { - return exception || 3; // Break 7. -} // Break 8. - -function observer2() { - Promise.resolve().then(promise4); // Break 9. StepOver. - return break_count + 1; // Break 10. -} // Break 11. + return break_count; // Break 4. +} // Break 5. function promise4() { - finalize(); // Break 12. StepOver. - return 0; // Break 13. -} // Break 14. StepOver. + finalize(); // Break 6. StepOver. + return 0; // Break 7. +} // Break 8. StepOver. function finalize() { - var dummy = {}; - Object.observe(dummy, function() { + Promise.resolve().then(function() { if (expected_breaks !== break_count) { %AbortJS("FAIL: expected <" + expected_breaks + "> breaks instead of <" + break_count + ">"); @@ -98,5 +78,4 @@ function finalize() { %AbortJS("FAIL: exception: " + exception); } }); - dummy.foo = 1; } diff --git a/deps/v8/test/mjsunit/es6/debug-stepin-proxies.js b/deps/v8/test/mjsunit/es6/debug-stepin-proxies.js index 4e71c79198..72c01f0c43 100644 --- a/deps/v8/test/mjsunit/es6/debug-stepin-proxies.js +++ b/deps/v8/test/mjsunit/es6/debug-stepin-proxies.js @@ -54,7 +54,7 @@ assertEquals(42, get); assertEquals([ "a0", - "b17", "h4b20", "i2b20", // [[Has]] + "b17", "h4b17", "i2b17", // [[Has]] "c15", "j4c15", "k2c15", // [[Get]] "d0", "l4d11", "m2d11", // [[Set]] "g0" diff --git a/deps/v8/test/mjsunit/es6/debug-stepnext-for.js b/deps/v8/test/mjsunit/es6/debug-stepnext-for.js index 9d5641a4a3..d425a46b84 100644 --- a/deps/v8/test/mjsunit/es6/debug-stepnext-for.js +++ b/deps/v8/test/mjsunit/es6/debug-stepnext-for.js @@ -11,6 +11,8 @@ var log = [] var s = 0; var a = [1, 2, 3]; +var b = [1, 2, 3, 4]; +var null_value = null; var i = 0; function f() { @@ -18,11 +20,11 @@ function f() { debugger; // Break a var j; // Break b - for (var i in null) { // Break c + for (var i in null_value) { // Break c s += a[i]; } - for (j in null) { // Break d + for (j in null_value) { // Break d s += a[j]; } @@ -46,7 +48,7 @@ function f() { s += j; // Break I } - for (let i of a) { // Break j + for (let i of a) { // Break j s += i; // Break J } @@ -61,6 +63,11 @@ function f() { for (let i = 0; i < 3; i++) { // Break m s += a[i]; // Break M } + + for (let i of a) {} // Break n + + [1, ...a] // Break o + } // Break y function listener(event, exec_state, event_data, data) { @@ -103,17 +110,21 @@ var expected = [ // For-in-let: get enumerable, next, body, next, ... "g16","g11","G4","g11","G4","g11","G4","g11", // For-of-var: [Symbol.iterator](), next(), body, next(), body, ... - "h16","h14","h15","H4","h15","H4","h15","H4","h15", + "h16","h13","H4","h13","H4","h13","H4","h13", // For-of: [Symbol.iterator](), next(), body, next(), body, ... - "i12","i10","i11","I4","i11","I4","i11","I4","i11", + "i12","i9","I4","i9","I4","i9","I4","i9", // For-of-let: [Symbol.iterator](), next(), body, next(), ... - "j16","j14","j15","J4","j15","J4","j15","J4","j15", + "j18","j14","J4","j14","J4","j14","J4","j14", // For-var: init, condition, body, next, condition, body, ... "k15","k20","K4","k26","k20","K4","k26","k20","K4","k26","k20", // For: init, condition, body, next, condition, body, ... "l7","l16","L4","l22","l16","L4","l22","l16","L4","l22","l16", // For-let: init, condition, body, next, condition, body, ... "m15","m20","M4","m26","m20","M4","m26","m20","M4","m26","m20", + // For-of, empty: [Symbol.iterator](), next() once + "n16", "n13", + // Spread: expression statement, spread + "o2", "o9", // Exit. "y0","z0", ] diff --git a/deps/v8/test/mjsunit/es6/default-parameters.js b/deps/v8/test/mjsunit/es6/default-parameters.js index 4e0bf542ef..c0fe031c03 100644 --- a/deps/v8/test/mjsunit/es6/default-parameters.js +++ b/deps/v8/test/mjsunit/es6/default-parameters.js @@ -350,14 +350,15 @@ (function TestDirectiveThrows() { "use strict"; - assertThrows(function(){ eval("function(x=1){'use strict';}") }, SyntaxError); - assertThrows(function(){ eval("(x=1) => {'use strict';}") }, SyntaxError); - assertThrows( - function(){ eval("(class{foo(x=1) {'use strict';}});") }, SyntaxError); - - assertThrows( - function(){ eval("function(a, x=1){'use strict';}") }, SyntaxError); - assertThrows(function(){ eval("(a, x=1) => {'use strict';}") }, SyntaxError); - assertThrows( - function(){ eval("(class{foo(a, x=1) {'use strict';}});") }, SyntaxError); + assertThrows("(function(x=1){'use strict';})", SyntaxError); + assertThrows("(x=1) => {'use strict';}", SyntaxError); + assertThrows("(class{foo(x=1) {'use strict';}});", SyntaxError); + + assertThrows("(function(a, x=1){'use strict';})", SyntaxError); + assertThrows("(a, x=1) => {'use strict';}", SyntaxError); + assertThrows("(class{foo(a, x=1) {'use strict';}});", SyntaxError); + + assertThrows("(function({x}){'use strict';})", SyntaxError); + assertThrows("({x}) => {'use strict';}", SyntaxError); + assertThrows("(class{foo({x}) {'use strict';}});", SyntaxError); })(); diff --git a/deps/v8/test/mjsunit/es6/destructuring.js b/deps/v8/test/mjsunit/es6/destructuring.js index 1f16c45270..a4f88844d4 100644 --- a/deps/v8/test/mjsunit/es6/destructuring.js +++ b/deps/v8/test/mjsunit/es6/destructuring.js @@ -1045,9 +1045,9 @@ function f20({x}) { function x() { return 2 }; return x(); } assertEquals(2, f20({x: 1})); - // Function hoisting is blocked by the conflicting x declaration - function f21({x}) { { function x() { return 2 } } return x(); } - assertThrows(() => f21({x: 1}), TypeError); + // Annex B 3.3 function hoisting is blocked by the conflicting x declaration + function f21({x}) { { function x() { return 2 } } return x; } + assertEquals(1, f21({x: 1})); var g1 = ({x}) => { var x = 2; return x }; assertEquals(2, g1({x: 1})); @@ -1082,15 +1082,15 @@ var g21 = ({x}) => { { function x() { return 2 } } return x(); } assertThrows(() => g21({x: 1}), TypeError); - assertThrows("'use strict'; function f(x) { let x = 0; }; f({});", SyntaxError); - assertThrows("'use strict'; function f({x}) { let x = 0; }; f({});", SyntaxError); - assertThrows("'use strict'; function f(x) { const x = 0; }; f({});", SyntaxError); - assertThrows("'use strict'; function f({x}) { const x = 0; }; f({});", SyntaxError); + assertThrows("'use strict'; function f(x) { let x = 0; }", SyntaxError); + assertThrows("'use strict'; function f({x}) { let x = 0; }", SyntaxError); + assertThrows("'use strict'; function f(x) { const x = 0; }", SyntaxError); + assertThrows("'use strict'; function f({x}) { const x = 0; }", SyntaxError); - assertThrows("'use strict'; let g = (x) => { let x = 0; }; f({});", SyntaxError); - assertThrows("'use strict'; let g = ({x}) => { let x = 0; }; f({});", SyntaxError); - assertThrows("'use strict'; let g = (x) => { const x = 0; }; f({});", SyntaxError); - assertThrows("'use strict'; let g = ({x}) => { const x = 0; }; f({});", SyntaxError); + assertThrows("'use strict'; let g = (x) => { let x = 0; }", SyntaxError); + assertThrows("'use strict'; let g = ({x}) => { let x = 0; }", SyntaxError); + assertThrows("'use strict'; let g = (x) => { const x = 0; }", SyntaxError); + assertThrows("'use strict'; let g = ({x}) => { const x = 0; }", SyntaxError); }()); diff --git a/deps/v8/test/mjsunit/es6/for-each-in-catch.js b/deps/v8/test/mjsunit/es6/for-each-in-catch.js new file mode 100644 index 0000000000..674cddd047 --- /dev/null +++ b/deps/v8/test/mjsunit/es6/for-each-in-catch.js @@ -0,0 +1,194 @@ +// Copyright 2016 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +function checkIsRedeclarationError(code) { + try { + eval(` +checkIsRedeclarationError : { + break checkIsRedeclarationError; +${code} +} +`); + assertUnreachable(); + } catch(e) { + assertInstanceof(e, SyntaxError ); + assertTrue( e.toString().indexOf("has already been declared") >= 0 ); + } +} + +function checkIsNotRedeclarationError(code) { + assertDoesNotThrow(()=>eval(` +checkIsNotRedeclarationError_label : { + break checkIsNotRedeclarationError_label; +${code} +} +`)); +} + + +let var_e = [ + 'var e', + 'var {e}', + 'var {f, e}', + 'var [e]', + 'var {f:e}', + 'var [[[], e]]' +]; + +let not_var_e = [ + 'var f', + 'var {}', + 'var {e:f}', + 'e', + '{e}', + 'let e', + 'const e', + 'let {e}', + 'const {e}', + 'let [e]', + 'const [e]', + 'let {f:e}', + 'const {f:e}' +]; + +// Check that `for (var ... of ...)` cannot redeclare a simple catch variable +// but `for (var ... in ...)` can. +for (let binding of var_e) { + checkIsRedeclarationError(` +try { + throw 0; +} catch(e) { + for (${binding} of []); +} +`); + + checkIsNotRedeclarationError(` +try { + throw 0; +} catch(e) { + for (${binding} in []); +} +`); +} + +// Check that the above error occurs even for nested catches. +for (let binding of var_e) { + checkIsRedeclarationError(` +try { + throw 0; +} catch(e) { + try { + throw 1; + } catch(f) { + try { + throw 2; + } catch({}) { + for (${binding} of []); + } + } +} +`); + + checkIsNotRedeclarationError(` +try { + throw 0; +} catch(e) { + try { + throw 1; + } catch(f) { + try { + throw 2; + } catch({}) { + for (${binding} in []); + } + } +} +`); +} + +// Check that the above error does not occur if a declaration scope is between +// the catch and the loop. +for (let binding of var_e) { + checkIsNotRedeclarationError(` +try { + throw 0; +} catch(e) { + (()=>{for (${binding} of []);})(); +} +`); + + checkIsNotRedeclarationError(` +try { + throw 0; +} catch(e) { + (function(){for (${binding} of []);})(); +} +`); +} + +// Check that there is no error when not declaring a var named e. +for (let binding of not_var_e) { + checkIsNotRedeclarationError(` +try { + throw 0; +} catch(e) { + for (${binding} of []); +} +`); +} + +// Check that there is an error for both for-in and for-of when redeclaring +// a non-simple catch parameter +for (let binding of var_e) { + checkIsRedeclarationError(` +try { + throw 0; +} catch({e}) { + for (${binding} of []); +} +`); + + checkIsRedeclarationError(` +try { + throw 0; +} catch({e}) { + for (${binding} in []); +} +`); +} + +// Check that the above error occurs even for nested catches. +for (let binding of var_e) { + checkIsRedeclarationError(` +try { + throw 0; +} catch({e}) { + try { + throw 1; + } catch(f) { + try { + throw 2; + } catch({}) { + for (${binding} of []); + } + } +} +`); + + checkIsRedeclarationError(` +try { + throw 0; +} catch({e}) { + try { + throw 1; + } catch(f) { + try { + throw 2; + } catch({}) { + for (${binding} in []); + } + } +} +`); +} diff --git a/deps/v8/test/mjsunit/es6/function-name.js b/deps/v8/test/mjsunit/es6/function-name.js new file mode 100644 index 0000000000..0fcab441ed --- /dev/null +++ b/deps/v8/test/mjsunit/es6/function-name.js @@ -0,0 +1,370 @@ +// 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. + +(function testVariableDeclarationsFunction() { + 'use strict'; + var a = function(){}; + assertEquals('a', a.name); + let b = () => {}; + assertEquals('b', b.name); + const c = ((function(){})); + assertEquals('c', c.name); + + var x = function(){}, y = () => {}, z = function withName() {}; + assertEquals('x', x.name); + assertEquals('y', y.name); + assertEquals('withName', z.name); +})(); + +(function testVariableDeclarationsClass() { + 'use strict'; + var a = class {}; + assertEquals('a', a.name); + let b = ((class {})); + assertEquals('b', b.name); + // Should not overwrite name property. + const c = class { static name() { } } + assertEquals('function', typeof c.name); + + var x = class {}, y = class NamedClass {}; + assertEquals('x', x.name); + assertEquals('NamedClass', y.name); +})(); + +(function testObjectProperties() { + 'use strict'; + var obj = { + a: function() {}, + b: () => {}, + c() { }, + get d() { }, + set d(val) { }, + x: function withName() { }, + y: class { }, + z: class ClassName { }, + 42: function() {}, + 4.2: function() {}, + __proto__: function() {}, + }; + + assertEquals('a', obj.a.name); + assertEquals('b', obj.b.name); + assertEquals('c', obj.c.name); + var dDescriptor = Object.getOwnPropertyDescriptor(obj, 'd'); + assertEquals('get d', dDescriptor.get.name); + assertEquals('set d', dDescriptor.set.name); + assertEquals('withName', obj.x.name); + assertEquals('y', obj.y.name); + assertEquals('ClassName', obj.z.name); + assertEquals('42', obj[42].name); + assertEquals('4.2', obj[4.2].name); + assertEquals('', obj.__proto__.name); +})(); + +(function testClassProperties() { + 'use strict'; + class C { + a() { } + static b() { } + get c() { } + set c(val) { } + 42() { } + static 43() { } + get 44() { } + set 44(val) { } + }; + + assertEquals('a', C.prototype.a.name); + assertEquals('b', C.b.name); + var descriptor = Object.getOwnPropertyDescriptor(C.prototype, 'c'); + assertEquals('get c', descriptor.get.name); + assertEquals('set c', descriptor.set.name); + assertEquals('42', C.prototype[42].name); + assertEquals('43', C[43].name); + var descriptor = Object.getOwnPropertyDescriptor(C.prototype, '44'); + assertEquals('get 44', descriptor.get.name); + assertEquals('set 44', descriptor.set.name); +})(); + +(function testComputedProperties() { + 'use strict'; + var a = 'a'; + var b = 'b'; + var sym1 = Symbol('1'); + var sym2 = Symbol('2'); + var sym3 = Symbol('3'); + var symNoDescription = Symbol(); + var obj = { + [a]: function() {}, + [sym1]: function() {}, + [sym2]: function withName() {}, + [symNoDescription]: function() {}, + + get [sym3]() {}, + set [b](val) {}, + }; + + assertEquals('a', obj[a].name); + assertEquals('[1]', obj[sym1].name); + assertEquals('withName', obj[sym2].name); + assertEquals('', obj[symNoDescription].name); + + assertEquals('get [3]', Object.getOwnPropertyDescriptor(obj, sym3).get.name); + assertEquals('set b', Object.getOwnPropertyDescriptor(obj, 'b').set.name); + + var objMethods = { + [a]() {}, + [sym1]() {}, + [symNoDescription]: function() {}, + }; + + assertEquals('a', objMethods[a].name); + assertEquals('[1]', objMethods[sym1].name); + assertEquals('', objMethods[symNoDescription].name); + + class C { + [a]() { } + [sym1]() { } + static [sym2]() { } + [symNoDescription]() { } + + get [sym3]() { } + static set [b](val) { } + } + + assertEquals('a', C.prototype[a].name); + assertEquals('[1]', C.prototype[sym1].name); + assertEquals('[2]', C[sym2].name); + assertEquals('', C.prototype[symNoDescription].name); + + assertEquals('get [3]', Object.getOwnPropertyDescriptor(C.prototype, sym3).get.name); + assertEquals('set b', Object.getOwnPropertyDescriptor(C, 'b').set.name); +})(); + + +(function testAssignment() { + var basicFn, arrowFn, generatorFn, classLit; + + basicFn = function() { return true; }; + assertEquals('basicFn', basicFn.name); + var basicFn2 = basicFn; + assertEquals('basicFn', basicFn2.name); + basicFn = function functionWithName() { }; + assertEquals("functionWithName", basicFn.name); + + arrowFn = x => x; + assertEquals('arrowFn', arrowFn.name); + var arrowFn2 = arrowFn; + assertEquals('arrowFn', arrowFn2.name); + + generatorFn = function*() { yield true; }; + assertEquals('generatorFn', generatorFn.name); + var generatorFn2 = generatorFn; + assertEquals('generatorFn', generatorFn2.name); + generatorFn = function* generatorWithName() { }; + assertEquals("generatorWithName", generatorFn.name); + + classLit = class { constructor() {} }; + assertEquals('classLit', classLit.name); + var classLit2 = classLit; + assertEquals('classLit', classLit2.name); + classLit = class classWithName { constructor() {} }; + assertEquals('classWithName', classLit.name); + classLit = class { constructor() {} static name() {} }; + assertEquals('function', typeof classLit.name); + classLit = class { constructor() {} static get name() { return true; } }; + assertTrue(classLit.name); + classLit = class { constructor() {} static ['name']() {} }; + assertEquals('function', typeof classLit.name); + classLit = class { constructor() {} static get ['name']() { return true; } }; + assertTrue(classLit.name); +})(); + +(function testObjectBindingPattern() { + var { + a = function() {}, + b = () => {}, + x = function withName() { }, + y = class { }, + z = class ClassName { }, + q = class { static name() { return 42 } }, + foo: bar = function() {}, + inParens = (() => {}), + inManyParens = ((((() => {})))), + } = {}; + assertEquals('a', a.name); + assertEquals('b', b.name); + assertEquals('withName', x.name); + assertEquals('y', y.name); + assertEquals('ClassName', z.name); + assertEquals('function', typeof q.name); + assertEquals('bar', bar.name); + assertEquals('inParens', inParens.name) + assertEquals('inManyParens', inManyParens.name) +})(); + +(function testArrayBindingPattern() { + var [ + a = function() {}, + b = () => {}, + x = function withName() { }, + y = class { }, + z = class ClassName { }, + q = class { static name() { return 42 } }, + inParens = (() => {}), + inManyParens = ((((() => {})))), + ] = []; + assertEquals('a', a.name); + assertEquals('b', b.name); + assertEquals('withName', x.name); + assertEquals('y', y.name); + assertEquals('ClassName', z.name); + assertEquals('function', typeof q.name); + assertEquals('inParens', inParens.name) + assertEquals('inManyParens', inManyParens.name) +})(); + +(function testObjectAssignmentPattern() { + var a, b, x, y, z, q; + ({ + a = function() {}, + b = () => {}, + x = function withName() { }, + y = class { }, + z = class ClassName { }, + q = class { static name() { return 42 } }, + foo: bar = function() {}, + inParens = (() => {}), + inManyParens = ((((() => {})))), + } = {}); + assertEquals('a', a.name); + assertEquals('b', b.name); + assertEquals('withName', x.name); + assertEquals('y', y.name); + assertEquals('ClassName', z.name); + assertEquals('function', typeof q.name); + assertEquals('bar', bar.name); + assertEquals('inParens', inParens.name) + assertEquals('inManyParens', inManyParens.name) +})(); + +(function testArrayAssignmentPattern() { + var a, b, x, y, z, q; + [ + a = function() {}, + b = () => {}, + x = function withName() { }, + y = class { }, + z = class ClassName { }, + q = class { static name() { return 42 } }, + inParens = (() => {}), + inManyParens = ((((() => {})))), + ] = []; + assertEquals('a', a.name); + assertEquals('b', b.name); + assertEquals('withName', x.name); + assertEquals('y', y.name); + assertEquals('ClassName', z.name); + assertEquals('function', typeof q.name); + assertEquals('inParens', inParens.name) + assertEquals('inManyParens', inManyParens.name) +})(); + +(function testParameterDestructuring() { + (function({ a = function() {}, + b = () => {}, + x = function withName() { }, + y = class { }, + z = class ClassName { }, + q = class { static name() { return 42 } }, + foo: bar = function() {}, + inParens = (() => {}), + inManyParens = ((((() => {})))) }) { + assertEquals('a', a.name); + assertEquals('b', b.name); + assertEquals('withName', x.name); + assertEquals('y', y.name); + assertEquals('ClassName', z.name); + assertEquals('function', typeof q.name); + assertEquals('bar', bar.name); + assertEquals('inParens', inParens.name) + assertEquals('inManyParens', inManyParens.name) + })({}); + + (function([ a = function() {}, + b = () => {}, + x = function withName() { }, + y = class { }, + z = class ClassName { }, + q = class { static name() { return 42 } }, + inParens = (() => {}), + inManyParens = ((((() => {})))) ]) { + assertEquals('a', a.name); + assertEquals('b', b.name); + assertEquals('withName', x.name); + assertEquals('y', y.name); + assertEquals('ClassName', z.name); + assertEquals('function', typeof q.name); + assertEquals('inParens', inParens.name) + assertEquals('inManyParens', inManyParens.name) + })([]); +})(); + +(function testDefaultParameters() { + (function(a = function() {}, + b = () => {}, + x = function withName() { }, + y = class { }, + z = class ClassName { }, + q = class { static name() { return 42 } }, + inParens = (() => {}), + inManyParens = ((((() => {}))))) { + assertEquals('a', a.name); + assertEquals('b', b.name); + assertEquals('withName', x.name); + assertEquals('y', y.name); + assertEquals('ClassName', z.name); + assertEquals('function', typeof q.name); + assertEquals('inParens', inParens.name) + assertEquals('inManyParens', inManyParens.name) + })(); +})(); + +(function testComputedNameNotShared() { + function makeClass(propName) { + return class { + static [propName]() {} + } + } + + var sym1 = Symbol('1'); + var sym2 = Symbol('2'); + var class1 = makeClass(sym1); + assertEquals('[1]', class1[sym1].name); + var class2 = makeClass(sym2); + assertEquals('[2]', class2[sym2].name); + assertEquals('[1]', class1[sym1].name); +})(); + + +(function testComputedNamesOnlyAppliedSyntactically() { + function factory() { return () => {}; } + + var obj = { ['foo']: factory() }; + assertEquals('', obj.foo.name); +})(); + + +(function testNameNotReflectedInToString() { + var f = function () {}; + var g = function* () {}; + var obj = { + ['h']: function () {}, + i: () => {} + }; + assertEquals('function () {}', f.toString()); + assertEquals('function* () {}', g.toString()); + assertEquals('function () {}', obj.h.toString()); + assertEquals('() => {}', obj.i.toString()); +})(); diff --git a/deps/v8/test/mjsunit/es6/generator-destructuring.js b/deps/v8/test/mjsunit/es6/generator-destructuring.js new file mode 100644 index 0000000000..7228782c09 --- /dev/null +++ b/deps/v8/test/mjsunit/es6/generator-destructuring.js @@ -0,0 +1,317 @@ +// Copyright 2016 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +(function TestDefaultBeforeInitializingYield() { + var y = 0; + var z = 0; + function* f1(x = (y = 1)) { z = 1 }; + assertEquals(0, y); + assertEquals(0, z); + var gen = f1(); + assertEquals(1, y); + assertEquals(0, z); + gen.next(); + assertEquals(1, y); + assertEquals(1, z); +})(); + +(function TestShadowingOfParameters() { + function* f1({x}) { var x = 2; return x } + assertEquals(2, f1({x: 1}).next().value); + function* f2({x}) { { var x = 2; } return x; } + assertEquals(2, f2({x: 1}).next().value); + function* f3({x}) { var y = x; var x = 2; return y; } + assertEquals(1, f3({x: 1}).next().value); + function* f4({x}) { { var y = x; var x = 2; } return y; } + assertEquals(1, f4({x: 1}).next().value); + function* f5({x}, g = () => x) { var x = 2; return g(); } + assertEquals(1, f5({x: 1}).next().value); + function* f6({x}, g = () => x) { { var x = 2; } return g(); } + assertEquals(1, f6({x: 1}).next().value); + function* f7({x}) { var g = () => x; var x = 2; return g(); } + assertEquals(2, f7({x: 1}).next().value); + function* f8({x}) { { var g = () => x; var x = 2; } return g(); } + assertEquals(2, f8({x: 1}).next().value); + function* f9({x}, g = () => eval("x")) { var x = 2; return g(); } + assertEquals(1, f9({x: 1}).next().value); + + function* f10({x}, y) { var y; return y } + assertEquals(2, f10({x: 6}, 2).next().value); + function* f11({x}, y) { var z = y; var y = 2; return z; } + assertEquals(1, f11({x: 6}, 1).next().value); + function* f12(y, g = () => y) { var y = 2; return g(); } + assertEquals(1, f12(1).next().value); + function* f13({x}, y, [z], v) { var x, y, z; return x*y*z*v } + assertEquals(210, f13({x: 2}, 3, [5], 7).next().value); + + function* f20({x}) { function x() { return 2 }; return x(); } + assertEquals(2, f20({x: 1}).next().value); + // Annex B 3.3 function hoisting is blocked by the conflicting x declaration + function* f21({x}) { { function x() { return 2 } } return x; } + assertEquals(1, f21({x: 1}).next().value); + + assertThrows("'use strict'; function* f(x) { let x = 0; }", SyntaxError); + assertThrows("'use strict'; function* f({x}) { let x = 0; }", SyntaxError); + assertThrows("'use strict'; function* f(x) { const x = 0; }", SyntaxError); + assertThrows("'use strict'; function* f({x}) { const x = 0; }", SyntaxError); +}()); + +(function TestDefaults() { + function* f1(x = 1) { return x } + assertEquals(1, f1().next().value); + assertEquals(1, f1(undefined).next().value); + assertEquals(2, f1(2).next().value); + assertEquals(null, f1(null).next().value); + + function* f2(x, y = x) { return x + y; } + assertEquals(8, f2(4).next().value); + assertEquals(8, f2(4, undefined).next().value); + assertEquals(6, f2(4, 2).next().value); + + function* f3(x = 1, y) { return x + y; } + assertEquals(8, f3(5, 3).next().value); + assertEquals(3, f3(undefined, 2).next().value); + assertEquals(6, f3(4, 2).next().value); + + function* f4(x = () => 1) { return x() } + assertEquals(1, f4().next().value); + assertEquals(1, f4(undefined).next().value); + assertEquals(2, f4(() => 2).next().value); + assertThrows(() => f4(null).next(), TypeError); + + function* f5(x, y = () => x) { return x + y(); } + assertEquals(8, f5(4).next().value); + assertEquals(8, f5(4, undefined).next().value); + assertEquals(6, f5(4, () => 2).next().value); + + function* f6(x = {a: 1, m() { return 2 }}) { return x.a + x.m(); } + assertEquals(3, f6().next().value); + assertEquals(3, f6(undefined).next().value); + assertEquals(5, f6({a: 2, m() { return 3 }}).next().value); +}()); + + +(function TestEvalInParameters() { + function* f1(x = eval(0)) { return x } + assertEquals(0, f1().next().value); + function* f2(x = () => eval(1)) { return x() } + assertEquals(1, f2().next().value); +})(); + + +(function TestParameterScopingSloppy() { + var x = 1; + + function* f1(a = x) { var x = 2; return a; } + assertEquals(1, f1().next().value); + function* f2(a = x) { function x() {}; return a; } + assertEquals(1, f2().next().value); + function* f3(a = eval("x")) { var x; return a; } + assertEquals(1, f3().next().value); + function* f31(a = eval("'use strict'; x")) { var x; return a; } + assertEquals(1, f31().next().value); + function* f4(a = function() { return x }) { var x; return a(); } + assertEquals(1, f4().next().value); + function* f5(a = () => x) { var x; return a(); } + assertEquals(1, f5().next().value); + function* f6(a = () => eval("x")) { var x; return a(); } + assertEquals(1, f6().next().value); + function* f61(a = () => { 'use strict'; return eval("x") }) { var x; return a(); } + assertEquals(1, f61().next().value); + function* f62(a = () => eval("'use strict'; x")) { var x; return a(); } + assertEquals(1, f62().next().value); + + var f11 = function* f(x = f) { var f; return x; } + assertSame(f11, f11().next().value); + var f12 = function* f(x = f) { function f() {}; return x; } + assertSame(f12, f12().next().value); + var f13 = function* f(f = 7, x = f) { return x; } + assertSame(7, f13().next().value); + + var o1 = {f: function*(x = this) { return x; }}; + assertSame(o1, o1.f().next().value); + assertSame(1, o1.f(1).next().value); +})(); + +(function TestParameterScopingStrict() { + "use strict"; + var x = 1; + + function* f1(a = x) { let x = 2; return a; } + assertEquals(1, f1().next().value); + function* f2(a = x) { const x = 2; return a; } + assertEquals(1, f2().next().value); + function* f3(a = x) { function x() {}; return a; } + assertEquals(1, f3().next().value); + function* f4(a = eval("x")) { var x; return a; } + assertEquals(1, f4().next().value); + function* f5(a = () => eval("x")) { var x; return a(); } + assertEquals(1, f5().next().value); + + var f11 = function* f(x = f) { let f; return x; } + assertSame(f11, f11().next().value); + var f12 = function* f(x = f) { const f = 0; return x; } + assertSame(f12, f12().next().value); + var f13 = function* f(x = f) { function f() {}; return x; } + assertSame(f13, f13().next().value); +})(); + +(function TestSloppyEvalScoping() { + var x = 1; + + function* f1(y = eval("var x = 2")) { with ({}) { return x; } } + assertEquals(1, f1().next().value); + function* f2(y = eval("var x = 2"), z = x) { return z; } + assertEquals(1, f2().next().value); + assertEquals(1, f2(0).next().value); + function* f3(y = eval("var x = 2"), z = eval("x")) { return z; } + assertEquals(1, f3().next().value); + assertEquals(1, f3(0).next().value); + function* f8(y = (eval("var x = 2"), x)) { return y; } + assertEquals(2, f8().next().value); + assertEquals(0, f8(0).next().value); + + function* f11(z = eval("var y = 2")) { return y; } + assertThrows(() => f11().next(), ReferenceError); + function* f12(z = eval("var y = 2"), b = y) {} + assertThrows(() => f12().next(), ReferenceError); + function* f13(z = eval("var y = 2"), b = eval("y")) {} + assertThrows(() => f13().next(), ReferenceError); + + function* f21(f = () => x) { eval("var x = 2"); return f() } + assertEquals(1, f21().next().value); + assertEquals(3, f21(() => 3).next().value); + function* f22(f = () => eval("x")) { eval("var x = 2"); return f() } + assertEquals(1, f22().next().value); + assertEquals(3, f22(() => 3).next().value); +})(); + + +(function TestStrictEvalScoping() { + 'use strict'; + var x = 1; + + function* f1(y = eval("var x = 2")) { return x; } + assertEquals(1, f1().next().value); + function* f2(y = eval("var x = 2"), z = x) { return z; } + assertEquals(1, f2().next().value); + assertEquals(1, f2(0).next().value); + function* f3(y = eval("var x = 2"), z = eval("x")) { return z; } + assertEquals(1, f3().next().value); + assertEquals(1, f3(0).next().value); + function* f8(y = (eval("var x = 2"), x)) { return y; } + assertEquals(1, f8().next().value); + assertEquals(0, f8(0).next().value); + + function* f11(z = eval("var y = 2")) { return y; } + assertThrows(() => f11().next().value, ReferenceError); + function* f12(z = eval("var y = 2"), b = y) {} + assertThrows(() => f12().next().value, ReferenceError); + function* f13(z = eval("var y = 2"), b = eval("y")) {} + assertThrows(() => f13().next().value, ReferenceError); + + function* f21(f = () => x) { eval("var x = 2"); return f() } + assertEquals(1, f21().next().value); + assertEquals(3, f21(() => 3).next().value); + function* f22(f = () => eval("x")) { eval("var x = 2"); return f() } + assertEquals(1, f22().next().value); + assertEquals(3, f22(() => 3).next().value); +})(); + +(function TestParameterTDZSloppy() { + function* f1(a = x, x) { return a } + assertThrows(() => f1(undefined, 4), ReferenceError); + assertEquals(4, f1(4, 5).next().value); + function* f2(a = eval("x"), x) { return a } + assertThrows(() => f2(undefined, 4), ReferenceError); + assertEquals(4, f2(4, 5).next().value); + function* f3(a = eval("'use strict'; x"), x) { return a } + assertThrows(() => f3(undefined, 4), ReferenceError); + assertEquals(4, f3(4, 5).next().value); + function* f4(a = () => x, x) { return a() } + assertEquals(4, f4(() => 4, 5).next().value); + function* f5(a = () => eval("x"), x) { return a() } + assertEquals(4, f5(() => 4, 5).next().value); + function* f6(a = () => eval("'use strict'; x"), x) { return a() } + assertEquals(4, f6(() => 4, 5).next().value); + + function* f11(a = x, x = 2) { return a } + assertThrows(() => f11(), ReferenceError); + assertThrows(() => f11(undefined), ReferenceError); + assertThrows(() => f11(undefined, 4), ReferenceError); + assertEquals(4, f1(4, 5).next().value); + function* f12(a = eval("x"), x = 2) { return a } + assertThrows(() => f12(), ReferenceError); + assertThrows(() => f12(undefined), ReferenceError); + assertThrows(() => f12(undefined, 4), ReferenceError); + assertEquals(4, f12(4, 5).next().value); + function* f13(a = eval("'use strict'; x"), x = 2) { return a } + assertThrows(() => f13(), ReferenceError); + assertThrows(() => f13(undefined), ReferenceError); + assertThrows(() => f13(undefined, 4), ReferenceError); + assertEquals(4, f13(4, 5).next().value); + + function* f21(x = function() { return a }, ...a) { return x()[0] } + assertEquals(4, f21(undefined, 4).next().value); + function* f22(x = () => a, ...a) { return x()[0] } + assertEquals(4, f22(undefined, 4).next().value); + function* f23(x = () => eval("a"), ...a) { return x()[0] } + assertEquals(4, f23(undefined, 4).next().value); + function* f24(x = () => {'use strict'; return eval("a") }, ...a) { + return x()[0] + } + assertEquals(4, f24(undefined, 4).next().value); + function* f25(x = () => eval("'use strict'; a"), ...a) { return x()[0] } + assertEquals(4, f25(undefined, 4).next().value); +})(); + +(function TestParameterTDZStrict() { + "use strict"; + + function* f1(a = eval("x"), x) { return a } + assertThrows(() => f1(undefined, 4), ReferenceError); + assertEquals(4, f1(4, 5).next().value); + function* f2(a = () => eval("x"), x) { return a() } + assertEquals(4, f2(() => 4, 5).next().value); + + function* f11(a = eval("x"), x = 2) { return a } + assertThrows(() => f11(), ReferenceError); + assertThrows(() => f11(undefined), ReferenceError); + assertThrows(() => f11(undefined, 4), ReferenceError); + assertEquals(4, f11(4, 5).next().value); + + function* f21(x = () => eval("a"), ...a) { return x()[0] } + assertEquals(4, f21(undefined, 4).next().value); +})(); + +(function TestArgumentsForNonSimpleParameters() { + function* f1(x = 900) { arguments[0] = 1; return x } + assertEquals(9, f1(9).next().value); + assertEquals(900, f1().next().value); + function* f2(x = 1001) { x = 2; return arguments[0] } + assertEquals(10, f2(10).next().value); + assertEquals(undefined, f2().next().value); +}()); + + +(function TestFunctionLength() { + assertEquals(0, (function*(x = 1) {}).length); + assertEquals(0, (function*(x = 1, ...a) {}).length); + assertEquals(1, (function*(x, y = 1) {}).length); + assertEquals(1, (function*(x, y = 1, ...a) {}).length); + assertEquals(2, (function*(x, y, z = 1) {}).length); + assertEquals(2, (function*(x, y, z = 1, ...a) {}).length); + assertEquals(1, (function*(x, y = 1, z) {}).length); + assertEquals(1, (function*(x, y = 1, z, ...a) {}).length); + assertEquals(1, (function*(x, y = 1, z, v = 2) {}).length); + assertEquals(1, (function*(x, y = 1, z, v = 2, ...a) {}).length); +})(); + +(function TestDirectiveThrows() { + "use strict"; + + assertThrows("(function*(x=1){'use strict';})", SyntaxError); + assertThrows("(function*(a, x=1){'use strict';})", SyntaxError); + assertThrows("(function*({x}){'use strict';})", SyntaxError); +})(); diff --git a/deps/v8/test/mjsunit/es6/generators-objects.js b/deps/v8/test/mjsunit/es6/generators-objects.js index a0c3b809be..2cc359f911 100644 --- a/deps/v8/test/mjsunit/es6/generators-objects.js +++ b/deps/v8/test/mjsunit/es6/generators-objects.js @@ -87,3 +87,43 @@ function TestGeneratorObjectMethods() { TestNonGenerator(g.prototype); } TestGeneratorObjectMethods(); + + +function TestPrototype() { + function* g() { } + + let g_prototype = g.prototype; + assertEquals([], Reflect.ownKeys(g_prototype)); + + let generator_prototype = Object.getPrototypeOf(g_prototype); + assertSame(generator_prototype, Object.getPrototypeOf(g).prototype); + + // Unchanged .prototype + assertSame(g_prototype, Object.getPrototypeOf(g())); + + // Custom object as .prototype + { + let proto = {}; + g.prototype = proto; + assertSame(proto, Object.getPrototypeOf(g())); + } + + // Custom non-object as .prototype + g.prototype = null; + assertSame(generator_prototype, Object.getPrototypeOf(g())); +} +TestPrototype(); + + +function TestComputedPropertyNames() { + function* f1() { return {[yield]: 42} } + var g1 = f1(); + g1.next(); + assertEquals(42, g1.next('a').value.a); + + function* f2() { return {['a']: yield} } + var g2 = f2(); + g2.next(); + assertEquals(42, g2.next(42).value.a); +} +TestComputedPropertyNames(); diff --git a/deps/v8/test/mjsunit/es6/instanceof.js b/deps/v8/test/mjsunit/es6/instanceof.js new file mode 100644 index 0000000000..6bf225953f --- /dev/null +++ b/deps/v8/test/mjsunit/es6/instanceof.js @@ -0,0 +1,67 @@ +// 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. + +// Make sure it's an error if @@hasInstance isn't a function. +(function() { + var F = {}; + F[Symbol.hasInstance] = null; + assertThrows(function() { 0 instanceof F; }, TypeError); +})(); + +// Make sure the result is coerced to boolean. +(function() { + var F = {}; + F[Symbol.hasInstance] = function() { return undefined; }; + assertEquals(0 instanceof F, false); + F[Symbol.hasInstance] = function() { return null; }; + assertEquals(0 instanceof F, false); + F[Symbol.hasInstance] = function() { return true; }; + assertEquals(0 instanceof F, true); +})(); + +// Make sure if @@hasInstance throws, we catch it. +(function() { + var F = {}; + F[Symbol.hasInstance] = function() { throw new Error("always throws"); } + try { + 0 instanceof F; + } catch (e) { + assertEquals(e.message, "always throws"); + } +})(); + +// @@hasInstance works for bound functions. +(function() { + var BC = function() {}; + var bc = new BC(); + var bound = BC.bind(); + assertEquals(bound[Symbol.hasInstance](bc), true); + assertEquals(bound[Symbol.hasInstance]([]), false); +})(); + +// if OrdinaryHasInstance is passed a non-callable receiver, return false. +assertEquals(Function.prototype[Symbol.hasInstance].call(Array, []), true); +assertEquals(Function.prototype[Symbol.hasInstance].call({}, {}), false); + +// OrdinaryHasInstance passed a non-object argument returns false. +assertEquals(Function.prototype[Symbol.hasInstance].call(Array, 0), false); + +// Cannot assign to @@hasInstance with %FunctionPrototype%. +(function() { + "use strict"; + function F() {} + assertThrows(function() { F[Symbol.hasInstance] = (v) => v }, TypeError); +})(); + +// Check correct invocation of @@hasInstance handler on function instance. +(function() { + function F() {} + var counter = 0; + var proto = Object.getPrototypeOf(F); + Object.setPrototypeOf(F, null); + F[Symbol.hasInstance] = function(v) { ++counter; return true }; + Object.setPrototypeOf(F, proto); + assertTrue(1 instanceof F); + assertEquals(1, counter); +})(); diff --git a/deps/v8/test/mjsunit/es6/iterator-close.js b/deps/v8/test/mjsunit/es6/iterator-close.js new file mode 100644 index 0000000000..fd8f361e5e --- /dev/null +++ b/deps/v8/test/mjsunit/es6/iterator-close.js @@ -0,0 +1,1382 @@ +// Copyright 2016 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + + +function* g() { yield 42; return 88 }; + + +// Return method is "undefined". +{ + g.prototype.return = null; + + + assertEquals(undefined, (() => { + for (var x of g()) { break; } + })()); + + assertEquals(undefined, (() => { + for (let x of g()) { break; } + })()); + + assertEquals(undefined, (() => { + for (const x of g()) { break; } + })()); + + assertEquals(undefined, (() => { + for (x of g()) { break; } + })()); + + + assertThrowsEquals(() => { + for (var x of g()) { throw 42; } + }, 42); + + assertThrowsEquals(() => { + for (let x of g()) { throw 42; } + }, 42); + + assertThrowsEquals(() => { + for (const x of g()) { throw 42; } + }, 42); + + assertThrowsEquals(() => { + for (x of g()) { throw 42; } + }, 42); + + + assertEquals(42, (() => { + for (var x of g()) { return 42; } + })()); + + assertEquals(42, (() => { + for (let x of g()) { return 42; } + })()); + + assertEquals(42, (() => { + for (const x of g()) { return 42; } + })()); + + assertEquals(42, (() => { + for (x of g()) { return 42; } + })()); + + + assertEquals(42, eval('for (var x of g()) { x; }')); + + assertEquals(42, eval('for (let x of g()) { x; }')); + + assertEquals(42, eval('for (const x of g()) { x; }')); + + assertEquals(42, eval('for (x of g()) { x; }')); + + + assertEquals(42, (() => { + var [x] = g(); return x; + })()); + + assertEquals(42, (() => { + let [x] = g(); return x; + })()); + + assertEquals(42, (() => { + const [x] = g(); return x; + })()); + + assertEquals(42, (() => { + [x] = g(); return x; + })()); + + assertEquals(42, + (([x]) => x)(g()) + ); +} + + +// Return method is not callable. +{ + g.prototype.return = 666; + + + assertThrows(() => { + for (var x of g()) { break; } + }, TypeError); + + assertThrows(() => { + for (let x of g()) { break; } + }, TypeError); + + assertThrows(() => { + for (const x of g()) { break; } + }, TypeError); + + assertThrows(() => { + for (x of g()) { break; } + }, TypeError); + + + assertThrows(() => { + for (var x of g()) { throw 666; } + }, TypeError); + + assertThrows(() => { + for (let x of g()) { throw 666; } + }, TypeError); + + assertThrows(() => { + for (const x of g()) { throw 666; } + }, TypeError); + + assertThrows(() => { + for (x of g()) { throw 666; } + }, TypeError); + + + assertThrows(() => { + for (var x of g()) { return 666; } + }, TypeError); + + assertThrows(() => { + for (let x of g()) { return 666; } + }, TypeError); + + assertThrows(() => { + for (const x of g()) { return 666; } + }, TypeError); + + assertThrows(() => { + for (x of g()) { return 666; } + }, TypeError); + + + assertEquals(42, eval('for (var x of g()) { x; }')); + + assertEquals(42, eval('for (let x of g()) { x; }')); + + assertEquals(42, eval('for (const x of g()) { x; }')); + + assertEquals(42, eval('for (x of g()) { x; }')); + + + assertThrows(() => { + var [x] = g(); return x; + }, TypeError); + + assertThrows(() => { + let [x] = g(); return x; + }, TypeError); + + assertThrows(() => { + const [x] = g(); return x; + }, TypeError); + + assertThrows(() => { + [x] = g(); return x; + }, TypeError); + + assertThrows(() => { + (([x]) => x)(g()); + }, TypeError); +} + + +// Return method does not return an object. +{ + g.prototype.return = () => 666; + + + assertThrows(() => { + for (var x of g()) { break; } + }, TypeError); + + assertThrows(() => { + for (let x of g()) { break; } + }, TypeError); + + assertThrows(() => { + for (const x of g()) { break; } + }, TypeError); + + assertThrows(() => { + for (x of g()) { break; } + }, TypeError); + + + // Throw from the body of a for loop 'wins' vs throw + // originating from a bad 'return' value. + + assertThrowsEquals(() => { + for (var x of g()) { throw 666; } + }, 666); + + assertThrowsEquals(() => { + for (let x of g()) { throw 666; } + }, 666); + + assertThrowsEquals(() => { + for (const x of g()) { throw 666; } + }, 666); + + assertThrowsEquals(() => { + for (x of g()) { throw 666; } + }, 666); + + + assertThrows(() => { + for (var x of g()) { return 666; } + }, TypeError); + + assertThrows(() => { + for (let x of g()) { return 666; } + }, TypeError); + + assertThrows(() => { + for (const x of g()) { return 666; } + }, TypeError); + + assertThrows(() => { + for (x of g()) { return 666; } + }, TypeError); + + + assertEquals(42, eval('for (var x of g()) { x; }')); + + assertEquals(42, eval('for (let x of g()) { x; }')); + + assertEquals(42, eval('for (const x of g()) { x; }')); + + assertEquals(42, eval('for (x of g()) { x; }')); + + + assertThrows(() => { + var [x] = g(); return x; + }, TypeError); + + assertThrows(() => { + let [x] = g(); return x; + }, TypeError); + + assertThrows(() => { + const [x] = g(); return x; + }, TypeError); + + assertThrows(() => { + [x] = g(); return x; + }, TypeError); + + assertThrows(() => { + (([x]) => x)(g()); + }, TypeError); +} + + +// Return method returns an object. +{ + let log = []; + g.prototype.return = (...args) => { log.push(args); return {} }; + + + log = []; + for (var x of g()) { break; } + assertEquals([[]], log); + + log = []; + for (let x of g()) { break; } + assertEquals([[]], log); + + log = []; + for (const x of g()) { break; } + assertEquals([[]], log); + + log = []; + for (x of g()) { break; } + assertEquals([[]], log); + + + log = []; + assertThrowsEquals(() => { + for (var x of g()) { throw 42; } + }, 42); + assertEquals([[]], log); + + log = []; + assertThrowsEquals(() => { + for (let x of g()) { throw 42; } + }, 42); + assertEquals([[]], log); + + log = []; + assertThrowsEquals(() => { + for (const x of g()) { throw 42; } + }, 42); + assertEquals([[]], log); + + log = []; + assertThrowsEquals(() => { + for (x of g()) { throw 42; } + }, 42); + assertEquals([[]], log); + + + log = []; + assertEquals(42, (() => { + for (var x of g()) { return 42; } + })()); + assertEquals([[]], log); + + log = []; + assertEquals(42, (() => { + for (let x of g()) { return 42; } + })()); + assertEquals([[]], log); + + log = []; + assertEquals(42, (() => { + for (const x of g()) { return 42; } + })()); + assertEquals([[]], log); + + log = []; + assertEquals(42, (() => { + for (x of g()) { return 42; } + })()); + assertEquals([[]], log); + + + log = []; + assertEquals(42, eval('for (var x of g()) { x; }')); + assertEquals([], log); + + log = []; + assertEquals(42, eval('for (let x of g()) { x; }')); + assertEquals([], log); + + log = []; + assertEquals(42, eval('for (const x of g()) { x; }')); + assertEquals([], log); + + log = []; + assertEquals(42, eval('for (x of g()) { x; }')); + assertEquals([], log); + + + // Even if doing the assignment throws, still call return + log = []; + x = { set attr(_) { throw 1234; } }; + assertThrowsEquals(() => { + for (x.attr of g()) { throw 456; } + }, 1234); + assertEquals([[]], log); + + + log = []; + assertEquals(42, (() => { + var [x] = g(); return x; + })()); + assertEquals([[]], log); + + log = []; + assertEquals(42, (() => { + let [x] = g(); return x; + })()); + assertEquals([[]], log); + + log = []; + assertEquals(42, (() => { + const [x] = g(); return x; + })()); + assertEquals([[]], log); + + log = []; + assertEquals(42, (() => { + [x] = g(); return x; + })()); + assertEquals([[]], log); + + log = [] + assertEquals(42, + (([x]) => x)(g()) + ); + assertEquals([[]], log); + + + log = []; + assertEquals(42, (() => { + var [x,] = g(); return x; + })()); + assertEquals([[]], log); + + log = []; + assertEquals(42, (() => { + let [x,] = g(); return x; + })()); + assertEquals([[]], log); + + log = []; + assertEquals(42, (() => { + const [x,] = g(); return x; + })()); + assertEquals([[]], log); + + log = []; + assertEquals(42, (() => { + [x,] = g(); return x; + })()); + assertEquals([[]], log); + + log = [] + assertEquals(42, + (([x,]) => x)(g()) + ); + assertEquals([[]], log); + + + log = []; + assertEquals(42, (() => { + var [x,,] = g(); return x; + })()); + assertEquals([], log); + + log = []; + assertEquals(42, (() => { + let [x,,] = g(); return x; + })()); + assertEquals([], log); + + log = []; + assertEquals(42, (() => { + const [x,,] = g(); return x; + })()); + assertEquals([], log); + + log = []; + assertEquals(42, (() => { + [x,,] = g(); return x; + })()); + assertEquals([], log); + + log = [] + assertEquals(42, + (([x,,]) => x)(g()) + ); + assertEquals([], log); + + + log = []; + assertEquals([42, undefined], (() => { + var [x, y] = g(); return [x, y]; + })()); + assertEquals([], log); + + log = []; + assertEquals([42, undefined], (() => { + let [x, y] = g(); return [x, y]; + })()); + assertEquals([], log); + + log = []; + assertEquals([42, undefined], (() => { + const [x, y] = g(); return [x, y]; + })()); + assertEquals([], log); + + log = []; + assertEquals([42, undefined], (() => { + [x, y] = g(); return [x, y]; + })()); + assertEquals([], log); + + log = [] + assertEquals([42, undefined], + (([x, y]) => [x, y])(g()) + ); + assertEquals([], log); + + + log = []; + assertEquals([42], (() => { + var [...x] = g(); return x; + })()); + assertEquals([], log); + + log = []; + assertEquals([42], (() => { + let [...x] = g(); return x; + })()); + assertEquals([], log); + + log = []; + assertEquals([42], (() => { + const [...x] = g(); return x; + })()); + assertEquals([], log); + + log = []; + assertEquals([42], (() => { + [...x] = g(); return x; + })()); + assertEquals([], log); + + log = [] + assertEquals([42], + (([...x]) => x)(g()) + ); + assertEquals([], log); + + + log = []; + assertEquals([42, []], (() => { + var [x, ...y] = g(); return [x, y]; + })()); + assertEquals([], log); + + log = []; + assertEquals([42, []], (() => { + let [x, ...y] = g(); return [x, y]; + })()); + assertEquals([], log); + + log = []; + assertEquals([42, []], (() => { + const [x, ...y] = g(); return [x, y]; + })()); + assertEquals([], log); + + log = []; + assertEquals([42, []], (() => { + [x, ...y] = g(); return [x, y]; + })()); + assertEquals([], log); + + log = [] + assertEquals([42, []], + (([x, ...y]) => [x, y])(g()) + ); + assertEquals([], log); + + + log = []; + assertEquals([], (() => { + var [] = g(); return []; + })()); + assertEquals([[]], log); + + log = []; + assertEquals([], (() => { + let [] = g(); return []; + })()); + assertEquals([[]], log); + + log = []; + assertEquals([], (() => { + const [] = g(); return []; + })()); + assertEquals([[]], log); + + log = []; + assertEquals([], (() => { + [] = g(); return []; + })()); + assertEquals([[]], log); + + log = [] + assertEquals([], + (([]) => [])(g()) + ); + assertEquals([[]], log); + + + log = []; + assertEquals([], (() => { + var [...[]] = g(); return []; + })()); + assertEquals([], log); + + log = []; + assertEquals([], (() => { + let [...[]] = g(); return []; + })()); + assertEquals([], log); + + log = []; + assertEquals([], (() => { + const [...[]] = g(); return []; + })()); + assertEquals([], log); + + log = []; + assertEquals([], (() => { + [...[]] = g(); return []; + })()); + assertEquals([], log); + + log = [] + assertEquals([], + (([...[]]) => [])(g()) + ); + assertEquals([], log); + + + log = []; + assertEquals([42], (() => { + var [...[x]] = g(); return [x]; + })()); + assertEquals([], log); + + log = []; + assertEquals([42], (() => { + let [...[x]] = g(); return [x]; + })()); + assertEquals([], log); + + log = []; + assertEquals([42], (() => { + const [...[x]] = g(); return [x]; + })()); + assertEquals([], log); + + log = []; + assertEquals([42], (() => { + [...[x]] = g(); return [x]; + })()); + assertEquals([], log); + + log = [] + assertEquals([42], + (([...[x]]) => [x])(g()) + ); + assertEquals([], log); + + + log = []; + assertEquals([42, undefined], (() => { + var [...[x, y]] = g(); return [x, y]; + })()); + assertEquals([], log); + + log = []; + assertEquals([42, undefined], (() => { + let [...[x, y]] = g(); return [x, y]; + })()); + assertEquals([], log); + + log = []; + assertEquals([42, undefined], (() => { + const [...[x, y]] = g(); return [x, y]; + })()); + assertEquals([], log); + + log = []; + assertEquals([42, undefined], (() => { + [...[x, y]] = g(); return [x, y]; + })()); + assertEquals([], log); + + log = [] + assertEquals([42, undefined], + (([...[x, y]]) => [x, y])(g()) + ); + assertEquals([], log); + + + log = [] + assertThrowsEquals(() => { + let x = { set foo(_) { throw 666; } }; + [x.foo] = g(); + }, 666); + assertEquals([[]], log); + + + log = [] + assertThrows(() => { + var [[]] = g(); + }, TypeError); + assertEquals([[]], log); + + log = [] + assertThrows(() => { + let [[]] = g(); + }, TypeError); + assertEquals([[]], log); + + log = [] + assertThrows(() => { + const [[]] = g(); + }, TypeError); + assertEquals([[]], log); + + log = [] + assertThrows(() => { + [[]] = g(); + }, TypeError); + assertEquals([[]], log); + + log = [] + assertThrows(() => { + (([[]]) => 0)(g()); + }, TypeError); + assertEquals([[]], log); + + + log = [] + assertThrows(() => { + var [...[[]]] = g(); + }, TypeError); + assertEquals([], log); + + log = [] + assertThrows(() => { + let [...[[]]] = g(); + }, TypeError); + assertEquals([], log); + + log = [] + assertThrows(() => { + const [...[[]]] = g(); + }, TypeError); + assertEquals([], log); + + log = [] + assertThrows(() => { + [...[[]]] = g(); + }, TypeError); + assertEquals([], log); + + log = [] + assertThrows(() => { + (([...[[]]]) => 0)(g()); + }, TypeError); + assertEquals([], log); + + + { + let backup = Array.prototype[Symbol.iterator]; + Array.prototype[Symbol.iterator] = () => g(); + + + log = []; + assertDoesNotThrow(() => { + var [x, ...[y]] = [1, 2, 3] + }); + assertEquals(log, [[]]); + + log = []; + assertDoesNotThrow(() => { + let [x, ...[y]] = [1, 2, 3]; + }); + assertEquals(log, [[]]); + + log = []; + assertDoesNotThrow(() => { + const [x, ...[y]] = [1, 2, 3]; + }); + assertEquals(log, [[]]); + + log = []; + assertDoesNotThrow(() => { + (([x, ...[y]]) => {})([1, 2, 3]); + }); + assertEquals(log, [[]]); + + + log = []; + assertThrows(() => { + var [x, ...[[]]] = [1, 2, 3]; + }, TypeError); + assertEquals(log, [[]]); + + log = []; + assertThrows(() => { + let [x, ...[[]]] = [1, 2, 3]; + }, TypeError); + assertEquals(log, [[]]); + + log = []; + assertThrows(() => { + const [x, ...[[]]] = [1, 2, 3]; + }, TypeError); + assertEquals(log, [[]]); + + log = []; + assertThrows(() => { + (([x, ...[[]]]) => {})([1, 2, 3]); + }, TypeError); + assertEquals(log, [[]]); + + + log = []; + assertDoesNotThrow(() => { + var [x, ...[...y]] = [1, 2, 3]; + }); + assertEquals(log, []); + + log = []; + assertDoesNotThrow(() => { + let [x, ...[...y]] = [1, 2, 3]; + }); + assertEquals(log, []); + + log = []; + assertDoesNotThrow(() => { + const [x, ...[...y]] = [1, 2, 3]; + }); + assertEquals(log, []); + + log = []; + assertDoesNotThrow(() => { + (([x, ...[...y]]) => {})([1, 2, 3]); + }); + assertEquals(log, []); + + + Array.prototype[Symbol.iterator] = backup; + } +} + + +// Return method throws. +{ + let log = []; + g.prototype.return = (...args) => { log.push(args); throw 23 }; + + + log = []; + assertThrowsEquals(() => { + for (var x of g()) { break; } + }, 23); + assertEquals([[]], log); + + log = []; + assertThrowsEquals(() => { + for (let x of g()) { break; } + }, 23); + assertEquals([[]], log); + + log = []; + assertThrowsEquals(() => { + for (const x of g()) { break; } + }, 23); + assertEquals([[]], log); + + log = []; + assertThrowsEquals(() => { + for (x of g()) { break; } + }, 23); + assertEquals([[]], log); + + + log = []; + assertThrowsEquals(() => { + for (var x of g()) { throw 42; } + }, 42); + assertEquals([[]], log); + + log = []; + assertThrowsEquals(() => { + for (let x of g()) { throw 42; } + }, 42); + assertEquals([[]], log); + + log = []; + assertThrowsEquals(() => { + for (const x of g()) { throw 42; } + }, 42); + assertEquals([[]], log); + + log = []; + assertThrowsEquals(() => { + for (x of g()) { throw 42; } + }, 42); + assertEquals([[]], log); + + + log = []; + assertThrowsEquals(() => { + for (var x of g()) { return 42; } + }, 23); + assertEquals([[]], log); + + log = []; + assertThrowsEquals(() => { + for (let x of g()) { return 42; } + }, 23); + assertEquals([[]], log); + + log = []; + assertThrowsEquals(() => { + for (const x of g()) { return 42; } + }, 23); + assertEquals([[]], log); + + log = []; + assertThrowsEquals(() => { + for (x of g()) { return 42; } + }, 23); + assertEquals([[]], log); + + + log = []; + assertEquals(42, eval('for (var x of g()) { x; }')); + assertEquals([], log); + + log = []; + assertEquals(42, eval('for (let x of g()) { x; }')); + assertEquals([], log); + + log = []; + assertEquals(42, eval('for (const x of g()) { x; }')); + assertEquals([], log); + + log = []; + assertEquals(42, eval('for (x of g()) { x; }')); + assertEquals([], log); + + + log = []; + assertThrowsEquals(() => { + var [x] = g(); return x; + }, 23); + assertEquals([[]], log); + + log = []; + assertThrowsEquals(() => { + let [x] = g(); return x; + }, 23); + assertEquals([[]], log); + + log = []; + assertThrowsEquals(() => { + const [x] = g(); return x; + }, 23); + assertEquals([[]], log); + + log = []; + assertThrowsEquals(() => { + [x] = g(); return x; + }, 23); + assertEquals([[]], log); + + log = []; + assertThrowsEquals(() => { + (([x]) => x)(g()) + }, 23); + assertEquals([[]], log); +} + + +// Next method throws. +{ + let closed = false; + g.prototype.next = () => { throw 666; }; + g.prototype.return = () => { closed = true; }; + + + assertThrowsEquals(() => { + for (var x of g()) {} + }, 666); + + assertThrowsEquals(() => { + for (let x of g()) {} + }, 666); + + assertThrowsEquals(() => { + for (const x of g()) {} + }, 666); + + assertThrowsEquals(() => { + for (x of g()) {} + }, 666); + + assertThrowsEquals(() => { + var [x] = g(); + }, 666); + + assertThrowsEquals(() => { + let [x] = g(); + }, 666); + + assertThrowsEquals(() => { + const [x] = g(); + }, 666); + + assertThrowsEquals(() => { + [x] = g(); + }, 666); + + assertThrowsEquals(() => { + (([x]) => x)(g()); + }, 666); + + assertThrowsEquals(() => { + var [...x] = g(); + }, 666); + + assertThrowsEquals(() => { + let [...x] = g(); + }, 666); + + assertThrowsEquals(() => { + const [...x] = g(); + }, 666); + + assertThrowsEquals(() => { + [...x] = g(); + }, 666); + + assertThrowsEquals(() => { + (([...x]) => x)(g()); + }, 666); + + + assertFalse(closed); +} + + +// Value throws. +{ + let closed = false; + g.prototype.next = () => ({get value() {throw 666}}); + g.prototype.return = () => { closed = true; }; + + + assertThrowsEquals(() => { + for (var x of g()) {} + }, 666); + + assertThrowsEquals(() => { + for (let x of g()) {} + }, 666); + + assertThrowsEquals(() => { + for (const x of g()) {} + }, 666); + + assertThrowsEquals(() => { + for (x of g()) {} + }, 666); + + assertThrowsEquals(() => { + var [x] = g(); + }, 666); + + assertThrowsEquals(() => { + let [x] = g(); + }, 666); + + assertThrowsEquals(() => { + const [x] = g(); + }, 666); + + assertThrowsEquals(() => { + [x] = g(); + }, 666); + + assertThrowsEquals(() => { + (([x]) => x)(g()); + }, 666); + + assertThrowsEquals(() => { + var [...x] = g(); + }, 666); + + assertThrowsEquals(() => { + let [...x] = g(); + }, 666); + + assertThrowsEquals(() => { + const [...x] = g(); + }, 666); + + assertThrowsEquals(() => { + [...x] = g(); + }, 666); + + assertThrowsEquals(() => { + (([...x]) => x)(g()); + }, 666); + + + assertFalse(closed); +} + + +// Done throws. +{ + let closed = false; + g.prototype.next = () => ({get done() {throw 666}}); + g.prototype.return = () => { closed = true; }; + + + assertThrowsEquals(() => { + for (var x of g()) {} + }, 666); + + assertThrowsEquals(() => { + for (let x of g()) {} + }, 666); + + assertThrowsEquals(() => { + for (const x of g()) {} + }, 666); + + assertThrowsEquals(() => { + for (x of g()) {} + }, 666); + + assertThrowsEquals(() => { + var [x] = g(); + }, 666); + + assertThrowsEquals(() => { + let [x] = g(); + }, 666); + + assertThrowsEquals(() => { + const [x] = g(); + }, 666); + + assertThrowsEquals(() => { + [x] = g(); + }, 666); + + assertThrowsEquals(() => { + (([x]) => x)(g()); + }, 666); + + assertThrowsEquals(() => { + var [...x] = g(); + }, 666); + + assertThrowsEquals(() => { + let [...x] = g(); + }, 666); + + assertThrowsEquals(() => { + const [...x] = g(); + }, 666); + + assertThrowsEquals(() => { + [...x] = g(); + }, 666); + + assertThrowsEquals(() => { + (([...x]) => x)(g()); + }, 666); + + + assertFalse(closed); +} + + +// Nested loops. +{ + function* g1() { yield 1; yield 2; throw 3; } + function* g2() { yield -1; yield -2; throw -3; } + + assertDoesNotThrow(() => { + for (let x of g1()) { + for (let y of g2()) { + if (y == -2) break; + } + if (x == 2) break; + } + }, -3); + + assertThrowsEquals(() => { + for (let x of g1()) { + for (let y of g2()) { + } + } + }, -3); + + assertThrowsEquals(() => { + for (let x of g1()) { + for (let y of g2()) { + if (y == -2) break; + } + } + }, 3); + + assertDoesNotThrow(() => { + l: for (let x of g1()) { + for (let y of g2()) { + if (y == -2) break l; + } + } + }); + + assertThrowsEquals(() => { + for (let x of g1()) { + for (let y of g2()) { + throw 4; + } + } + }, 4); + + assertThrowsEquals(() => { + for (let x of g1()) { + for (let y of g2()) { + if (y == -2) throw 4; + } + } + }, 4); + + let log = []; + g1.prototype.return = () => { log.push(1); throw 5 }; + g2.prototype.return = () => { log.push(2); throw -5 }; + + log = []; + assertThrowsEquals(() => { + for (let x of g1()) { + for (let y of g2()) { + if (y == -2) break; + } + if (x == 2) break; + } + }, -5); + assertEquals([2, 1], log); + + log = []; + assertThrowsEquals(() => { + for (let x of g1()) { + for (let y of g2()) { + } + } + }, -3); + assertEquals([1], log); + + log = []; + assertThrowsEquals(() => { + for (let x of g1()) { + for (let y of g2()) { + if (y == -2) break; + } + } + }, -5); + assertEquals([2, 1], log); + + log = []; + assertThrowsEquals(() => { + l: for (let x of g1()) { + for (let y of g2()) { + if (y == -2) break l; + } + } + }, -5); + assertEquals([2, 1], log); + + log = []; + assertThrowsEquals(() => { + for (let x of g1()) { + for (let y of g2()) { + throw 4; + } + } + }, 4); + assertEquals([2, 1], log); + + log = []; + assertThrowsEquals(() => { + for (let x of g1()) { + for (let y of g2()) { + if (y == -2) throw 4; + } + } + }, 4); + assertEquals([2, 1], log); + + log = []; + assertThrowsEquals(() => { + for (let x of g1()) { + try { + for (let y of g2()) { + } + } catch (_) {} + } + }, 3); + assertEquals([], log); + + log = []; + assertThrowsEquals(() => { + for (let x of g1()) { + try { + for (let y of g2()) { + } + } catch (_) {} + if (x == 2) break; + } + }, 5); + assertEquals([1], log); +} + + +// yield*, argument's return method is "undefined". +function TestYieldStarWithoutReturn(get_iterable) { + assertTrue(get_iterable().return == undefined); + + function* g() { yield* get_iterable() } + + { + let gen = g(); + assertEquals({value: 1, done: false}, gen.next()); + assertEquals({value: undefined, done: true}, gen.return()); + } + + assertEquals(42, (() => { + for (let x of g()) break; + return 42; + })()); + + assertEquals(42, (() => { + for (let x of g()) return 42; + })()); + + assertThrowsEquals(() => { + for (let x of g()) throw 42; + }, 42); +} +{ + let get_iterable1 = () => [1, 2]; + let get_iterable2 = function*() { yield 1; yield 2 }; + get_iterable2.prototype.return = null; + TestYieldStarWithoutReturn(get_iterable1); + TestYieldStarWithoutReturn(get_iterable2); +} + + +// yield*, argument's return method is defined. +{ + let get_iterable = function*() { yield 1; yield 2 }; + const obj = {}; + get_iterable.prototype.return = (...args) => obj; + + function* g() { yield* get_iterable() } + + { + let gen = g(); + assertEquals({value: 1, done: false}, gen.next()); + assertSame(obj, gen.return()); + assertSame(obj, gen.return()); + assertSame(obj, gen.return()); + assertEquals({value: 2, done: false}, gen.next()); + assertSame(obj, gen.return()); + assertSame(obj, gen.return()); + assertSame(obj, gen.return()); + assertEquals({value: undefined, done: true}, gen.next()); + assertEquals({value: undefined, done: true}, gen.return()); + assertEquals({value: undefined, done: true}, gen.return()); + } + + assertEquals(42, (() => { + for (let x of g()) break; + return 42; + })()); + + assertEquals(42, (() => { + for (let x of g()) return 42; + })()); + + assertThrowsEquals(() => { + for (let x of g()) throw 42; + }, 42); +} diff --git a/deps/v8/test/mjsunit/es6/json.js b/deps/v8/test/mjsunit/es6/json.js index 4c1ada8a86..c049a25ddd 100644 --- a/deps/v8/test/mjsunit/es6/json.js +++ b/deps/v8/test/mjsunit/es6/json.js @@ -9,5 +9,7 @@ function testJSONToString() { assertTrue(desc.configurable); assertFalse(desc.writable); assertEquals("JSON", desc.value); + delete JSON[Symbol.toStringTag]; + assertEquals('[object Object]', "" + JSON); } testJSONToString(); diff --git a/deps/v8/test/mjsunit/es6/legacy-subclassing.js b/deps/v8/test/mjsunit/es6/legacy-subclassing.js deleted file mode 100644 index dbf666d07c..0000000000 --- a/deps/v8/test/mjsunit/es6/legacy-subclassing.js +++ /dev/null @@ -1,38 +0,0 @@ -// Copyright 2015 the V8 project authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -// Flags: --noharmony-species - -// Before Symbol.species was added, ArrayBuffer subclasses constructed -// ArrayBuffers, and Array subclasses constructed Arrays, but TypedArray and -// Promise subclasses constructed an instance of the subclass. - -'use strict'; - -assertEquals(undefined, Symbol.species); - -class MyArray extends Array { } -let myArray = new MyArray(); -assertEquals(MyArray, myArray.constructor); -assertEquals(Array, myArray.map(x => x + 1).constructor); -assertEquals(Array, myArray.concat().constructor); - -class MyUint8Array extends Uint8Array { } -Object.defineProperty(MyUint8Array.prototype, "BYTES_PER_ELEMENT", {value: 1}); -let myTypedArray = new MyUint8Array(3); -assertEquals(MyUint8Array, myTypedArray.constructor); -assertEquals(MyUint8Array, myTypedArray.map(x => x + 1).constructor); - -class MyArrayBuffer extends ArrayBuffer { } -let myBuffer = new MyArrayBuffer(0); -assertEquals(MyArrayBuffer, myBuffer.constructor); -assertEquals(ArrayBuffer, myBuffer.slice().constructor); - -class MyPromise extends Promise { } -let myPromise = new MyPromise(() => {}); -assertEquals(MyPromise, myPromise.constructor); -assertEquals(MyPromise, myPromise.then().constructor); - -// However, subarray instantiates members of the parent class -assertEquals(Uint8Array, myTypedArray.subarray(1).constructor); diff --git a/deps/v8/test/mjsunit/es6/math-log2-log10.js b/deps/v8/test/mjsunit/es6/math-log2-log10.js index b1a7736d71..ea17a79daf 100644 --- a/deps/v8/test/mjsunit/es6/math-log2-log10.js +++ b/deps/v8/test/mjsunit/es6/math-log2-log10.js @@ -57,13 +57,13 @@ assertEqualsDelta(-9.643274665532873e-17, Math.log10(1-Number.EPSILON), 3e-32); var n = -1074; // This loop covers n from -1074 to -1043 for (var lowbits = 1; lowbits <= 0x80000000; lowbits *= 2) { - var x = %_ConstructDouble(0, lowbits); + var x = %ConstructDouble(0, lowbits); assertEquals(n, Math.log2(x)); n++; } // This loop covers n from -1042 to -1023 for (var hibits = 1; hibits <= 0x80000; hibits *= 2) { - var x = %_ConstructDouble(hibits, 0); + var x = %ConstructDouble(hibits, 0); assertEquals(n, Math.log2(x)); n++; } diff --git a/deps/v8/test/mjsunit/es6/math.js b/deps/v8/test/mjsunit/es6/math.js index cb43bd5bd1..dc761d687d 100644 --- a/deps/v8/test/mjsunit/es6/math.js +++ b/deps/v8/test/mjsunit/es6/math.js @@ -9,5 +9,7 @@ function testMathToString() { assertTrue(desc.configurable); assertFalse(desc.writable); assertEquals("Math", desc.value); + delete Math[Symbol.toStringTag]; + assertEquals('[object Object]', "" + Math); } testMathToString(); diff --git a/deps/v8/test/mjsunit/es6/microtask-delivery.js b/deps/v8/test/mjsunit/es6/microtask-delivery.js index 01b971ddc0..6b239bea47 100644 --- a/deps/v8/test/mjsunit/es6/microtask-delivery.js +++ b/deps/v8/test/mjsunit/es6/microtask-delivery.js @@ -25,7 +25,6 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// Flags: --harmony-object-observe // Flags: --allow-natives-syntax var ordering = []; @@ -71,22 +70,6 @@ function newPromise(id, fn) { }; } -function newObserver(id, fn, obj) { - var observer = { - value: 1, - recordCounts: [] - }; - - Object.observe(observer, function(records) { - ordering.push('o' + id); - observer.recordCounts.push(records.length); - if (fn) fn(); - }); - - return observer; -} - - (function PromiseThens() { reset(); @@ -98,72 +81,3 @@ function newObserver(id, fn, obj) { assertOrdering(['p1', 'p2', 'p1:1', 'p2:1']); })(); - - -(function ObserversBatch() { - reset(); - - var p1 = newPromise(1); - var p2 = newPromise(2); - var p3 = newPromise(3); - - var ob1 = newObserver(1); - var ob2 = newObserver(2, function() { - ob3.value++; - p3.resolve(); - ob1.value++; - }); - var ob3 = newObserver(3); - - p1.resolve(); - ob1.value++; - p2.resolve(); - ob2.value++; - - assertOrdering(['p1', 'o1', 'o2', 'p2', 'o1', 'o3', 'p3']); - assertArrayValues([1, 1], ob1.recordCounts); - assertArrayValues([1], ob2.recordCounts); - assertArrayValues([1], ob3.recordCounts); -})(); - - -(function ObserversGetAllRecords() { - reset(); - - var p1 = newPromise(1); - var p2 = newPromise(2); - var ob1 = newObserver(1, function() { - ob2.value++; - }); - var ob2 = newObserver(2); - - p1.resolve(); - ob1.value++; - p2.resolve(); - ob2.value++; - - assertOrdering(['p1', 'o1', 'o2', 'p2']); - assertArrayValues([1], ob1.recordCounts); - assertArrayValues([2], ob2.recordCounts); -})(); - - -(function NewObserverDeliveryGetsNewMicrotask() { - reset(); - - var p1 = newPromise(1); - var p2 = newPromise(2); - var ob1 = newObserver(1); - var ob2 = newObserver(2, function() { - ob1.value++; - }); - - p1.resolve(); - ob1.value++; - p2.resolve(); - ob2.value++; - - assertOrdering(['p1', 'o1', 'o2', 'p2', 'o1']); - assertArrayValues([1, 1], ob1.recordCounts); - assertArrayValues([1], ob2.recordCounts); -})(); diff --git a/deps/v8/test/mjsunit/es6/mirror-collections.js b/deps/v8/test/mjsunit/es6/mirror-collections.js index 81a98b8a58..4232ef91cb 100644 --- a/deps/v8/test/mjsunit/es6/mirror-collections.js +++ b/deps/v8/test/mjsunit/es6/mirror-collections.js @@ -88,16 +88,21 @@ assertEquals(1, setMirror.values(1).length); assertSame(o2, values[0]); assertEquals(undefined, values[1]); +function initWeakMap(weakMap) { + weakMap.set(o1, 11); + weakMap.set(new Object(), 22); + weakMap.set(o3, 33); + weakMap.set(new Object(), 44); + var weakMapMirror = debug.MakeMirror(weakMap); + testMapMirror(weakMapMirror); + weakMap.set(new Object(), 55); + assertTrue(weakMapMirror.entries().length <= 5); + return weakMapMirror; +} + // Test the mirror object for WeakMaps var weakMap = new WeakMap(); -weakMap.set(o1, 11); -weakMap.set(new Object(), 22); -weakMap.set(o3, 33); -weakMap.set(new Object(), 44); -var weakMapMirror = debug.MakeMirror(weakMap); -testMapMirror(weakMapMirror); -weakMap.set(new Object(), 55); -assertTrue(weakMapMirror.entries().length <= 5); +var weakMapMirror = initWeakMap(weakMap); gc(); function testWeakMapEntries(weakMapMirror) { @@ -121,18 +126,23 @@ function testWeakMapEntries(weakMapMirror) { testWeakMapEntries(weakMapMirror); +function initWeakSet(weakSet) { + weakSet.add(o1); + weakSet.add(new Object()); + weakSet.add(o2); + weakSet.add(new Object()); + weakSet.add(new Object()); + weakSet.add(o3); + weakSet.delete(o2); + var weakSetMirror = debug.MakeMirror(weakSet); + testSetMirror(weakSetMirror); + assertTrue(weakSetMirror.values().length <= 5); + return weakSetMirror; +} + // Test the mirror object for WeakSets var weakSet = new WeakSet(); -weakSet.add(o1); -weakSet.add(new Object()); -weakSet.add(o2); -weakSet.add(new Object()); -weakSet.add(new Object()); -weakSet.add(o3); -weakSet.delete(o2); -var weakSetMirror = debug.MakeMirror(weakSet); -testSetMirror(weakSetMirror); -assertTrue(weakSetMirror.values().length <= 5); +var weakSetMirror = initWeakSet(weakSet); gc(); function testWeakSetValues(weakSetMirror) { diff --git a/deps/v8/test/mjsunit/es6/no-unicode-regexp-flag.js b/deps/v8/test/mjsunit/es6/no-unicode-regexp-flag.js deleted file mode 100644 index 82d070e92d..0000000000 --- a/deps/v8/test/mjsunit/es6/no-unicode-regexp-flag.js +++ /dev/null @@ -1,24 +0,0 @@ -// 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. - -// Before Unicode RegExps are shipped, we shouldn't have the 'unicode' -// property on RegExp.prototype, or read it from 'flags'. -// mjsunit/es6/regexp-flags tests that the property is there when the -// flag is on. - -// Flags: --no-harmony-unicode-regexps - -'use strict'; - -assertFalse(RegExp.prototype.hasOwnProperty('unicode')); - -// If we were going to be really strict, we could have a test like this, -// with the assertTrue replaced by assertFalse, since flags shouldn't -// Get the 'unicode' property. However, it is probably OK to omit this -// detailed fix. -var x = /a/; -var y = false; -Object.defineProperty(x, 'unicode', { get() { y = true; } }); -assertEquals("", x.flags); -assertTrue(y); diff --git a/deps/v8/test/mjsunit/es6/object-tostring.js b/deps/v8/test/mjsunit/es6/object-tostring.js index 29d07f263a..bc7d9681f8 100644 --- a/deps/v8/test/mjsunit/es6/object-tostring.js +++ b/deps/v8/test/mjsunit/es6/object-tostring.js @@ -15,15 +15,16 @@ var funs = { RegExp: [ RegExp ], Error: [ Error, TypeError, RangeError, SyntaxError, ReferenceError, EvalError, URIError ] -} -for (f in funs) { - for (i in funs[f]) { +}; +for (var f in funs) { + for (var i in funs[f]) { + assertEquals("[object " + f + "]", - Object.prototype.toString.call(new funs[f][i]), - funs[f][i]); + Object.prototype.toString.call(new funs[f][i]), + funs[f][i]); assertEquals("[object Function]", - Object.prototype.toString.call(funs[f][i]), - funs[f][i]); + Object.prototype.toString.call(funs[f][i]), + funs[f][i]); } } @@ -130,11 +131,11 @@ function testObjectToStringPropertyDesc() { } testObjectToStringPropertyDesc(); -function testObjectToStringOwnNonStringValue() { - var obj = Object.defineProperty({}, Symbol.toStringTag, { value: 1 }); +function testObjectToStringOnNonStringValue(obj) { + Object.defineProperty(obj, Symbol.toStringTag, { value: 1 }); assertEquals("[object Object]", ({}).toString.call(obj)); } -testObjectToStringOwnNonStringValue(); +testObjectToStringOnNonStringValue({}); // Proxies @@ -149,11 +150,77 @@ assertTag("Function", new Proxy(() => 42, {})); assertTag("Foo", new Proxy(() => 42, {get() {return "Foo"}})); assertTag("Function", new Proxy(() => 42, {get() {return 666}})); -revocable = Proxy.revocable([], {}); +var revocable = Proxy.revocable([], {}); revocable.revoke(); assertThrows(() => Object.prototype.toString.call(revocable.proxy), TypeError); -handler = {}; +var handler = {}; revocable = Proxy.revocable([], handler); +// The first get() call, i.e., toString() revokes the proxy handler.get = () => revocable.revoke(); +assertEquals("[object Array]", Object.prototype.toString.call(revocable.proxy)); assertThrows(() => Object.prototype.toString.call(revocable.proxy), TypeError); + +revocable = Proxy.revocable([], handler); +handler.get = () => {revocable.revoke(); return "value";}; +assertEquals("[object value]", Object.prototype.toString.call(revocable.proxy)); +assertThrows(() => Object.prototype.toString.call(revocable.proxy), TypeError); + + +revocable = Proxy.revocable(function() {}, handler); +handler.get = () => revocable.revoke(); +assertEquals("[object Function]", Object.prototype.toString.call(revocable.proxy)); +assertThrows(() => Object.prototype.toString.call(revocable.proxy), TypeError); + +function* gen() { yield 1; } + +assertTag("GeneratorFunction", gen); +Object.defineProperty(gen, Symbol.toStringTag, {writable: true}); +gen[Symbol.toStringTag] = "different string"; +assertTag("different string", gen); +gen[Symbol.toStringTag] = 1; +assertTag("Function", gen); + +function overwriteToStringTagWithNonStringValue(tag, obj) { + assertTag(tag, obj); + + Object.defineProperty(obj, Symbol.toStringTag, { + configurable: true, + value: "different string" + }); + assertTag("different string", obj); + + testObjectToStringOnNonStringValue(obj); +} + +overwriteToStringTagWithNonStringValue("global", global); +overwriteToStringTagWithNonStringValue("Generator", gen()); + +var arrayBuffer = new ArrayBuffer(); +overwriteToStringTagWithNonStringValue("ArrayBuffer", arrayBuffer); +overwriteToStringTagWithNonStringValue("DataView", new DataView(arrayBuffer)); + +overwriteToStringTagWithNonStringValue("Int8Array", new Int8Array()); +overwriteToStringTagWithNonStringValue("Uint8Array", new Uint8Array()); +overwriteToStringTagWithNonStringValue("Uint8ClampedArray", + new Uint8ClampedArray()); +overwriteToStringTagWithNonStringValue("Int16Array", new Int16Array()); +overwriteToStringTagWithNonStringValue("Uint16Array", new Uint16Array()); +overwriteToStringTagWithNonStringValue("Int32Array", new Int32Array()); +overwriteToStringTagWithNonStringValue("Uint32Array", new Uint32Array()); +overwriteToStringTagWithNonStringValue("Float32Array", new Float32Array()); +overwriteToStringTagWithNonStringValue("Float64Array", new Float64Array()); + +var set = new Set(); +var map = new Map(); + +overwriteToStringTagWithNonStringValue("Set", set); +overwriteToStringTagWithNonStringValue("Map", map); + +overwriteToStringTagWithNonStringValue("Set Iterator", set[Symbol.iterator]()); +overwriteToStringTagWithNonStringValue("Map Iterator", map[Symbol.iterator]()); + +overwriteToStringTagWithNonStringValue("WeakSet", new WeakSet()); +overwriteToStringTagWithNonStringValue("WeakMap", new WeakMap()); + +overwriteToStringTagWithNonStringValue("Promise", new Promise(function() {})); diff --git a/deps/v8/test/mjsunit/es6/pattern-brand-check.js b/deps/v8/test/mjsunit/es6/pattern-brand-check.js index 9b0c0111ef..2e3229481f 100644 --- a/deps/v8/test/mjsunit/es6/pattern-brand-check.js +++ b/deps/v8/test/mjsunit/es6/pattern-brand-check.js @@ -2,8 +2,6 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// Flags: --harmony-regexp-subclass - function createNonRegExp(calls) { return { get [Symbol.match]() { diff --git a/deps/v8/test/mjsunit/es6/promise-internal-setter.js b/deps/v8/test/mjsunit/es6/promise-internal-setter.js index 20d361f623..bf0045a98b 100644 --- a/deps/v8/test/mjsunit/es6/promise-internal-setter.js +++ b/deps/v8/test/mjsunit/es6/promise-internal-setter.js @@ -2,8 +2,6 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// Flags: --promise-extra - 'use strict'; Object.defineProperties(Object.prototype, { @@ -16,4 +14,3 @@ class P extends Promise {} P.all([Promise.resolve('ok')]); P.race([Promise.resolve('ok')]); -P.defer(); diff --git a/deps/v8/test/mjsunit/es6/promise-species.js b/deps/v8/test/mjsunit/es6/promise-species.js new file mode 100644 index 0000000000..f6f2e7a1b5 --- /dev/null +++ b/deps/v8/test/mjsunit/es6/promise-species.js @@ -0,0 +1,42 @@ +// Copyright 2015 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Flags: --allow-natives-syntax + +// Test that Promises use @@species appropriately + +// Another constructor with no species will not be instantiated +var test = new Promise(function(){}); +var bogoCount = 0; +function bogusConstructor() { bogoCount++; } +test.constructor = bogusConstructor; +assertTrue(Promise.resolve(test) instanceof Promise); +assertFalse(Promise.resolve(test) instanceof bogusConstructor); +// Tests that chromium:575314 is fixed thoroughly +Promise.resolve(test).catch(e => %AbortJS("Error " + e)).then(() => { + if (bogoCount != 0) %AbortJS("bogoCount was " + bogoCount + " should be 0"); +}); + +// If there is a species, it will be instantiated +// @@species will be read exactly once, and the constructor is called with a +// function +var count = 0; +var params; +class MyPromise extends Promise { + constructor(...args) { + super(...args); + params = args; + } + static get [Symbol.species]() { + count++ + return this; + } +} + +var myPromise = MyPromise.resolve().then(); +assertEquals(1, count); +assertEquals(1, params.length); +assertEquals('function', typeof(params[0])); +assertTrue(myPromise instanceof MyPromise); +assertTrue(myPromise instanceof Promise); diff --git a/deps/v8/test/mjsunit/es6/promises.js b/deps/v8/test/mjsunit/es6/promises.js index 4eb539cbd5..0af7a882e7 100644 --- a/deps/v8/test/mjsunit/es6/promises.js +++ b/deps/v8/test/mjsunit/es6/promises.js @@ -25,7 +25,7 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// Flags: --allow-natives-syntax --promise-extra +// Flags: --allow-natives-syntax // Make sure we don't rely on functions patchable by monkeys. var call = Function.prototype.call.call.bind(Function.prototype.call) @@ -82,6 +82,12 @@ for (var i in globals) { } +function defer(constructor) { + var resolve, reject; + var promise = new constructor((res, rej) => { resolve = res; reject = rej }); + return { promise, resolve, reject }; +} + var asyncAssertsExpected = 0; function assertAsyncRan() { ++asyncAssertsExpected } @@ -141,7 +147,7 @@ function assertAsyncDone(iteration) { })(); (function() { - (new Promise(function() { throw 5 })).chain( + (new Promise(function() { throw 5 })).then( assertUnreachable, function(r) { assertAsync(r === 5, "new-throw") } ) @@ -149,29 +155,21 @@ function assertAsyncDone(iteration) { })(); (function() { - Promise.accept(5); - Promise.accept(5).chain(undefined, assertUnreachable).chain( - function(x) { assertAsync(x === 5, "resolved/chain-nohandler") }, + Promise.resolve(5); + Promise.resolve(5).then(undefined, assertUnreachable).then( + function(x) { assertAsync(x === 5, "resolved/then-nohandler") }, assertUnreachable ) assertAsyncRan() })(); (function() { - Promise.reject(5).chain(assertUnreachable, undefined).chain( - assertUnreachable, - function(r) { assertAsync(r === 5, "rejected/chain-nohandler") } - ) - assertAsyncRan() -})(); - -(function() { - Promise.accept(5).then(undefined, assertUnreachable).chain( + Promise.resolve(5).then(undefined, assertUnreachable).then( function(x) { assertAsync(x === 5, "resolved/then-nohandler-undefined") }, assertUnreachable ) assertAsyncRan() - Promise.accept(6).then(null, assertUnreachable).chain( + Promise.resolve(6).then(null, assertUnreachable).then( function(x) { assertAsync(x === 6, "resolved/then-nohandler-null") }, assertUnreachable ) @@ -179,34 +177,9 @@ function assertAsyncDone(iteration) { })(); (function() { - Promise.reject(5).then(assertUnreachable, undefined).chain( - assertUnreachable, - function(r) { assertAsync(r === 5, "rejected/then-nohandler-undefined") } - ) - assertAsyncRan() - Promise.reject(6).then(assertUnreachable, null).chain( - assertUnreachable, - function(r) { assertAsync(r === 6, "rejected/then-nohandler-null") } - ) - assertAsyncRan() -})(); - -(function() { - var p1 = Promise.accept(5) - var p2 = Promise.accept(p1) - var p3 = Promise.accept(p2) - // Note: Chain now has then-style semantics, here and in future tests. - p3.chain( - function(x) { assertAsync(x === 5, "resolved/chain") }, - assertUnreachable - ) - assertAsyncRan() -})(); - -(function() { - var p1 = Promise.accept(5) - var p2 = Promise.accept(p1) - var p3 = Promise.accept(p2) + var p1 = Promise.resolve(5) + var p2 = Promise.resolve(p1) + var p3 = Promise.resolve(p2) p3.then( function(x) { assertAsync(x === 5, "resolved/then") }, assertUnreachable @@ -216,19 +189,8 @@ function assertAsyncDone(iteration) { (function() { var p1 = Promise.reject(5) - var p2 = Promise.accept(p1) - var p3 = Promise.accept(p2) - p3.chain( - assertUnreachable, - function(x) { assertAsync(x === 5, "rejected/chain") } - ) - assertAsyncRan() -})(); - -(function() { - var p1 = Promise.reject(5) - var p2 = Promise.accept(p1) - var p3 = Promise.accept(p2) + var p2 = Promise.resolve(p1) + var p3 = Promise.resolve(p2) p3.then( assertUnreachable, function(x) { assertAsync(x === 5, "rejected/then") } @@ -237,87 +199,21 @@ function assertAsyncDone(iteration) { })(); (function() { - var p1 = Promise.accept(5) - var p2 = Promise.accept(p1) - var p3 = Promise.accept(p2) - p3.chain(function(x) { return x }, assertUnreachable).chain( - function(x) { assertAsync(x === 5, "resolved/chain/chain") }, - assertUnreachable - ) - assertAsyncRan() -})(); - -(function() { - var p1 = Promise.accept(5) - var p2 = Promise.accept(p1) - var p3 = Promise.accept(p2) - p3.chain(function(x) { return x }, assertUnreachable).then( - function(x) { assertAsync(x === 5, "resolved/chain/then") }, - assertUnreachable - ) - assertAsyncRan() -})(); - -(function() { - var p1 = Promise.accept(5) - var p2 = Promise.accept(p1) - var p3 = Promise.accept(p2) - p3.chain(function(x) { return 6 }, assertUnreachable).chain( - function(x) { assertAsync(x === 6, "resolved/chain/chain2") }, - assertUnreachable - ) - assertAsyncRan() -})(); - -(function() { - var p1 = Promise.accept(5) - var p2 = Promise.accept(p1) - var p3 = Promise.accept(p2) - p3.chain(function(x) { return 6 }, assertUnreachable).then( - function(x) { assertAsync(x === 6, "resolved/chain/then2") }, - assertUnreachable - ) - assertAsyncRan() -})(); - -(function() { - var p1 = Promise.accept(5) - var p2 = Promise.accept(p1) - var p3 = Promise.accept(p2) - p3.then(function(x) { return x + 1 }, assertUnreachable).chain( - function(x) { assertAsync(x === 6, "resolved/then/chain") }, - assertUnreachable - ) - assertAsyncRan() -})(); - -(function() { - var p1 = Promise.accept(5) - var p2 = Promise.accept(p1) - var p3 = Promise.accept(p2) - p3.then(function(x) { return x + 1 }, assertUnreachable).then( - function(x) { assertAsync(x === 6, "resolved/then/then") }, - assertUnreachable - ) - assertAsyncRan() -})(); - -(function() { - var p1 = Promise.accept(5) - var p2 = Promise.accept(p1) - var p3 = Promise.accept(p2) - p3.then(function(x){ return Promise.accept(x+1) }, assertUnreachable).chain( - function(x) { assertAsync(x === 6, "resolved/then/chain2") }, + var p1 = Promise.resolve(5) + var p2 = Promise.resolve(p1) + var p3 = Promise.resolve(p2) + p3.then(function(x) { return x }, assertUnreachable).then( + function(x) { assertAsync(x === 5, "resolved/then/then") }, assertUnreachable ) assertAsyncRan() })(); (function() { - var p1 = Promise.accept(5) - var p2 = Promise.accept(p1) - var p3 = Promise.accept(p2) - p3.then(function(x) { return Promise.accept(x+1) }, assertUnreachable).then( + var p1 = Promise.resolve(5) + var p2 = Promise.resolve(p1) + var p3 = Promise.resolve(p2) + p3.then(function(x){ return Promise.resolve(x+1) }, assertUnreachable).then( function(x) { assertAsync(x === 6, "resolved/then/then2") }, assertUnreachable ) @@ -325,42 +221,42 @@ function assertAsyncDone(iteration) { })(); (function() { - var p1 = Promise.accept(5) - var p2 = Promise.accept(p1) - var p3 = Promise.accept(p2) - p3.chain(function(x) { throw 6 }, assertUnreachable).chain( + var p1 = Promise.resolve(5) + var p2 = Promise.resolve(p1) + var p3 = Promise.resolve(p2) + p3.then(function(x) { throw 6 }, assertUnreachable).then( assertUnreachable, - function(x) { assertAsync(x === 6, "resolved/chain-throw/chain") } + function(x) { assertAsync(x === 6, "resolved/then-throw/then") } ) assertAsyncRan() })(); (function() { - var p1 = Promise.accept(5) - var p2 = Promise.accept(p1) - var p3 = Promise.accept(p2) - p3.chain(function(x) { throw 6 }, assertUnreachable).then( + var p1 = Promise.resolve(5) + var p2 = Promise.resolve(p1) + var p3 = Promise.resolve(p2) + p3.then(function(x) { throw 6 }, assertUnreachable).then( assertUnreachable, - function(x) { assertAsync(x === 6, "resolved/chain-throw/then") } + function(x) { assertAsync(x === 6, "resolved/then-throw/then") } ) assertAsyncRan() })(); (function() { - var p1 = Promise.accept(5) - var p2 = Promise.accept(p1) - var p3 = Promise.accept(p2) - p3.then(function(x) { throw 6 }, assertUnreachable).chain( + var p1 = Promise.resolve(5) + var p2 = Promise.resolve(p1) + var p3 = Promise.resolve(p2) + p3.then(function(x) { throw 6 }, assertUnreachable).then( assertUnreachable, - function(x) { assertAsync(x === 6, "resolved/then-throw/chain") } + function(x) { assertAsync(x === 6, "resolved/then-throw/then") } ) assertAsyncRan() })(); (function() { - var p1 = Promise.accept(5) - var p2 = Promise.accept(p1) - var p3 = Promise.accept(p2) + var p1 = Promise.resolve(5) + var p2 = Promise.resolve(p1) + var p3 = Promise.resolve(p2) p3.then(function(x) { throw 6 }, assertUnreachable).then( assertUnreachable, function(x) { assertAsync(x === 6, "resolved/then-throw/then") } @@ -369,20 +265,20 @@ function assertAsyncDone(iteration) { })(); (function() { - var p1 = Promise.accept(5) + var p1 = Promise.resolve(5) var p2 = {then: function(onResolve, onReject) { onResolve(p1) }} - var p3 = Promise.accept(p2) - p3.chain( - function(x) { assertAsync(x === 5, "resolved/thenable/chain") }, + var p3 = Promise.resolve(p2) + p3.then( + function(x) { assertAsync(x === 5, "resolved/thenable/then") }, assertUnreachable ) assertAsyncRan() })(); (function() { - var p1 = Promise.accept(5) + var p1 = Promise.resolve(5) var p2 = {then: function(onResolve, onReject) { onResolve(p1) }} - var p3 = Promise.accept(p2) + var p3 = Promise.resolve(p2) p3.then( function(x) { assertAsync(x === 5, "resolved/thenable/then") }, assertUnreachable @@ -393,10 +289,10 @@ function assertAsyncDone(iteration) { (function() { var p1 = Promise.reject(5) var p2 = {then: function(onResolve, onReject) { onResolve(p1) }} - var p3 = Promise.accept(p2) - p3.chain( + var p3 = Promise.resolve(p2) + p3.then( assertUnreachable, - function(x) { assertAsync(x === 5, "rejected/thenable/chain") } + function(x) { assertAsync(x === 5, "rejected/thenable/then") } ) assertAsyncRan() })(); @@ -404,7 +300,7 @@ function assertAsyncDone(iteration) { (function() { var p1 = Promise.reject(5) var p2 = {then: function(onResolve, onReject) { onResolve(p1) }} - var p3 = Promise.accept(p2) + var p3 = Promise.resolve(p2) p3.then( assertUnreachable, function(x) { assertAsync(x === 5, "rejected/thenable/then") } @@ -413,12 +309,12 @@ function assertAsyncDone(iteration) { })(); (function() { - var deferred = Promise.defer() + var deferred = defer(Promise) var p1 = deferred.promise - var p2 = Promise.accept(p1) - var p3 = Promise.accept(p2) - p3.chain( - function(x) { assertAsync(x === 5, "chain/resolve") }, + var p2 = Promise.resolve(p1) + var p3 = Promise.resolve(p2) + p3.then( + function(x) { assertAsync(x === 5, "then/resolve") }, assertUnreachable ) deferred.resolve(5) @@ -426,7 +322,7 @@ function assertAsyncDone(iteration) { })(); (function() { - var deferred = Promise.defer() + var deferred = defer(Promise) var p1 = deferred.promise var p2 = Promise.resolve(p1) var p3 = Promise.resolve(p2) @@ -439,23 +335,23 @@ function assertAsyncDone(iteration) { })(); (function() { - var deferred = Promise.defer() + var deferred = defer(Promise) var p1 = deferred.promise - var p2 = Promise.accept(p1) - var p3 = Promise.accept(p2) - p3.chain( + var p2 = Promise.resolve(p1) + var p3 = Promise.resolve(p2) + p3.then( assertUnreachable, - function(x) { assertAsync(x === 5, "chain/reject") } + function(x) { assertAsync(x === 5, "then/reject") } ) deferred.reject(5) assertAsyncRan() })(); (function() { - var deferred = Promise.defer() + var deferred = defer(Promise) var p1 = deferred.promise - var p2 = Promise.accept(p1) - var p3 = Promise.accept(p2) + var p2 = Promise.resolve(p1) + var p3 = Promise.resolve(p2) p3.then( assertUnreachable, function(x) { assertAsync(x === 5, "then/reject") } @@ -465,7 +361,7 @@ function assertAsyncDone(iteration) { })(); (function() { - var deferred = Promise.defer() + var deferred = defer(Promise) var p1 = deferred.promise var p2 = p1.then(1, 2) p2.then( @@ -477,7 +373,7 @@ function assertAsyncDone(iteration) { })(); (function() { - var deferred = Promise.defer() + var deferred = defer(Promise) var p1 = deferred.promise var p2 = p1.then(1, 2) p2.then( @@ -489,12 +385,12 @@ function assertAsyncDone(iteration) { })(); (function() { - var deferred = Promise.defer() + var deferred = defer(Promise) var p1 = deferred.promise var p2 = {then: function(onResolve, onReject) { onResolve(p1) }} - var p3 = Promise.accept(p2) - p3.chain( - function(x) { assertAsync(x === 5, "chain/resolve/thenable") }, + var p3 = Promise.resolve(p2) + p3.then( + function(x) { assertAsync(x === 5, "then/resolve/thenable") }, assertUnreachable ) deferred.resolve(5) @@ -502,10 +398,10 @@ function assertAsyncDone(iteration) { })(); (function() { - var deferred = Promise.defer() + var deferred = defer(Promise) var p1 = deferred.promise var p2 = {then: function(onResolve, onReject) { onResolve(p1) }} - var p3 = Promise.accept(p2) + var p3 = Promise.resolve(p2) p3.then( function(x) { assertAsync(x === 5, "then/resolve/thenable") }, assertUnreachable @@ -515,23 +411,23 @@ function assertAsyncDone(iteration) { })(); (function() { - var deferred = Promise.defer() + var deferred = defer(Promise) var p1 = deferred.promise var p2 = {then: function(onResolve, onReject) { onResolve(p1) }} - var p3 = Promise.accept(p2) - p3.chain( + var p3 = Promise.resolve(p2) + p3.then( assertUnreachable, - function(x) { assertAsync(x === 5, "chain/reject/thenable") } + function(x) { assertAsync(x === 5, "then/reject/thenable") } ) deferred.reject(5) assertAsyncRan() })(); (function() { - var deferred = Promise.defer() + var deferred = defer(Promise) var p1 = deferred.promise var p2 = {then: function(onResolve, onReject) { onResolve(p1) }} - var p3 = Promise.accept(p2) + var p3 = Promise.resolve(p2) p3.then( assertUnreachable, function(x) { assertAsync(x === 5, "then/reject/thenable") } @@ -541,12 +437,12 @@ function assertAsyncDone(iteration) { })(); (function() { - var p1 = Promise.accept(5) - var p2 = Promise.accept(p1) - var deferred = Promise.defer() + var p1 = Promise.resolve(5) + var p2 = Promise.resolve(p1) + var deferred = defer(Promise) var p3 = deferred.promise - p3.chain( - function(x) { assertAsync(x === 5, "chain/resolve2") }, + p3.then( + function(x) { assertAsync(x === 5, "then/resolve2") }, assertUnreachable ) deferred.resolve(p2) @@ -554,9 +450,9 @@ function assertAsyncDone(iteration) { })(); (function() { - var p1 = Promise.accept(5) - var p2 = Promise.accept(p1) - var deferred = Promise.defer() + var p1 = Promise.resolve(5) + var p2 = Promise.resolve(p1) + var deferred = defer(Promise) var p3 = deferred.promise p3.then( function(x) { assertAsync(x === 5, "then/resolve2") }, @@ -567,22 +463,22 @@ function assertAsyncDone(iteration) { })(); (function() { - var p1 = Promise.accept(5) - var p2 = Promise.accept(p1) - var deferred = Promise.defer() + var p1 = Promise.resolve(5) + var p2 = Promise.resolve(p1) + var deferred = defer(Promise) var p3 = deferred.promise - p3.chain( + p3.then( assertUnreachable, - function(x) { assertAsync(x === 5, "chain/reject2") } + function(x) { assertAsync(x === 5, "then/reject2") } ) deferred.reject(5) assertAsyncRan() })(); (function() { - var p1 = Promise.accept(5) - var p2 = Promise.accept(p1) - var deferred = Promise.defer() + var p1 = Promise.resolve(5) + var p2 = Promise.resolve(p1) + var deferred = defer(Promise) var p3 = deferred.promise p3.then( assertUnreachable, @@ -593,12 +489,12 @@ function assertAsyncDone(iteration) { })(); (function() { - var p1 = Promise.accept(5) + var p1 = Promise.resolve(5) var p2 = {then: function(onResolve, onReject) { onResolve(p1) }} - var deferred = Promise.defer() + var deferred = defer(Promise) var p3 = deferred.promise - p3.chain( - function(x) { assertAsync(x === 5, "chain/resolve/thenable2") }, + p3.then( + function(x) { assertAsync(x === 5, "then/resolve/thenable2") }, assertUnreachable ) deferred.resolve(p2) @@ -606,9 +502,9 @@ function assertAsyncDone(iteration) { })(); (function() { - var p1 = Promise.accept(5) + var p1 = Promise.resolve(5) var p2 = {then: function(onResolve, onReject) { onResolve(p1) }} - var deferred = Promise.defer() + var deferred = defer(Promise) var p3 = deferred.promise p3.then( function(x) { assertAsync(x === 5, "then/resolve/thenable2") }, @@ -619,19 +515,19 @@ function assertAsyncDone(iteration) { })(); (function() { - var p1 = Promise.accept(0) - var p2 = p1.chain(function(x) { return p2 }, assertUnreachable) - p2.chain( + var p1 = Promise.resolve(0) + var p2 = p1.then(function(x) { return p2 }, assertUnreachable) + p2.then( assertUnreachable, - function(r) { assertAsync(r instanceof TypeError, "cyclic/chain") } + function(r) { assertAsync(r instanceof TypeError, "cyclic/then") } ) assertAsyncRan() })(); (function() { - var p1 = Promise.accept(0) + var p1 = Promise.resolve(0) var p2 = p1.then(function(x) { return p2 }, assertUnreachable) - p2.chain( + p2.then( assertUnreachable, function(r) { assertAsync(r instanceof TypeError, "cyclic/then") } ) @@ -639,10 +535,10 @@ function assertAsyncDone(iteration) { })(); (function() { - var deferred = Promise.defer() + var deferred = defer(Promise) var p = deferred.promise deferred.resolve(p) - p.chain( + p.then( assertUnreachable, function(r) { assertAsync(r instanceof TypeError, "cyclic/deferred/then") } ) @@ -650,7 +546,7 @@ function assertAsyncDone(iteration) { })(); (function() { - var deferred = Promise.defer() + var deferred = defer(Promise) var p = deferred.promise deferred.resolve(p) p.then( @@ -661,7 +557,7 @@ function assertAsyncDone(iteration) { })(); (function() { - Promise.all([]).chain( + Promise.all([]).then( function(x) { assertAsync(x.length === 0, "all/resolve/empty") }, assertUnreachable ) @@ -670,7 +566,7 @@ function assertAsyncDone(iteration) { (function() { function testPromiseAllNonIterable(value) { - Promise.all(value).chain( + Promise.all(value).then( assertUnreachable, function(r) { assertAsync(r instanceof TypeError, 'all/non iterable'); @@ -684,14 +580,14 @@ function assertAsyncDone(iteration) { })(); (function() { - var deferred = Promise.defer(); + var deferred = defer(Promise); var p = deferred.promise; function* f() { yield 1; yield p; yield 3; } - Promise.all(f()).chain( + Promise.all(f()).then( function(x) { assertAsync(x.length === 3, "all/resolve/iterable"); assertAsync(x[0] === 1, "all/resolve/iterable/0"); @@ -708,13 +604,13 @@ function assertAsyncDone(iteration) { (function() { - var deferred1 = Promise.defer() + var deferred1 = defer(Promise) var p1 = deferred1.promise - var deferred2 = Promise.defer() + var deferred2 = defer(Promise) var p2 = deferred2.promise - var deferred3 = Promise.defer() + var deferred3 = defer(Promise) var p3 = deferred3.promise - Promise.all([p1, p2, p3]).chain( + Promise.all([p1, p2, p3]).then( function(x) { assertAsync(x.length === 3, "all/resolve") assertAsync(x[0] === 1, "all/resolve/0") @@ -733,11 +629,11 @@ function assertAsyncDone(iteration) { })(); (function() { - var deferred = Promise.defer() + var deferred = defer(Promise) var p1 = deferred.promise - var p2 = Promise.accept(2) - var p3 = Promise.defer().promise - Promise.all([p1, p2, p3]).chain( + var p2 = Promise.resolve(2) + var p3 = defer(Promise).promise + Promise.all([p1, p2, p3]).then( assertUnreachable, assertUnreachable ) @@ -745,13 +641,13 @@ function assertAsyncDone(iteration) { })(); (function() { - var deferred1 = Promise.defer() + var deferred1 = defer(Promise) var p1 = deferred1.promise - var deferred2 = Promise.defer() + var deferred2 = defer(Promise) var p2 = deferred2.promise - var deferred3 = Promise.defer() + var deferred3 = defer(Promise) var p3 = deferred3.promise - Promise.all([p1, p2, p3]).chain( + Promise.all([p1, p2, p3]).then( assertUnreachable, function(x) { assertAsync(x === 2, "all/reject") } ) @@ -786,7 +682,7 @@ function assertAsyncDone(iteration) { configurable: true }); - Promise.all(3).chain( + Promise.all(3).then( function(x) { assertAsync(x.length === 3, "all/iterable/number/length"); assertAsync(x[0] === 0, "all/iterable/number/0"); @@ -807,17 +703,17 @@ function assertAsyncDone(iteration) { (function() { - Promise.race([]).chain( + Promise.race([]).then( assertUnreachable, assertUnreachable ) })(); (function() { - var p1 = Promise.accept(1) - var p2 = Promise.accept(2) - var p3 = Promise.accept(3) - Promise.race([p1, p2, p3]).chain( + var p1 = Promise.resolve(1) + var p2 = Promise.resolve(2) + var p3 = Promise.resolve(3) + Promise.race([p1, p2, p3]).then( function(x) { assertAsync(x === 1, "resolved/one") }, assertUnreachable ) @@ -825,10 +721,10 @@ function assertAsyncDone(iteration) { })(); (function() { - var p1 = Promise.accept(1) - var p2 = Promise.accept(2) - var p3 = Promise.accept(3) - Promise.race([0, p1, p2, p3]).chain( + var p1 = Promise.resolve(1) + var p2 = Promise.resolve(2) + var p3 = Promise.resolve(3) + Promise.race([0, p1, p2, p3]).then( function(x) { assertAsync(x === 0, "resolved-const/one") }, assertUnreachable ) @@ -836,13 +732,13 @@ function assertAsyncDone(iteration) { })(); (function() { - var deferred1 = Promise.defer() + var deferred1 = defer(Promise) var p1 = deferred1.promise - var deferred2 = Promise.defer() + var deferred2 = defer(Promise) var p2 = deferred2.promise - var deferred3 = Promise.defer() + var deferred3 = defer(Promise) var p3 = deferred3.promise - Promise.race([p1, p2, p3]).chain( + Promise.race([p1, p2, p3]).then( function(x) { assertAsync(x === 3, "one/resolve") }, assertUnreachable ) @@ -852,11 +748,11 @@ function assertAsyncDone(iteration) { })(); (function() { - var deferred = Promise.defer() + var deferred = defer(Promise) var p1 = deferred.promise - var p2 = Promise.accept(2) - var p3 = Promise.defer().promise - Promise.race([p1, p2, p3]).chain( + var p2 = Promise.resolve(2) + var p3 = defer(Promise).promise + Promise.race([p1, p2, p3]).then( function(x) { assertAsync(x === 2, "resolved/one") }, assertUnreachable ) @@ -865,13 +761,13 @@ function assertAsyncDone(iteration) { })(); (function() { - var deferred1 = Promise.defer() + var deferred1 = defer(Promise) var p1 = deferred1.promise - var deferred2 = Promise.defer() + var deferred2 = defer(Promise) var p2 = deferred2.promise - var deferred3 = Promise.defer() + var deferred3 = defer(Promise) var p3 = deferred3.promise - Promise.race([p1, p2, p3]).chain( + Promise.race([p1, p2, p3]).then( function(x) { assertAsync(x === 3, "one/resolve/reject") }, assertUnreachable ) @@ -881,13 +777,13 @@ function assertAsyncDone(iteration) { })(); (function() { - var deferred1 = Promise.defer() + var deferred1 = defer(Promise) var p1 = deferred1.promise - var deferred2 = Promise.defer() + var deferred2 = defer(Promise) var p2 = deferred2.promise - var deferred3 = Promise.defer() + var deferred3 = defer(Promise) var p3 = deferred3.promise - Promise.race([p1, p2, p3]).chain( + Promise.race([p1, p2, p3]).then( assertUnreachable, function(x) { assertAsync(x === 3, "one/reject/resolve") } ) @@ -899,7 +795,7 @@ function assertAsyncDone(iteration) { (function() { function testPromiseRaceNonIterable(value) { - Promise.race(value).chain( + Promise.race(value).then( assertUnreachable, function(r) { assertAsync(r instanceof TypeError, 'race/non iterable'); @@ -914,18 +810,18 @@ function assertAsyncDone(iteration) { (function() { - var deferred1 = Promise.defer() + var deferred1 = defer(Promise) var p1 = deferred1.promise - var deferred2 = Promise.defer() + var deferred2 = defer(Promise) var p2 = deferred2.promise - var deferred3 = Promise.defer() + var deferred3 = defer(Promise) var p3 = deferred3.promise function* f() { yield p1; yield p2; yield p3; } - Promise.race(f()).chain( + Promise.race(f()).then( function(x) { assertAsync(x === 3, "race/iterable/resolve/reject") }, assertUnreachable ) @@ -935,18 +831,18 @@ function assertAsyncDone(iteration) { })(); (function() { - var deferred1 = Promise.defer() + var deferred1 = defer(Promise) var p1 = deferred1.promise - var deferred2 = Promise.defer() + var deferred2 = defer(Promise) var p2 = deferred2.promise - var deferred3 = Promise.defer() + var deferred3 = defer(Promise) var p3 = deferred3.promise function* f() { yield p1; yield p2; yield p3; } - Promise.race(f()).chain( + Promise.race(f()).then( assertUnreachable, function(x) { assertAsync(x === 3, "race/iterable/reject/resolve") } ) @@ -980,7 +876,7 @@ function assertAsyncDone(iteration) { configurable: true }); - Promise.race(3).chain( + Promise.race(3).then( function(x) { assertAsync(x === 0, "race/iterable/number"); }, @@ -1014,18 +910,18 @@ function assertAsyncDone(iteration) { } MyPromise.prototype.__proto__ = Promise.prototype - MyPromise.prototype.chain = function(resolve, reject) { + MyPromise.prototype.then = function(resolve, reject) { log += "c" - return call(this.__proto__.__proto__.chain, this, resolve, reject) + return call(this.__proto__.__proto__.then, this, resolve, reject) } log = "" var p1 = new MyPromise(function(resolve, reject) { resolve(1) }) var p2 = new MyPromise(function(resolve, reject) { reject(2) }) - var d3 = MyPromise.defer() + var d3 = defer(MyPromise) assertTrue(d3.promise instanceof Promise, "subclass/instance") assertTrue(d3.promise instanceof MyPromise, "subclass/instance-my3") - assertTrue(log === "nx1nr2dn", "subclass/create") + assertTrue(log === "nx1nr2n", "subclass/create") log = "" var p4 = MyPromise.resolve(4) @@ -1038,21 +934,21 @@ function assertAsyncDone(iteration) { assertTrue(log === "nx4nr5x3", "subclass/resolve") log = "" - var d6 = MyPromise.defer() - d6.promise.chain(function(x) { + var d6 = defer(MyPromise) + d6.promise.then(function(x) { return new Promise(function(resolve) { resolve(x) }) - }).chain(function() {}) + }).then(function() {}) d6.resolve(6) - assertTrue(log === "dncncnx6", "subclass/chain") + assertTrue(log === "ncncnx6", "subclass/then") log = "" - Promise.all([11, Promise.accept(12), 13, MyPromise.accept(14), 15, 16]) + Promise.all([11, Promise.resolve(12), 13, MyPromise.resolve(14), 15, 16]) assertTrue(log === "nx14", "subclass/all/arg") log = "" - MyPromise.all([21, Promise.accept(22), 23, MyPromise.accept(24), 25, 26]) - assertTrue(log === "nx24nnx21nnx[object Promise]nnx23nnnx25nnx26n", + MyPromise.all([21, Promise.resolve(22), 23, MyPromise.resolve(24), 25, 26]) + assertTrue(log === "nx24nnx21cnnx[object Promise]cnnx23cncnnx25cnnx26cn", "subclass/all/self") })(); diff --git a/deps/v8/test/mjsunit/es6/proxies-for.js b/deps/v8/test/mjsunit/es6/proxies-for.js index 5b818453a9..2b3060b17e 100644 --- a/deps/v8/test/mjsunit/es6/proxies-for.js +++ b/deps/v8/test/mjsunit/es6/proxies-for.js @@ -151,7 +151,7 @@ function keys(object) { object.__proto__ = proxy; assertEquals(["0"], keys(object)); - // The Proxy doesn't set his ownKeys enumerable. + // The Proxy doesn't set its ownKeys enumerable. delete object[0]; assertEquals([], keys(object)); @@ -209,10 +209,15 @@ function keys(object) { assertThrowsEquals(() => {keys(proxy)}, "error"); })(); - -(function () { - var symbol = Symbol(); - var p = new Proxy({}, {ownKeys() { return ["1", symbol, "2"] }}); - assertEquals(["1","2"], Object.getOwnPropertyNames(p)); - assertEquals([symbol], Object.getOwnPropertySymbols(p)); +(function testNestedProxy() { + var handler = { + ownKeys() { + return ['c']; + }, + getOwnPropertyDescriptor() { return {configurable: true, enumerable: true } } + } + var proxy = new Proxy({}, handler); + var proxy2 = new Proxy(proxy, {}); + assertEquals(['c'], keys(proxy)); + assertEquals(['c'], keys(proxy2)); })(); diff --git a/deps/v8/test/mjsunit/es6/proxies-global-reference.js b/deps/v8/test/mjsunit/es6/proxies-global-reference.js index 975d7f75fb..1e3d3beb86 100644 --- a/deps/v8/test/mjsunit/es6/proxies-global-reference.js +++ b/deps/v8/test/mjsunit/es6/proxies-global-reference.js @@ -5,8 +5,5 @@ var failing_proxy = new Proxy({}, new Proxy({}, { get() { throw "No trap should fire" }})); -Object.setPrototypeOf(Object.prototype, failing_proxy); -assertThrows(()=>a, TypeError); - -Object.setPrototypeOf(this, failing_proxy); -assertThrows(()=>a, TypeError); +assertThrows(() => Object.setPrototypeOf(Object.prototype, failing_proxy), TypeError); +assertThrows(()=>a, ReferenceError); diff --git a/deps/v8/test/mjsunit/es6/proxies-json.js b/deps/v8/test/mjsunit/es6/proxies-json.js index d48d5390f6..6b40e3ee7d 100644 --- a/deps/v8/test/mjsunit/es6/proxies-json.js +++ b/deps/v8/test/mjsunit/es6/proxies-json.js @@ -35,7 +35,10 @@ function testStringify(expected, object) { // Test fast case that bails out to slow case. assertEquals(expected, JSON.stringify(object)); // Test slow case. - assertEquals(expected, JSON.stringify(object, undefined, 0)); + assertEquals(expected, JSON.stringify(object, (key, value) => value)); + // Test gap. + assertEquals(JSON.stringify(object, null, "="), + JSON.stringify(object, (key, value) => value, "=")); } @@ -67,6 +70,7 @@ testStringify('[1,null]', [1, proxy_fun]); var parent1a = { b: proxy1 }; testStringify('{"b":{"a":"A","b":"B","c":"C"}}', parent1a); +testStringify('{"b":{"a":"A","b":"B","c":"C"}}', parent1a); var parent1b = { a: 123, b: proxy1, c: true }; testStringify('{"a":123,"b":{"a":"A","b":"B","c":"C"},"c":true}', parent1b); @@ -503,3 +507,56 @@ for (var i in log) assertSame(target, log[i][1]); assertEquals(["get", target, "length", proxy], log[0]); assertEquals(["get", target, "0", proxy], log[1]); assertEquals(["deleteProperty", target, "0"], log[2]); + +proxy = new Proxy([], { + get: function(target, property) { + if (property == "length") return 7; + return 0; + }, +}); +assertEquals('[[0,0,0,0,0,0,0]]', JSON.stringify([proxy])); + +proxy = new Proxy([], { + get: function(target, property) { + if (property == "length") return 1E40; + return 0; + }, +}); +assertThrows(() => JSON.stringify([proxy]), RangeError); + +log = []; +proxy = new Proxy({}, { + ownKeys: function() { + log.push("ownKeys"); + return ["0", "a", "b"]; + }, + get: function(target, property) { + log.push("get " + property); + return property.toUpperCase(); + }, + getOwnPropertyDescriptor: function(target, property) { + log.push("descriptor " + property); + return {enumerable: true, configurable: true}; + }, + isExtensible: assertUnreachable, + has: assertUnreachable, + getPrototypeOf: assertUnreachable, + setPrototypeOf: assertUnreachable, + preventExtensions: assertUnreachable, + setPrototypeOf: assertUnreachable, + defineProperty: assertUnreachable, + set: assertUnreachable, + deleteProperty: assertUnreachable, + apply: assertUnreachable, + construct: assertUnreachable, +}); + +assertEquals('[{"0":"0","a":"A","b":"B"}]', JSON.stringify([proxy])); +assertEquals(['get toJSON', + 'ownKeys', + 'descriptor 0', + 'descriptor a', + 'descriptor b', + 'get 0', + 'get a', + 'get b'], log); diff --git a/deps/v8/test/mjsunit/es6/proxies-keys.js b/deps/v8/test/mjsunit/es6/proxies-keys.js index 7344032aaf..4781ae37f4 100644 --- a/deps/v8/test/mjsunit/es6/proxies-keys.js +++ b/deps/v8/test/mjsunit/es6/proxies-keys.js @@ -2,38 +2,82 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -var target = { - target: 1 -}; -target.__proto__ = { - target_proto: 2 -}; - -var handler = { - ownKeys: function(target) { - return ["foo", "bar", Symbol("baz"), "non-enum", "not-found"]; - }, - getOwnPropertyDescriptor: function(target, name) { - if (name == "non-enum") return {configurable: true}; - if (name == "not-found") return undefined; - return {enumerable: true, configurable: true}; +(function testObjectKeys() { + var target = { + target: 1 + }; + target.__proto__ = { + target_proto: 2 + }; + + var handler = { + ownKeys: function(target) { + return ["foo", "bar", Symbol("baz"), "non-enum", "not-found"]; + }, + getOwnPropertyDescriptor: function(target, name) { + if (name == "non-enum") return {configurable: true}; + if (name == "not-found") return undefined; + return {enumerable: true, configurable: true}; + } } -} -var proxy = new Proxy(target, handler); + var proxy = new Proxy(target, handler); + + // Object.keys() ignores symbols and non-enumerable keys. + assertEquals(["foo", "bar"], Object.keys(proxy)); + + // Edge case: no properties left after filtering. + handler.getOwnPropertyDescriptor = undefined; + assertEquals([], Object.keys(proxy)); + + // Throwing shouldn't crash. + handler.getOwnPropertyDescriptor = function() { throw new Number(1); }; + assertThrows(() => Object.keys(proxy), Number); + + // Fall through to getOwnPropertyDescriptor if there is no trap. + handler.ownKeys = undefined; + assertThrows(() => Object.keys(proxy), Number); + + // Fall through to target if there is no trap. + handler.getOwnPropertyDescriptor = undefined; + assertEquals(["target"], Object.keys(proxy)); + assertEquals(["target"], Object.keys(target)); -// Object.keys() ignores symbols and non-enumerable keys. -assertEquals(["foo", "bar"], Object.keys(proxy)); + var proxy2 = new Proxy(proxy, {}); + assertEquals(["target"], Object.keys(proxy2)); +})(); -// Edge case: no properties left after filtering. -handler.getOwnPropertyDescriptor = undefined; -assertEquals([], Object.keys(proxy)); +(function testForSymbols() { + var symbol = Symbol(); + var p = new Proxy({}, {ownKeys() { return ["1", symbol, "2"] }}); + assertEquals(["1","2"], Object.getOwnPropertyNames(p)); + assertEquals([symbol], Object.getOwnPropertySymbols(p)); +})(); -// Throwing shouldn't crash. -handler.getOwnPropertyDescriptor = function() { throw new Number(1); }; -assertThrows("Object.keys(proxy)", Number); +(function testNoProxyTraps() { + var test_sym = Symbol("sym1"); + var test_sym2 = Symbol("sym2"); + var target = { + one: 1, + two: 2, + [test_sym]: 4, + 0: 0, + }; + Object.defineProperty( + target, "non-enum", + { enumerable: false, value: "nope", configurable: true, writable: true }); + target.__proto__ = { + target_proto: 3, + 1: 1, + [test_sym2]: 5 + }; + Object.defineProperty( + target.__proto__, "non-enum2", + { enumerable: false, value: "nope", configurable: true, writable: true }); + var proxy = new Proxy(target, {}); -// Fall through to target if there is no trap. -handler.ownKeys = undefined; -assertEquals(["target"], Object.keys(proxy)); -assertEquals(["target"], Object.keys(target)); + assertEquals(["0", "one", "two"], Object.keys(proxy)); + assertEquals(["0", "one", "two", "non-enum"], + Object.getOwnPropertyNames(proxy)); + assertEquals([test_sym], Object.getOwnPropertySymbols(proxy)); +})(); diff --git a/deps/v8/test/mjsunit/es6/reflect-construct.js b/deps/v8/test/mjsunit/es6/reflect-construct.js index b37f876e94..4661b4093b 100644 --- a/deps/v8/test/mjsunit/es6/reflect-construct.js +++ b/deps/v8/test/mjsunit/es6/reflect-construct.js @@ -1,6 +1,8 @@ // Copyright 2014 the V8 project authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +// +// Flags: --allow-unsafe-function-constructor (function testReflectConstructArity() { diff --git a/deps/v8/test/mjsunit/es6/reflect-define-property.js b/deps/v8/test/mjsunit/es6/reflect-define-property.js index b19c5aa6ff..8eb3f6580e 100644 --- a/deps/v8/test/mjsunit/es6/reflect-define-property.js +++ b/deps/v8/test/mjsunit/es6/reflect-define-property.js @@ -441,53 +441,6 @@ try { } -// Test runtime calls to DefineDataPropertyUnchecked and -// DefineAccessorPropertyUnchecked - make sure we don't -// crash. -try { - %DefineAccessorPropertyUnchecked(0, 0, 0, 0, 0); -} catch (e) { - assertTrue(/illegal access/.test(e)); -} - -try { - %DefineDataPropertyUnchecked(0, 0, 0, 0); -} catch (e) { - assertTrue(/illegal access/.test(e)); -} - -try { - %DefineDataPropertyUnchecked(null, null, null, null); -} catch (e) { - assertTrue(/illegal access/.test(e)); -} - -try { - %DefineAccessorPropertyUnchecked(null, null, null, null, null); -} catch (e) { - assertTrue(/illegal access/.test(e)); -} - -try { - %DefineDataPropertyUnchecked({}, null, null, null); -} catch (e) { - assertTrue(/illegal access/.test(e)); -} - -// Defining properties null should fail even when we have -// other allowed values -try { - %DefineAccessorPropertyUnchecked(null, 'foo', func, null, 0); -} catch (e) { - assertTrue(/illegal access/.test(e)); -} - -try { - %DefineDataPropertyUnchecked(null, 'foo', 0, 0); -} catch (e) { - assertTrue(/illegal access/.test(e)); -} - // Test that all possible differences in step 6 in DefineOwnProperty are // exercised, i.e., any difference in the given property descriptor and the // existing properties should not return true, but throw an error if the diff --git a/deps/v8/test/mjsunit/es6/reflect.js b/deps/v8/test/mjsunit/es6/reflect.js index ee272b0fc7..d597a78901 100644 --- a/deps/v8/test/mjsunit/es6/reflect.js +++ b/deps/v8/test/mjsunit/es6/reflect.js @@ -541,6 +541,13 @@ function prepare(target) { [s2]: 0, "-1": 0, "88": 0, "aaa": 0 }; assertEquals(["0", "42", "88", "bla", "-1", "aaa", s1, s2], Reflect.ownKeys(obj)); + // Force dict-mode elements. + delete obj[0]; + assertEquals(["42", "88", "bla", "-1", "aaa", s1, s2], + Reflect.ownKeys(obj)); + // Force dict-mode properties. + delete obj["bla"]; + assertEquals(["42", "88", "-1", "aaa", s1, s2], Reflect.ownKeys(obj)); })(); diff --git a/deps/v8/test/mjsunit/es6/regexp-constructor.js b/deps/v8/test/mjsunit/es6/regexp-constructor.js index 559ac00cd0..b685ff2991 100644 --- a/deps/v8/test/mjsunit/es6/regexp-constructor.js +++ b/deps/v8/test/mjsunit/es6/regexp-constructor.js @@ -2,8 +2,6 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// Flags: --harmony-regexp-subclass - "use strict"; function should_not_be_called() { diff --git a/deps/v8/test/mjsunit/es6/regexp-flags.js b/deps/v8/test/mjsunit/es6/regexp-flags.js index 480222d95a..2bcccfa760 100644 --- a/deps/v8/test/mjsunit/es6/regexp-flags.js +++ b/deps/v8/test/mjsunit/es6/regexp-flags.js @@ -2,8 +2,6 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// Flags: --harmony-unicode-regexps - var r1 = /abc/gi; assertEquals("abc", r1.source); assertTrue(r1.global); diff --git a/deps/v8/test/mjsunit/es6/regress/regress-3750.js b/deps/v8/test/mjsunit/es6/regress/regress-3750.js deleted file mode 100644 index 10509bff51..0000000000 --- a/deps/v8/test/mjsunit/es6/regress/regress-3750.js +++ /dev/null @@ -1,9 +0,0 @@ -// Copyright 2014 the V8 project authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. -// -// Flags: --harmony-object-observe - -'use strict'; -class Example { } -Object.observe(Example.prototype, function(){}); diff --git a/deps/v8/test/mjsunit/es6/regress/regress-4482.js b/deps/v8/test/mjsunit/es6/regress/regress-4482.js new file mode 100644 index 0000000000..d813d21300 --- /dev/null +++ b/deps/v8/test/mjsunit/es6/regress/regress-4482.js @@ -0,0 +1,7 @@ +// 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. + +assertEquals("function", (function f() { f = 42; return typeof f })()); +assertEquals("function", + (function* g() { g = 42; yield typeof g })().next().value); diff --git a/deps/v8/test/mjsunit/es6/regress/regress-468661.js b/deps/v8/test/mjsunit/es6/regress/regress-468661.js index 4a42350930..4a58a71d30 100644 --- a/deps/v8/test/mjsunit/es6/regress/regress-468661.js +++ b/deps/v8/test/mjsunit/es6/regress/regress-468661.js @@ -9,7 +9,8 @@ var exception = null; var break_count = 0; var expected_values = - [ReferenceError, undefined, 0, 0, 0, 0, 1, ReferenceError, ReferenceError]; + [ReferenceError, undefined, 0, 0, 0, 0, 1, + ReferenceError, ReferenceError]; function listener(event, exec_state, event_data, data) { try { @@ -39,7 +40,6 @@ function listener(event, exec_state, event_data, data) { assertTrue(v instanceof ReferenceError); } else { assertSame(expected_values[break_count], v); - } ++break_count; diff --git a/deps/v8/test/mjsunit/es6/regress/regress-cr372788.js b/deps/v8/test/mjsunit/es6/regress/regress-cr372788.js index 3144b39830..c157a7e79f 100644 --- a/deps/v8/test/mjsunit/es6/regress/regress-cr372788.js +++ b/deps/v8/test/mjsunit/es6/regress/regress-cr372788.js @@ -25,7 +25,7 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// Flags: --allow-natives-syntax --promise-extra +// Flags: --allow-natives-syntax var x = 0; var y = 0; @@ -38,7 +38,7 @@ for (var i = 0; i < 3; ++i) { assertEquals(0, x); (function check() { - Promise.resolve().chain(function() { + Promise.resolve().then(function() { // Delay check until all handlers have run. if (y < 3) check(); else assertEquals(6, x); }).catch(function(e) { %AbortJS("FAILURE: " + e) }); diff --git a/deps/v8/test/mjsunit/es6/species.js b/deps/v8/test/mjsunit/es6/species.js new file mode 100644 index 0000000000..39156a4a2e --- /dev/null +++ b/deps/v8/test/mjsunit/es6/species.js @@ -0,0 +1,35 @@ +// 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 the ES2015 @@species feature + +'use strict'; + +let TypedArray = Uint8Array.__proto__; + +// The @@species property exists on the right objects and has the right values + +let classesWithSpecies = [RegExp, Array, TypedArray, ArrayBuffer, Map, Set, Promise]; +let classesWithoutSpecies = [Object, Function, String, Number, Symbol, WeakMap, WeakSet]; + +for (let constructor of classesWithSpecies) { + assertEquals(constructor, constructor[Symbol.species]); + assertThrows(function() { constructor[Symbol.species] = undefined }, TypeError); + let descriptor = Object.getOwnPropertyDescriptor(constructor, Symbol.species); + assertTrue(descriptor.configurable); + assertFalse(descriptor.enumerable); + assertEquals(undefined, descriptor.writable); + assertEquals(undefined, descriptor.set); + assertEquals('function', typeof descriptor.get); +} + +// @@species is defined with distinct getters +assertEquals(classesWithSpecies.length, + new Set(classesWithSpecies.map(constructor => + Object.getOwnPropertyDescriptor( + constructor, Symbol.species).get) + ).size); + +for (let constructor of classesWithoutSpecies) + assertEquals(undefined, constructor[Symbol.species]); diff --git a/deps/v8/test/mjsunit/es6/spread-call-new-class.js b/deps/v8/test/mjsunit/es6/spread-call-new-class.js index 1fdf25b616..de88cff5d1 100644 --- a/deps/v8/test/mjsunit/es6/spread-call-new-class.js +++ b/deps/v8/test/mjsunit/es6/spread-call-new-class.js @@ -2,8 +2,6 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// Flags: --harmony-sloppy - (function testConstructClassStrict() { "use strict"; diff --git a/deps/v8/test/mjsunit/es6/spread-call-super-property.js b/deps/v8/test/mjsunit/es6/spread-call-super-property.js index b298a69aa1..a85ea41638 100644 --- a/deps/v8/test/mjsunit/es6/spread-call-super-property.js +++ b/deps/v8/test/mjsunit/es6/spread-call-super-property.js @@ -2,8 +2,6 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// Flags: --harmony-sloppy - (function testCallSuperPropertyStrict() { "use strict"; class BaseClass { diff --git a/deps/v8/test/mjsunit/es6/string-match.js b/deps/v8/test/mjsunit/es6/string-match.js new file mode 100644 index 0000000000..2c7affe454 --- /dev/null +++ b/deps/v8/test/mjsunit/es6/string-match.js @@ -0,0 +1,18 @@ +// Copyright 2015 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +var pattern = {}; +pattern[Symbol.match] = function(string) { + return string.length; +}; +// Check object coercible fails. +assertThrows(() => String.prototype.match.call(null, pattern), + TypeError); +// Override is called. +assertEquals(5, "abcde".match(pattern)); +// Non-callable override. +pattern[Symbol.match] = "dumdidum"; +assertThrows(() => "abcde".match(pattern), TypeError); + +assertEquals("[Symbol.match]", RegExp.prototype[Symbol.match].name); diff --git a/deps/v8/test/mjsunit/es6/string-replace.js b/deps/v8/test/mjsunit/es6/string-replace.js new file mode 100644 index 0000000000..0beb57a536 --- /dev/null +++ b/deps/v8/test/mjsunit/es6/string-replace.js @@ -0,0 +1,17 @@ +// Copyright 2015 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +var pattern = { + [Symbol.replace]: (string, newValue) => string + newValue +}; +// Check object coercible fails. +assertThrows(() => String.prototype.replace.call(null, pattern, "x"), + TypeError); +// Override is called. +assertEquals("abcdex", "abcde".replace(pattern, "x")); +// Non-callable override. +pattern[Symbol.replace] = "dumdidum"; +assertThrows(() => "abcde".replace(pattern, "x"), TypeError); + +assertEquals("[Symbol.replace]", RegExp.prototype[Symbol.replace].name); diff --git a/deps/v8/test/mjsunit/es6/string-search.js b/deps/v8/test/mjsunit/es6/string-search.js index dc029826ad..cbdf33d692 100644 --- a/deps/v8/test/mjsunit/es6/string-search.js +++ b/deps/v8/test/mjsunit/es6/string-search.js @@ -2,8 +2,6 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// Flags: --harmony-regexp-subclass - var pattern = {}; pattern[Symbol.search] = function(string) { return string.length; diff --git a/deps/v8/test/mjsunit/es6/string-split.js b/deps/v8/test/mjsunit/es6/string-split.js new file mode 100644 index 0000000000..8ca655cad9 --- /dev/null +++ b/deps/v8/test/mjsunit/es6/string-split.js @@ -0,0 +1,19 @@ +// Copyright 2015 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +var pattern = {}; +var limit = { value: 3 }; +pattern[Symbol.split] = function(string, limit) { + return string.length * limit.value; +}; +// Check object coercible fails. +assertThrows(() => String.prototype.split.call(null, pattern, limit), + TypeError); +// Override is called. +assertEquals(15, "abcde".split(pattern, limit)); +// Non-callable override. +pattern[Symbol.split] = "dumdidum"; +assertThrows(() => "abcde".split(pattern, limit), TypeError); + +assertEquals("[Symbol.split]", RegExp.prototype[Symbol.split].name); diff --git a/deps/v8/test/mjsunit/es6/super.js b/deps/v8/test/mjsunit/es6/super.js index a2ba1e863b..4c80ce7711 100644 --- a/deps/v8/test/mjsunit/es6/super.js +++ b/deps/v8/test/mjsunit/es6/super.js @@ -3,7 +3,6 @@ // found in the LICENSE file. // Flags: --allow-natives-syntax -// Flags: --harmony-sloppy (function TestSuperNamedLoads() { function Base() { } diff --git a/deps/v8/test/mjsunit/es6/symbols.js b/deps/v8/test/mjsunit/es6/symbols.js index 9bac41f863..a21afb3770 100644 --- a/deps/v8/test/mjsunit/es6/symbols.js +++ b/deps/v8/test/mjsunit/es6/symbols.js @@ -555,7 +555,9 @@ TestContext(); function TestStringify(expected, input) { assertEquals(expected, JSON.stringify(input)); - assertEquals(expected, JSON.stringify(input, null, 0)); + assertEquals(expected, JSON.stringify(input, (key, value) => value)); + assertEquals(JSON.stringify(input, null, "="), + JSON.stringify(input, (key, value) => value, "=")); } TestStringify(undefined, Symbol("a")); diff --git a/deps/v8/test/mjsunit/es6/tail-call-megatest.js b/deps/v8/test/mjsunit/es6/tail-call-megatest.js index 1de8ec6c8e..3d2ecb8daa 100644 --- a/deps/v8/test/mjsunit/es6/tail-call-megatest.js +++ b/deps/v8/test/mjsunit/es6/tail-call-megatest.js @@ -10,6 +10,7 @@ Error.prepareStackTrace = (error,stack) => { return error.message + "\n at " + stack.join("\n at "); } +var verbose = typeof(arguments) !== "undefined" && arguments.indexOf("-v") >= 0; function checkStackTrace(expected) { var e = new Error(); @@ -340,32 +341,32 @@ function run_tests(shard) { return source; } - var f_args_variants = ["", "1", "1, 2"]; - var g_args_variants = ["", "10", "10, 20"]; + var f_args_variants = [/*"", "1",*/ "1, 2"]; + var g_args_variants = [/*"", "10",*/ "10, 20"]; var f_inlinable_variants = [true, false]; var g_inlinable_variants = [true, false]; // This is to avoid bailing out because of referencing new.target. - var check_new_target_variants = [true, false]; + var check_new_target_variants = [/*true,*/ false]; var deopt_mode_variants = ["none", "f", "g", "test"]; var f_variants = [ f_cfg_sloppy, f_cfg_strict, f_cfg_bound, f_cfg_proxy, - f_cfg_possibly_eval, +// f_cfg_possibly_eval, ]; var g_variants = [ g_cfg_normal, - g_cfg_reflect_apply, +// g_cfg_reflect_apply, g_cfg_function_apply, - g_cfg_function_apply_arguments_object, +// g_cfg_function_apply_arguments_object, g_cfg_function_call, ]; var test_warmup_counts = [0, 1, 2]; var iter = 0; var tests_executed = 0; - if (shard !== undefined) { + if (verbose && shard !== undefined) { print("Running shard #" + shard); } f_variants.forEach((f_cfg) => { @@ -378,7 +379,9 @@ function run_tests(shard) { g_inlinable_variants.forEach((g_inlinable) => { test_warmup_counts.forEach((test_warmup_count) => { if (shard !== undefined && (iter++) % SHARDS_COUNT != shard) { - print("skipping..."); + if (verbose) { + print("skipping..."); + } return; } tests_executed++; @@ -396,8 +399,10 @@ function run_tests(shard) { deopt_mode, }; var source = test_template(cfg); - print("===================="); - print(source); + if (verbose) { + // print("===================="); + // print(source); + } eval(source); }); }); @@ -408,7 +413,9 @@ function run_tests(shard) { }); }); }); - print("Number of tests executed: " + tests_executed); + if (verbose) { + print("Number of tests executed: " + tests_executed); + } } // Uncomment to run all the tests at once or use shard runners. diff --git a/deps/v8/test/mjsunit/es6/tail-call.js b/deps/v8/test/mjsunit/es6/tail-call.js index d0d00f4b3e..6ecf04f3d9 100644 --- a/deps/v8/test/mjsunit/es6/tail-call.js +++ b/deps/v8/test/mjsunit/es6/tail-call.js @@ -3,6 +3,8 @@ // found in the LICENSE file. // Flags: --allow-natives-syntax --harmony-tailcalls +// Flags: --harmony-do-expressions + "use strict"; Error.prepareStackTrace = (error,stack) => { @@ -259,9 +261,8 @@ function f_153(expected_call_stack, a) { } %NeverOptimizeFunction(g); - var context = 10; function f(v) { - return g(context); + return g(); } %SetForceInlineFlag(f); @@ -319,10 +320,57 @@ function f_153(expected_call_stack, a) { return f([f, g3, test], 13), f([f, test], 153); } + function g4(a) { + return f([f, g4, test], false) || + (f([f, g4, test], true) && f([f, test], true)); + } + + function g5(a) { + return f([f, g5, test], true) && + (f([f, g5, test], false) || f([f, test], true)); + } + + function g6(a) { + return f([f, g6, test], 13), f([f, g6, test], 42), + f([f, test], 153); + } + + function g7(a) { + return f([f, g7, test], false) || + (f([f, g7, test], false) ? f([f, test], true) + : f([f, test], true)); + } + + function g8(a) { + return f([f, g8, test], false) || f([f, g8, test], true) && + f([f, test], true); + } + + function g9(a) { + return f([f, g9, test], true) && f([f, g9, test], false) || + f([f, test], true); + } + + function g10(a) { + return f([f, g10, test], true) && f([f, g10, test], false) || + f([f, g10, test], true) ? + f([f, g10, test], true) && f([f, g10, test], false) || + f([f, test], true) : + f([f, g10, test], true) && f([f, g10, test], false) || + f([f, test], true); + } + function test() { assertEquals(true, g1()); assertEquals(true, g2()); assertEquals(153, g3()); + assertEquals(true, g4()); + assertEquals(true, g5()); + assertEquals(153, g6()); + assertEquals(true, g7()); + assertEquals(true, g8()); + assertEquals(true, g9()); + assertEquals(true, g10()); } test(); test(); @@ -534,9 +582,34 @@ function f_153(expected_call_stack, a) { return (() => f_153([f_153, test]))(); } + function g3(a) { + var closure = () => f([f, closure, test], true) + ? f_153([f_153, test]) + : f_153([f_153, test]); + return closure(); + } + function test() { assertEquals(153, g1()); assertEquals(153, g2()); + assertEquals(153, g3()); + } + test(); + test(); + %OptimizeFunctionOnNextCall(test); + test(); +})(); + + +// Test tail calls from do expressions. +(function () { + function g1(a) { + var a = do { return f_153([f_153, test]); 42; }; + return a; + } + + function test() { + assertEquals(153, g1()); } test(); test(); diff --git a/deps/v8/test/mjsunit/es6/typedarray-set-length-internal.js b/deps/v8/test/mjsunit/es6/typedarray-set-length-internal.js new file mode 100644 index 0000000000..22b8f67e0e --- /dev/null +++ b/deps/v8/test/mjsunit/es6/typedarray-set-length-internal.js @@ -0,0 +1,35 @@ +// 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. + +var typedArrayConstructors = [ + Uint8Array, + Int8Array, + Uint16Array, + Int16Array, + Uint32Array, + Int32Array, + Uint8ClampedArray, + Float32Array, + Float64Array +]; + +var descriptor = { get: function() { throw new Error("accessed length"); } }; + +for (var constructor of typedArrayConstructors) { + var differentConstructor = + constructor === Uint8Array ? Int8Array : Uint8Array; + var target = new constructor(16); + Object.defineProperty(target, "length", descriptor); + + var sameBuffer = new differentConstructor(target.buffer, 0, 2); + Object.defineProperty(sameBuffer, "length", descriptor); + target.set(sameBuffer); + + var differentBuffer = new differentConstructor(16); + Object.defineProperty(differentBuffer, "length", descriptor); + target.set(differentBuffer); + + var array = [0, 1, 2]; + target.set(array); +} diff --git a/deps/v8/test/mjsunit/es6/typedarray-species.js b/deps/v8/test/mjsunit/es6/typedarray-species.js new file mode 100644 index 0000000000..020d65c501 --- /dev/null +++ b/deps/v8/test/mjsunit/es6/typedarray-species.js @@ -0,0 +1,84 @@ +// 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. + +// Subclasses of %TypedArray% construct themselves under map, etc + +var typedArrayConstructors = [ + Uint8Array, + Int8Array, + Uint16Array, + Int16Array, + Uint32Array, + Int32Array, + Uint8ClampedArray, + Float32Array, + Float64Array +]; + +for (let constructor of typedArrayConstructors) { + class MyTypedArray extends constructor { } + assertEquals(MyTypedArray, new MyTypedArray().map(()=>0).constructor); + assertEquals(MyTypedArray, new MyTypedArray().filter(()=>{}).constructor); + assertEquals(MyTypedArray, new MyTypedArray().slice().constructor); +} + +// Subclasses can override @@species to return the another class + +for (let constructor of typedArrayConstructors) { + class MyTypedArray extends constructor { } + class MyOtherTypedArray extends constructor { + static get [Symbol.species]() { return MyTypedArray; } + } + assertEquals(MyTypedArray, new MyOtherTypedArray().map(()=>0).constructor); + assertEquals(MyTypedArray, new MyOtherTypedArray().filter(()=>{}).constructor); + assertEquals(MyTypedArray, new MyOtherTypedArray().slice().constructor); +} + +// TypedArray too-short and non-TypedArray error checking + +for (let constructor of typedArrayConstructors) { + class MyShortTypedArray extends constructor { + constructor(length) { super(length - 1); } + } + assertThrows(() => new MyShortTypedArray(5).map(()=>0), TypeError); + assertThrows(() => new MyShortTypedArray(5).filter(()=>true), TypeError); + assertThrows(() => new MyShortTypedArray(5).slice(), TypeError); + + class MyNonTypedArray extends constructor { + static get [Symbol.species]() { return Array; } + } + assertThrows(() => new MyNonTypedArray().map(()=>0), TypeError); + assertThrows(() => new MyNonTypedArray().filter(()=>{}), TypeError); + assertThrows(() => new MyNonTypedArray().slice(), TypeError); +} + +// Defaults when constructor or @@species is missing or non-constructor + +for (let constructor of typedArrayConstructors) { + class MyDefaultTypedArray extends constructor { + static get [Symbol.species]() { return undefined; } + } + assertEquals(constructor, new MyDefaultTypedArray().map(()=>0).constructor); + + class MyOtherDefaultTypedArray extends constructor { } + assertEquals(MyOtherDefaultTypedArray, new MyOtherDefaultTypedArray().map(()=>0).constructor); + MyOtherDefaultTypedArray.prototype.constructor = undefined; + assertEquals(constructor, new MyOtherDefaultTypedArray().map(()=>0).constructor); +} + +// Exceptions propagated when getting constructor @@species throws + +class SpeciesError extends Error { } +class ConstructorError extends Error { } + +for (let constructor of typedArrayConstructors) { + class MyThrowingArray extends constructor { + static get [Symbol.species]() { throw new SpeciesError; } + } + assertThrows(() => new MyThrowingArray().map(()=>{}), SpeciesError); + Object.defineProperty(MyThrowingArray.prototype, 'constructor', { + get() { throw new ConstructorError; } + }); + assertThrows(() => new MyThrowingArray().map(()=>{}), ConstructorError); +} diff --git a/deps/v8/test/mjsunit/es6/typedarray-tostring.js b/deps/v8/test/mjsunit/es6/typedarray-tostring.js index e6adda0405..9d49cb1cc9 100644 --- a/deps/v8/test/mjsunit/es6/typedarray-tostring.js +++ b/deps/v8/test/mjsunit/es6/typedarray-tostring.js @@ -83,4 +83,17 @@ for (var constructor of typedArrayConstructors) { assertEquals("1,2", Array.prototype.join.call(a5)); assertEquals("1,2,3", Array.prototype.toString.call(a5)); assertEquals("1,2", Array.prototype.toLocaleString.call(a5)); + + (function TestToLocaleStringCalls() { + let log = []; + let pushArgs = (label) => (...args) => log.push(label, args); + + let NumberToLocaleString = Number.prototype.toLocaleString; + Number.prototype.toLocaleString = pushArgs("Number"); + + (new constructor([1, 2])).toLocaleString(); + assertEquals(["Number", [], "Number", []], log); + + Number.prototype.toLocaleString = NumberToLocaleString; + })(); } diff --git a/deps/v8/test/mjsunit/es6/typedarray.js b/deps/v8/test/mjsunit/es6/typedarray.js index 4bdf8226a8..b1bd8937be 100644 --- a/deps/v8/test/mjsunit/es6/typedarray.js +++ b/deps/v8/test/mjsunit/es6/typedarray.js @@ -229,6 +229,27 @@ function TestTypedArray(constr, elementSize, typicalElement) { RangeError); } + var aFromUndef = new constr(); + assertSame(elementSize, aFromUndef.BYTES_PER_ELEMENT); + assertSame(0, aFromUndef.length); + assertSame(0*elementSize, aFromUndef.byteLength); + assertSame(0, aFromUndef.byteOffset); + assertSame(0*elementSize, aFromUndef.buffer.byteLength); + + var aFromNull = new constr(null); + assertSame(elementSize, aFromNull.BYTES_PER_ELEMENT); + assertSame(0, aFromNull.length); + assertSame(0*elementSize, aFromNull.byteLength); + assertSame(0, aFromNull.byteOffset); + assertSame(0*elementSize, aFromNull.buffer.byteLength); + + var aFromBool = new constr(true); + assertSame(elementSize, aFromBool.BYTES_PER_ELEMENT); + assertSame(1, aFromBool.length); + assertSame(1*elementSize, aFromBool.byteLength); + assertSame(0, aFromBool.byteOffset); + assertSame(1*elementSize, aFromBool.buffer.byteLength); + var aFromString = new constr("30"); assertSame(elementSize, aFromString.BYTES_PER_ELEMENT); assertSame(30, aFromString.length); @@ -236,6 +257,8 @@ function TestTypedArray(constr, elementSize, typicalElement) { assertSame(0, aFromString.byteOffset); assertSame(30*elementSize, aFromString.buffer.byteLength); + assertThrows(function() { new constr(Symbol()); }, TypeError); + var jsArray = []; for (i = 0; i < 30; i++) { jsArray.push(typicalElement); diff --git a/deps/v8/test/mjsunit/es6/unicode-character-ranges.js b/deps/v8/test/mjsunit/es6/unicode-character-ranges.js new file mode 100644 index 0000000000..f39004fe97 --- /dev/null +++ b/deps/v8/test/mjsunit/es6/unicode-character-ranges.js @@ -0,0 +1,158 @@ +// Copyright 2016 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Flags: --harmony-regexp-lookbehind + +function execl(expectation, regexp, subject) { + if (regexp instanceof String) regexp = new RegExp(regexp, "u"); + assertEquals(expectation, regexp.exec(subject)); +} + +function execs(expectation, regexp_source, subject) { + execl(expectation, new RegExp(regexp_source, "u"), subject); +} + +// Character ranges. +execl(["A"], /[A-D]/u, "A"); +execs(["A"], "[A-D]", "A"); +execl(["ABCD"], /[A-D]+/u, "ZABCDEF"); +execs(["ABCD"], "[A-D]+", "ZABCDEF"); + +execl(["\u{12345}"], /[\u1234-\u{12345}]/u, "\u{12345}"); +execs(["\u{12345}"], "[\u1234-\u{12345}]", "\u{12345}"); +execl(null, /[^\u1234-\u{12345}]/u, "\u{12345}"); +execs(null, "[^\u1234-\u{12345}]", "\u{12345}"); + +execl(["\u{1234}"], /[\u1234-\u{12345}]/u, "\u{1234}"); +execs(["\u{1234}"], "[\u1234-\u{12345}]", "\u{1234}"); +execl(null, /[^\u1234-\u{12345}]/u, "\u{1234}"); +execs(null, "[^\u1234-\u{12345}]", "\u{1234}"); + +execl(null, /[\u1234-\u{12345}]/u, "\u{1233}"); +execs(null, "[\u1234-\u{12345}]", "\u{1233}"); +execl(["\u{1233}"], /[^\u1234-\u{12345}]/u, "\u{1233}"); +execs(["\u{1233}"], "[^\u1234-\u{12345}]", "\u{1233}"); + +execl(["\u{12346}"], /[^\u1234-\u{12345}]/u, "\u{12346}"); +execs(["\u{12346}"], "[^\u1234-\u{12345}]", "\u{12346}"); +execl(null, /[\u1234-\u{12345}]/u, "\u{12346}"); +execs(null, "[\u1234-\u{12345}]", "\u{12346}"); + +execl(["\u{12342}"], /[\u{12340}-\u{12345}]/u, "\u{12342}"); +execs(["\u{12342}"], "[\u{12340}-\u{12345}]", "\u{12342}"); +execl(["\u{12342}"], /[\ud808\udf40-\ud808\udf45]/u, "\u{12342}"); +execs(["\u{12342}"], "[\ud808\udf40-\ud808\udf45]", "\u{12342}"); +execl(null, /[^\u{12340}-\u{12345}]/u, "\u{12342}"); +execs(null, "[^\u{12340}-\u{12345}]", "\u{12342}"); +execl(null, /[^\ud808\udf40-\ud808\udf45]/u, "\u{12342}"); +execs(null, "[^\ud808\udf40-\ud808\udf45]", "\u{12342}"); + +execl(["\u{ffff}"], /[\u{ff80}-\u{12345}]/u, "\u{ffff}"); +execs(["\u{ffff}"], "[\u{ff80}-\u{12345}]", "\u{ffff}"); +execl(["\u{ffff}"], /[\u{ff80}-\ud808\udf45]/u, "\u{ffff}"); +execs(["\u{ffff}"], "[\u{ff80}-\ud808\udf45]", "\u{ffff}"); +execl(null, /[^\u{ff80}-\u{12345}]/u, "\u{ffff}"); +execs(null, "[^\u{ff80}-\u{12345}]", "\u{ffff}"); +execl(null, /[^\u{ff80}-\ud808\udf45]/u, "\u{ffff}"); +execs(null, "[^\u{ff80}-\ud808\udf45]", "\u{ffff}"); + +// Lone surrogate +execl(["\ud800"], /[^\u{ff80}-\u{12345}]/u, "\uff99\u{d800}A"); +execs(["\udc00"], "[^\u{ff80}-\u{12345}]", "\uff99\u{dc00}A"); +execl(["\udc01"], /[\u0100-\u{10ffff}]/u, "A\udc01"); +execl(["\udc03"], /[\udc01-\udc03]/u, "\ud801\udc02\udc03"); +execl(["\ud801"], /[\ud801-\ud803]/u, "\ud802\udc01\ud801"); + +// Paired sorrogate. +execl(null, /[^\u{ff80}-\u{12345}]/u, "\u{d800}\u{dc00}"); +execs(null, "[^\u{ff80}-\u{12345}]", "\u{d800}\u{dc00}"); +execl(["\ud800\udc00"], /[\u{ff80}-\u{12345}]/u, "\u{d800}\u{dc00}"); +execs(["\ud800\udc00"], "[\u{ff80}-\u{12345}]", "\u{d800}\u{dc00}"); +execl(["foo\u{10e6d}bar"], /foo\ud803\ude6dbar/u, "foo\u{10e6d}bar"); + +// Lone surrogates +execl(["\ud801\ud801"], /\ud801+/u, "\ud801\udc01\ud801\ud801"); +execl(["\udc01\udc01"], /\udc01+/u, "\ud801\ud801\udc01\udc01\udc01"); + +execl(["\udc02\udc03A"], /\W\WA/u, "\ud801\udc01A\udc02\udc03A"); +execl(["\ud801\ud802"], /\ud801./u, "\ud801\udc01\ud801\ud802"); +execl(["\udc02\udc03A"], /[\ud800-\udfff][\ud800-\udfff]A/u, + "\ud801\udc01A\udc02\udc03A"); + +// Character classes +execl(null, /\w/u, "\ud801\udc01"); +execl(["\ud801"], /[^\w]/, "\ud801\udc01"); +execl(["\ud801\udc01"], /[^\w]/u, "\ud801\udc01"); +execl(["\ud801"], /\W/, "\ud801\udc01"); +execl(["\ud801\udc01"], /\W/u, "\ud801\udc01"); + +execl(["\ud800X"], /.X/u, "\ud800XaX"); +execl(["aX"], /.(?<!\ud800)X/u, "\ud800XaX"); +execl(["aX"], /.(?<![\ud800-\ud900])X/u, "\ud800XaX"); + +execl(null, /[]/u, "\u1234"); +execl(["0abc"], /[^]abc/u, "0abc"); +execl(["\u1234abc"], /[^]abc/u, "\u1234abc"); +execl(["\u{12345}abc"], /[^]abc/u, "\u{12345}abc"); + +execl(null, /[\u{0}-\u{1F444}]/u, "\ud83d\udfff"); + +// Backward matches of lone surrogates. +execl(["B", "\ud803A"], /(?<=([\ud800-\ud900]A))B/u, + "\ud801\udc00AB\udc00AB\ud802\ud803AB"); +execl(["B", "\udc00A"], /(?<=([\ud800-\u{10300}]A))B/u, + "\ud801\udc00AB\udc00AB\ud802\ud803AB"); +execl(["B", "\udc11A"], /(?<=([\udc00-\udd00]A))B/u, + "\ud801\udc00AB\udc11AB\ud802\ud803AB"); +execl(["X", "\ud800C"], /(?<=(\ud800\w))X/u, + "\ud800\udc00AX\udc11BX\ud800\ud800CX"); +execl(["C", "\ud800\ud800"], /(?<=(\ud800.))\w/u, + "\ud800\udc00AX\udc11BX\ud800\ud800CX"); +execl(["X", "\udc01C"], /(?<=(\udc01\w))X/u, + "\ud800\udc01AX\udc11BX\udc01\udc01CX"); +execl(["C", "\udc01\udc01"], /(?<=(\udc01.))./u, + "\ud800\udc01AX\udc11BX\udc01\udc01CX"); + +var L = "\ud800"; +var T = "\udc00"; +var X = "X"; + +// Test string contains only match. +function testw(expect, src, subject) { + var re = new RegExp("^" + src + "$", "u"); + assertEquals(expect, re.test(subject)); +} + +// Test string starts with match. +function tests(expect, src, subject) { + var re = new RegExp("^" + src, "u"); + assertEquals(expect, re.test(subject)); +} + +testw(true, X, X); +testw(true, L, L); +testw(true, T, T); +testw(true, L + T, L + T); +testw(true, T + L, T + L); +testw(false, T, L + T); +testw(false, L, L + T); +testw(true, ".(?<=" + L + ")", L); +testw(true, ".(?<=" + T + ")", T); +testw(true, ".(?<=" + L + T + ")", L + T); +testw(true, ".(?<=" + L + T + ")", L + T); +tests(true, ".(?<=" + T + ")", T + L); +tests(false, ".(?<=" + L + ")", L + T); +tests(false, ".(?<=" + T + ")", L + T); +tests(true, "..(?<=" + T + ")", T + T + L); +tests(true, "..(?<=" + T + ")", X + T + L); +tests(true, "...(?<=" + L + ")", X + T + L); +tests(false, "...(?<=" + T + ")", X + L + T) +tests(true, "..(?<=" + L + T + ")", X + L + T) +tests(true, "..(?<=" + L + T + "(?<=" + L + T + "))", X + L + T); +tests(false, "..(?<=" + L + "(" + T + "))", X + L + T); +tests(false, ".*" + L, X + L + T); +tests(true, ".*" + L, X + L + L + T); +tests(false, ".*" + L, X + L + T + L + T); +tests(false, ".*" + T, X + L + T + L + T); +tests(true, ".*" + T, X + L + T + T + L + T); diff --git a/deps/v8/test/mjsunit/es6/unicode-escapes-in-regexps.js b/deps/v8/test/mjsunit/es6/unicode-escapes-in-regexps.js new file mode 100644 index 0000000000..2d2d11825d --- /dev/null +++ b/deps/v8/test/mjsunit/es6/unicode-escapes-in-regexps.js @@ -0,0 +1,285 @@ +// 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. + +// ES6 extends the \uxxxx escape and also allows \u{xxxxx}. + +function testRegexpHelper(r) { + assertTrue(r.test("foo")); + assertTrue(r.test("boo")); + assertFalse(r.test("moo")); +} + + +(function TestUnicodeEscapes() { + testRegexpHelper(/(\u0066|\u0062)oo/); + testRegexpHelper(/(\u0066|\u0062)oo/u); + testRegexpHelper(/(\u{0066}|\u{0062})oo/u); + testRegexpHelper(/(\u{66}|\u{000062})oo/u); + + // Note that we need \\ inside a string, otherwise it's interpreted as a + // unicode escape inside a string. + testRegexpHelper(new RegExp("(\\u0066|\\u0062)oo")); + testRegexpHelper(new RegExp("(\\u0066|\\u0062)oo", "u")); + testRegexpHelper(new RegExp("(\\u{0066}|\\u{0062})oo", "u")); + testRegexpHelper(new RegExp("(\\u{66}|\\u{000062})oo", "u")); + + // Though, unicode escapes via strings should work too. + testRegexpHelper(new RegExp("(\u0066|\u0062)oo")); + testRegexpHelper(new RegExp("(\u0066|\u0062)oo", "u")); + testRegexpHelper(new RegExp("(\u{0066}|\u{0062})oo", "u")); + testRegexpHelper(new RegExp("(\u{66}|\u{000062})oo", "u")); +})(); + + +(function TestUnicodeEscapesInCharacterClasses() { + testRegexpHelper(/[\u0062-\u0066]oo/); + testRegexpHelper(/[\u0062-\u0066]oo/u); + testRegexpHelper(/[\u{0062}-\u{0066}]oo/u); + testRegexpHelper(/[\u{62}-\u{00000066}]oo/u); + + // Note that we need \\ inside a string, otherwise it's interpreted as a + // unicode escape inside a string. + testRegexpHelper(new RegExp("[\\u0062-\\u0066]oo")); + testRegexpHelper(new RegExp("[\\u0062-\\u0066]oo", "u")); + testRegexpHelper(new RegExp("[\\u{0062}-\\u{0066}]oo", "u")); + testRegexpHelper(new RegExp("[\\u{62}-\\u{00000066}]oo", "u")); + + // Though, unicode escapes via strings should work too. + testRegexpHelper(new RegExp("[\u0062-\u0066]oo")); + testRegexpHelper(new RegExp("[\u0062-\u0066]oo", "u")); + testRegexpHelper(new RegExp("[\u{0062}-\u{0066}]oo", "u")); + testRegexpHelper(new RegExp("[\u{62}-\u{00000066}]oo", "u")); +})(); + + +(function TestBraceEscapesWithoutUnicodeFlag() { + // \u followed by illegal escape will be parsed as u. {x} will be the + // character count. + function helper1(r) { + assertFalse(r.test("fbar")); + assertFalse(r.test("fubar")); + assertTrue(r.test("fuubar")); + assertFalse(r.test("fuuubar")); + } + helper1(/f\u{2}bar/); + helper1(new RegExp("f\\u{2}bar")); + + function helper2(r) { + assertFalse(r.test("fbar")); + assertTrue(r.test("fubar")); + assertTrue(r.test("fuubar")); + assertFalse(r.test("fuuubar")); + } + + helper2(/f\u{1,2}bar/); + helper2(new RegExp("f\\u{1,2}bar")); + + function helper3(r) { + assertTrue(r.test("u")); + assertTrue(r.test("{")); + assertTrue(r.test("2")); + assertTrue(r.test("}")); + assertFalse(r.test("q")); + assertFalse(r.test("(")); + assertFalse(r.test(")")); + } + helper3(/[\u{2}]/); + helper3(new RegExp("[\\u{2}]")); +})(); + + +(function TestInvalidEscapes() { + // Without the u flag, invalid unicode escapes and other invalid escapes are + // treated as identity escapes. + function helper1(r) { + assertTrue(r.test("firstuxz89second")); + } + helper1(/first\u\x\z\8\9second/); + helper1(new RegExp("first\\u\\x\\z\\8\\9second")); + + function helper2(r) { + assertTrue(r.test("u")); + assertTrue(r.test("x")); + assertTrue(r.test("z")); + assertTrue(r.test("8")); + assertTrue(r.test("9")); + assertFalse(r.test("q")); + assertFalse(r.test("7")); + } + helper2(/[\u\x\z\8\9]/); + helper2(new RegExp("[\\u\\x\\z\\8\\9]")); + + // However, with the u flag, these are treated as invalid escapes. + assertThrows("/\\u/u", SyntaxError); + assertThrows("/\\u12/u", SyntaxError); + assertThrows("/\\ufoo/u", SyntaxError); + assertThrows("/\\x/u", SyntaxError); + assertThrows("/\\xfoo/u", SyntaxError); + assertThrows("/\\z/u", SyntaxError); + assertThrows("/\\8/u", SyntaxError); + assertThrows("/\\9/u", SyntaxError); + + assertThrows("new RegExp('\\\\u', 'u')", SyntaxError); + assertThrows("new RegExp('\\\\u12', 'u')", SyntaxError); + assertThrows("new RegExp('\\\\ufoo', 'u')", SyntaxError); + assertThrows("new RegExp('\\\\x', 'u')", SyntaxError); + assertThrows("new RegExp('\\\\xfoo', 'u')", SyntaxError); + assertThrows("new RegExp('\\\\z', 'u')", SyntaxError); + assertThrows("new RegExp('\\\\8', 'u')", SyntaxError); + assertThrows("new RegExp('\\\\9', 'u')", SyntaxError); +})(); + + +(function TestTooBigHexEscape() { + // The hex number inside \u{} has a maximum value. + /\u{10ffff}/u + new RegExp("\\u{10ffff}", "u") + assertThrows("/\\u{110000}/u", SyntaxError); + assertThrows("new RegExp('\\\\u{110000}', 'u')", SyntaxError); + + // Without the u flag, they're of course fine ({x} is the count). + /\u{110000}/ + new RegExp("\\u{110000}") +})(); + + +(function TestSyntaxEscapes() { + // Syntax escapes work the same with or without the u flag. + function helper(r) { + assertTrue(r.test("foo[bar")); + assertFalse(r.test("foo]bar")); + } + helper(/foo\[bar/); + helper(new RegExp("foo\\[bar")); + helper(/foo\[bar/u); + helper(new RegExp("foo\\[bar", "u")); +})(); + + +(function TestUnicodeSurrogates() { + // U+10E6D corresponds to the surrogate pair [U+D803, U+DE6D]. + function helper(r) { + assertTrue(r.test("foo\u{10e6d}bar")); + } + helper(/foo\ud803\ude6dbar/u); + helper(new RegExp("foo\\ud803\\ude6dbar", "u")); +})(); + + +(function AllFlags() { + // Test that we can pass all possible regexp flags and they work properly. + function helper1(r) { + assertTrue(r.global); + assertTrue(r.ignoreCase); + assertTrue(r.multiline); + assertTrue(r.sticky); + assertTrue(r.unicode); + } + + helper1(/foo/gimyu); + helper1(new RegExp("foo", "gimyu")); + + function helper2(r) { + assertFalse(r.global); + assertFalse(r.ignoreCase); + assertFalse(r.multiline); + assertFalse(r.sticky); + assertFalse(r.unicode); + } + + helper2(/foo/); + helper2(new RegExp("foo")); +})(); + + +(function DuplicatedFlags() { + // Test that duplicating the u flag is not allowed. + assertThrows("/foo/ugu"); + assertThrows("new RegExp('foo', 'ugu')"); +})(); + + +(function ToString() { + // Test that the u flag is included in the string representation of regexps. + function helper(r) { + assertEquals(r.toString(), "/foo/u"); + } + helper(/foo/u); + helper(new RegExp("foo", "u")); +})(); + +// Non-BMP patterns. +// Single character atom. +assertTrue(new RegExp("\u{12345}", "u").test("\u{12345}")); +assertTrue(/\u{12345}/u.test("\u{12345}")); +assertTrue(new RegExp("\u{12345}", "u").test("\ud808\udf45")); +assertTrue(/\u{12345}/u.test("\ud808\udf45")); +assertFalse(new RegExp("\u{12345}", "u").test("\udf45")); +assertFalse(/\u{12345}/u.test("\udf45")); + +// Multi-character atom. +assertTrue(new RegExp("\u{12345}\u{23456}", "u").test("a\u{12345}\u{23456}b")); +assertTrue(/\u{12345}\u{23456}/u.test("b\u{12345}\u{23456}c")); +assertFalse(new RegExp("\u{12345}\u{23456}", "u").test("a\udf45\u{23456}b")); +assertFalse(/\u{12345}\u{23456}/u.test("b\udf45\u{23456}c")); + +// Disjunction. +assertTrue(new RegExp("\u{12345}(?:\u{23456})", "u").test( + "a\u{12345}\u{23456}b")); +assertTrue(/\u{12345}(?:\u{23456})/u.test("b\u{12345}\u{23456}c")); +assertFalse(new RegExp("\u{12345}(?:\u{23456})", "u").test( + "a\udf45\u{23456}b")); +assertFalse(/\u{12345}(?:\u{23456})/u.test("b\udf45\u{23456}c")); + +// Alternative. +assertTrue(new RegExp("\u{12345}|\u{23456}", "u").test("a\u{12345}b")); +assertTrue(/\u{12345}|\u{23456}/u.test("b\u{23456}c")); +assertFalse(new RegExp("\u{12345}|\u{23456}", "u").test("a\udf45\ud84db")); +assertFalse(/\u{12345}|\u{23456}/u.test("b\udf45\ud808c")); + +// Capture. +assertTrue(new RegExp("(\u{12345}|\u{23456}).\\1", "u").test( + "\u{12345}b\u{12345}")); +assertTrue(/(\u{12345}|\u{23456}).\1/u.test("\u{12345}b\u{12345}")); +assertFalse(new RegExp("(\u{12345}|\u{23456}).\\1", "u").test( + "\u{12345}b\u{23456}")); +assertFalse(/(\u{12345}|\u{23456}).\1/u.test("\u{12345}b\u{23456}")); + +// Quantifier. +assertTrue(new RegExp("\u{12345}{3}", "u").test("\u{12345}\u{12345}\u{12345}")); +assertTrue(/\u{12345}{3}/u.test("\u{12345}\u{12345}\u{12345}")); +assertTrue(new RegExp("\u{12345}{3}").test("\u{12345}\udf45\udf45")); +assertFalse(/\ud808\udf45{3}/u.test("\u{12345}\udf45\udf45")); +assertTrue(/\ud808\udf45{3}/u.test("\u{12345}\u{12345}\u{12345}")); +assertFalse(new RegExp("\u{12345}{3}", "u").test("\u{12345}\udf45\udf45")); +assertFalse(/\u{12345}{3}/u.test("\u{12345}\udf45\udf45")); + +// Literal surrogates. +assertEquals(["\u{10000}\u{10000}"], + new RegExp("\ud800\udc00+", "u").exec("\u{10000}\u{10000}")); +assertEquals(["\u{10000}\u{10000}"], + new RegExp("\\ud800\\udc00+", "u").exec("\u{10000}\u{10000}")); + +assertEquals(["\u{10003}\u{50001}"], + new RegExp("[\\ud800\\udc03-\\ud900\\udc01\]+", "u").exec( + "\u{10003}\u{50001}")); +assertEquals(["\u{10003}\u{50001}"], + new RegExp("[\ud800\udc03-\u{50001}\]+", "u").exec( + "\u{10003}\u{50001}")); + +// Unicode escape sequences to represent a non-BMP character cannot have +// mixed notation, and must follow the rules for RegExpUnicodeEscapeSequence. +assertThrows(() => new RegExp("[\\ud800\udc03-\ud900\\udc01\]+", "u")); +assertThrows(() => new RegExp("[\\ud800\udc03-\ud900\\udc01\]+", "u")); +assertNull(new RegExp("\\ud800\udc00+", "u").exec("\u{10000}\u{10000}")); +assertNull(new RegExp("\ud800\\udc00+", "u").exec("\u{10000}\u{10000}")); + +assertNull(new RegExp("[\\ud800\udc00]", "u").exec("\u{10000}")); +assertNull(new RegExp("[\\{ud800}\udc00]", "u").exec("\u{10000}")); +assertNull(new RegExp("[\ud800\\udc00]", "u").exec("\u{10000}")); +assertNull(new RegExp("[\ud800\\{udc00}]", "u").exec("\u{10000}")); + +assertNull(/\u{d800}\u{dc00}+/u.exec("\ud800\udc00\udc00")); +assertNull(/\ud800\u{dc00}+/u.exec("\ud800\udc00\udc00")); +assertNull(/\u{d800}\udc00+/u.exec("\ud800\udc00\udc00")); diff --git a/deps/v8/test/mjsunit/es6/unicode-regexp-backrefs.js b/deps/v8/test/mjsunit/es6/unicode-regexp-backrefs.js new file mode 100644 index 0000000000..56b9c5eb8c --- /dev/null +++ b/deps/v8/test/mjsunit/es6/unicode-regexp-backrefs.js @@ -0,0 +1,53 @@ +// Copyright 2016 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Flags: --harmony-regexp-lookbehind + +// Back reference does not end in the middle of a surrogate pair. +function replace(string) { + return string.replace(/L/g, "\ud800") + .replace(/l/g, "\ud801") + .replace(/T/g, "\udc00") + .replace(/\./g, "[^]"); +} + +function test(expectation, regexp_source, subject) { + if (expectation !== null) expectation = expectation.map(replace); + subject = replace(subject); + regexp_source = replace(regexp_source); + assertEquals(expectation, new RegExp(regexp_source, "u").exec(subject)); +} + +// Back reference does not end in the middle of a surrogate pair. +test(null, "(L)\\1", "LLT"); +test(["LLTLl", "L", "l"], "(L).*\\1(.)", "LLTLl"); +test(null, "(aL).*\\1", "aLaLT"); +test(["aLaLTaLl", "aL", "l"], "(aL).*\\1(.)", "aLaLTaLl"); + +var s = "TabcLxLTabcLxTabcLTyTabcLz"; +test([s, "TabcL", "z"], "([^x]+).*\\1(.)", s); + +// Back reference does not start in the middle of a surrogate pair. +test(["TLTabTc", "T", "c"], "(T).*\\1(.)", "TLTabTc"); + +// Lookbehinds. +test(null, "(?<=\\1(T)x)", "LTTx"); +test(["", "b", "T"], "(?<=(.)\\2.*(T)x)", "bTaLTTx"); +test(null, "(?<=\\1.*(L)x)", "LTLx"); +test(["", "b", "L"], "(?<=(.)\\2.*(L)x)", "bLaLTLx"); + + +test(null, "([^x]+)x*\\1", "LxLT"); +test(null, "([^x]+)x*\\1", "TxLT"); +test(null, "([^x]+)x*\\1", "LTxL"); +test(null, "([^x]+)x*\\1", "LTxT"); +test(null, "([^x]+)x*\\1", "xLxLT"); +test(null, "([^x]+)x*\\1", "xTxLT"); +test(null, "([^x]+)x*\\1", "xLTxL"); +test(null, "([^x]+)x*\\1", "xLTxT"); +test(null, "([^x]+)x*\\1", "xxxLxxLTxx"); +test(null, "([^x]+)x*\\1", "xxxTxxLTxx"); +test(null, "([^x]+)x*\\1", "xxxLTxxLxx"); +test(null, "([^x]+)x*\\1", "xxxLTxxTxx"); +test(["LTTxxLTT", "LTT"], "([^x]+)x*\\1", "xxxLTTxxLTTxx"); diff --git a/deps/v8/test/mjsunit/es6/unicode-regexp-ignore-case-noi18n.js b/deps/v8/test/mjsunit/es6/unicode-regexp-ignore-case-noi18n.js new file mode 100644 index 0000000000..a99894234a --- /dev/null +++ b/deps/v8/test/mjsunit/es6/unicode-regexp-ignore-case-noi18n.js @@ -0,0 +1,57 @@ +// Copyright 2016 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Non-unicode use toUpperCase mappings. +assertFalse(/[\u00e5]/i.test("\u212b")); +assertFalse(/[\u212b]/i.test("\u00e5\u1234")); +assertFalse(/[\u212b]/i.test("\u00e5")); + +assertTrue("\u212b".toLowerCase() == "\u00e5"); +assertTrue("\u00c5".toLowerCase() == "\u00e5"); +assertTrue("\u00e5".toUpperCase() == "\u00c5"); + +// Unicode uses case folding mappings. +assertFalse(/\u00e5/ui.test("\u212b")); +assertTrue(/\u00e5/ui.test("\u00c5")); +assertTrue(/\u00e5/ui.test("\u00e5")); +assertFalse(/\u00e5/ui.test("\u212b")); +assertTrue(/\u00c5/ui.test("\u00e5")); +assertFalse(/\u00c5/ui.test("\u212b")); +assertTrue(/\u00c5/ui.test("\u00c5")); +assertFalse(/\u212b/ui.test("\u00c5")); +assertFalse(/\u212b/ui.test("\u00e5")); +assertTrue(/\u212b/ui.test("\u212b")); + +// Non-BMP. +assertFalse(/\u{10400}/i.test("\u{10428}")); +assertFalse(/\u{10400}/ui.test("\u{10428}")); +assertFalse(/\ud801\udc00/ui.test("\u{10428}")); +assertFalse(/[\u{10428}]/ui.test("\u{10400}")); +assertFalse(/[\ud801\udc28]/ui.test("\u{10400}")); +assertEquals(["\uff21\u{10400}"], + /[\uff40-\u{10428}]+/ui.exec("\uff21\u{10400}abc")); +assertEquals(["abc"], /[^\uff40-\u{10428}]+/ui.exec("\uff21\u{10400}abc\uff23")); +assertEquals(["\uff53\u24bb"], + /[\u24d5-\uff33]+/ui.exec("\uff54\uff53\u24bb\u24ba")); + +// Full mappings are ignored. +assertFalse(/\u00df/ui.test("SS")); +assertFalse(/\u1f8d/ui.test("\u1f05\u03b9")); + +// Simple mappings. +assertFalse(/\u1f8d/ui.test("\u1f85")); + +// Common mappings. +assertTrue(/\u1f6b/ui.test("\u1f63")); + +// Back references. +assertNull(/(.)\1\1/ui.exec("\u00e5\u212b\u00c5")); +assertNull(/(.)\1/ui.exec("\u{118aa}\u{118ca}")); + + +// Non-Latin1 maps to Latin1. +assertNull(/^\u017F/ui.exec("s")); +assertNull(/^\u017F/ui.exec("s\u1234")); +assertNull(/^a[\u017F]/ui.exec("as")); +assertNull(/^a[\u017F]/ui.exec("as\u1234")); diff --git a/deps/v8/test/mjsunit/es6/unicode-regexp-ignore-case.js b/deps/v8/test/mjsunit/es6/unicode-regexp-ignore-case.js new file mode 100644 index 0000000000..dd02ca9d32 --- /dev/null +++ b/deps/v8/test/mjsunit/es6/unicode-regexp-ignore-case.js @@ -0,0 +1,62 @@ +// 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. + +// Non-unicode use toUpperCase mappings. +assertFalse(/[\u00e5]/i.test("\u212b")); +assertFalse(/[\u212b]/i.test("\u00e5\u1234")); +assertFalse(/[\u212b]/i.test("\u00e5")); + +assertTrue("\u212b".toLowerCase() == "\u00e5"); +assertTrue("\u00c5".toLowerCase() == "\u00e5"); +assertTrue("\u00e5".toUpperCase() == "\u00c5"); + +// Unicode uses case folding mappings. +assertTrue(/\u00e5/ui.test("\u212b")); +assertTrue(/\u00e5/ui.test("\u00c5")); +assertTrue(/\u00e5/ui.test("\u00e5")); +assertTrue(/\u00e5/ui.test("\u212b")); +assertTrue(/\u00c5/ui.test("\u00e5")); +assertTrue(/\u00c5/ui.test("\u212b")); +assertTrue(/\u00c5/ui.test("\u00c5")); +assertTrue(/\u212b/ui.test("\u00c5")); +assertTrue(/\u212b/ui.test("\u00e5")); +assertTrue(/\u212b/ui.test("\u212b")); + +// Non-BMP. +assertFalse(/\u{10400}/i.test("\u{10428}")); +assertTrue(/\u{10400}/ui.test("\u{10428}")); +assertTrue(/\ud801\udc00/ui.test("\u{10428}")); +assertTrue(/[\u{10428}]/ui.test("\u{10400}")); +assertTrue(/[\ud801\udc28]/ui.test("\u{10400}")); +assertEquals(["\uff21\u{10400}"], + /[\uff40-\u{10428}]+/ui.exec("\uff21\u{10400}abc")); +assertEquals(["abc"], /[^\uff40-\u{10428}]+/ui.exec("\uff21\u{10400}abc\uff23")); +assertEquals(["\uff53\u24bb"], + /[\u24d5-\uff33]+/ui.exec("\uff54\uff53\u24bb\u24ba")); + +// Full mappings are ignored. +assertFalse(/\u00df/ui.test("SS")); +assertFalse(/\u1f8d/ui.test("\u1f05\u03b9")); + +// Simple mappings work. +assertTrue(/\u1f8d/ui.test("\u1f85")); + +// Common mappings work. +assertTrue(/\u1f6b/ui.test("\u1f63")); + +// Back references. +assertEquals(["\u00e5\u212b\u00c5", "\u00e5"], + /(.)\1\1/ui.exec("\u00e5\u212b\u00c5")); +assertEquals(["\u{118aa}\u{118ca}", "\u{118aa}"], + /(.)\1/ui.exec("\u{118aa}\u{118ca}")); + +// Misc. +assertTrue(/\u00e5\u00e5\u00e5/ui.test("\u212b\u00e5\u00c5")); +assertTrue(/AB\u{10400}/ui.test("ab\u{10428}")); + +// Non-Latin1 maps to Latin1. +assertEquals(["s"], /^\u017F/ui.exec("s")); +assertEquals(["s"], /^\u017F/ui.exec("s\u1234")); +assertEquals(["as"], /^a[\u017F]/ui.exec("as")); +assertEquals(["as"], /^a[\u017F]/ui.exec("as\u1234")); diff --git a/deps/v8/test/mjsunit/es6/unicode-regexp-last-index.js b/deps/v8/test/mjsunit/es6/unicode-regexp-last-index.js new file mode 100644 index 0000000000..67fbac7ef3 --- /dev/null +++ b/deps/v8/test/mjsunit/es6/unicode-regexp-last-index.js @@ -0,0 +1,104 @@ +// Copyright 2016 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Flags: --harmony-regexp-lookbehind + +var r = /./ug; +assertEquals(["\ud800\udc00"], r.exec("\ud800\udc00\ud801\udc01")); +assertEquals(2, r.lastIndex); +r.lastIndex = 1; +assertEquals(["\ud800\udc00"], r.exec("\ud800\udc00\ud801\udc01")); +assertEquals(2, r.lastIndex); +assertEquals(["\ud801\udc01"], r.exec("\ud800\udc00\ud801\udc01")); +r.lastIndex = 3; +assertEquals(["\ud801\udc01"], r.exec("\ud800\udc00\ud801\udc01")); +assertEquals(4, r.lastIndex); +r.lastIndex = 4; +assertNull(r.exec("\ud800\udc00\ud801\udc01")); +assertEquals(0, r.lastIndex); +r.lastIndex = 5; +assertNull(r.exec("\ud800\udc00\ud801\udc01")); +assertEquals(0, r.lastIndex); + +r.lastIndex = 3; +assertEquals(["\ud802"], r.exec("\ud800\udc00\ud801\ud802")); +r.lastIndex = 4; +assertNull(r.exec("\ud800\udc00\ud801\ud802")); + +r = /./g; +assertEquals(["\ud800"], r.exec("\ud800\udc00\ud801\udc01")); +assertEquals(1, r.lastIndex); +assertEquals(["\udc00"], r.exec("\ud800\udc00\ud801\udc01")); +assertEquals(2, r.lastIndex); +assertEquals(["\ud801"], r.exec("\ud800\udc00\ud801\udc01")); +assertEquals(3, r.lastIndex); +assertEquals(["\udc01"], r.exec("\ud800\udc00\ud801\udc01")); +assertEquals(4, r.lastIndex); +assertNull(r.exec("\ud800\udc00\ud801\udc01")); +assertEquals(0, r.lastIndex); +r.lastIndex = 1; +assertEquals(["\udc00"], r.exec("\ud800\udc00\ud801\udc01")); +assertEquals(2, r.lastIndex); + +// ------------------------ + +r = /^./ug; +assertEquals(["\ud800\udc00"], r.exec("\ud800\udc00\ud801\udc01")); +assertEquals(2, r.lastIndex); +r.lastIndex = 1; +assertEquals(["\ud800\udc00"], r.exec("\ud800\udc00\ud801\udc01")); +assertEquals(2, r.lastIndex); +assertNull(r.exec("\ud800\udc00\ud801\udc01")); +assertEquals(0, r.lastIndex); +r.lastIndex = 3; +assertNull(r.exec("\ud800\udc00\ud801\udc01")); +assertEquals(0, r.lastIndex); +r.lastIndex = 4; +assertNull(r.exec("\ud800\udc00\ud801\udc01")); +assertEquals(0, r.lastIndex); +r.lastIndex = 5; +assertNull(r.exec("\ud800\udc00\ud801\udc01")); +assertEquals(0, r.lastIndex); + +r = /^./g; +assertEquals(["\ud800"], r.exec("\ud800\udc00\ud801\udc01")); +assertEquals(1, r.lastIndex); +assertNull(r.exec("\ud800\udc00\ud801\udc01")); +assertEquals(0, r.lastIndex); +r.lastIndex = 3; +assertNull(r.exec("\ud800\udc00\ud801\udc01")); +assertEquals(0, r.lastIndex); + +//------------------------ + +r = /(?:(^.)|.)/ug; +assertEquals(["\ud800\udc00", "\ud800\udc00"], + r.exec("\ud800\udc00\ud801\udc01")); +assertEquals(2, r.lastIndex); +r.lastIndex = 1; +assertEquals(["\ud800\udc00", "\ud800\udc00"], + r.exec("\ud800\udc00\ud801\udc01")); +assertEquals(2, r.lastIndex); +assertEquals(["\ud801\udc01", undefined], r.exec("\ud800\udc00\ud801\udc01")); +r.lastIndex = 3; +assertEquals(["\ud801\udc01", undefined], r.exec("\ud800\udc00\ud801\udc01")); +r.lastIndex = 4; +assertNull(r.exec("\ud800\udc00\ud801\udc01")); +r.lastIndex = 5; +assertNull(r.exec("\ud800\udc00\ud801\udc01")); + +r.lastIndex = 3; +assertEquals(["\ud802", undefined], r.exec("\ud800\udc00\ud801\ud802")); +r.lastIndex = 4; +assertNull(r.exec("\ud800\udc00\ud801\ud802")); + +r = /(?:(^.)|.)/g; +assertEquals(["\ud800", "\ud800"], + r.exec("\ud800\udc00\ud801\udc01")); +assertEquals(1, r.lastIndex); +assertEquals(["\udc00", undefined], r.exec("\ud800\udc00\ud801\udc01")); +assertEquals(2, r.lastIndex); +r.lastIndex = 3; +assertEquals(["\udc01", undefined], r.exec("\ud800\udc00\ud801\udc01")); +assertEquals(4, r.lastIndex); diff --git a/deps/v8/test/mjsunit/es6/unicode-regexp-restricted-syntax.js b/deps/v8/test/mjsunit/es6/unicode-regexp-restricted-syntax.js new file mode 100644 index 0000000000..dd4fa39ab5 --- /dev/null +++ b/deps/v8/test/mjsunit/es6/unicode-regexp-restricted-syntax.js @@ -0,0 +1,42 @@ +// 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. + +// test262/data/test/language/literals/regexp/u-dec-esc +assertThrows("/\\1/u", SyntaxError); +// test262/language/literals/regexp/u-invalid-char-range-a +assertThrows("/[\\w-a]/u", SyntaxError); +// test262/language/literals/regexp/u-invalid-char-range-b +assertThrows("/[a-\\w]/u", SyntaxError); +// test262/language/literals/regexp/u-invalid-char-esc +assertThrows("/\\c/u", SyntaxError); +assertThrows("/\\c0/u", SyntaxError); +// test262/built-ins/RegExp/unicode_restricted_quantifiable_assertion +assertThrows("/(?=.)*/u", SyntaxError); +// test262/built-ins/RegExp/unicode_restricted_octal_escape +assertThrows("/[\\1]/u", SyntaxError); +assertThrows("/\\00/u", SyntaxError); +assertThrows("/\\09/u", SyntaxError); +// test262/built-ins/RegExp/unicode_restricted_identity_escape_alpha +assertThrows("/[\\c]/u", SyntaxError); +// test262/built-ins/RegExp/unicode_restricted_identity_escape_c +assertThrows("/[\\c0]/u", SyntaxError); +// test262/built-ins/RegExp/unicode_restricted_incomple_quantifier +assertThrows("/a{/u", SyntaxError); +assertThrows("/a{1,/u", SyntaxError); +assertThrows("/{/u", SyntaxError); +assertThrows("/}/u", SyntaxError); +// test262/data/test/built-ins/RegExp/unicode_restricted_brackets +assertThrows("/]/u", SyntaxError); +// test262/built-ins/RegExp/unicode_identity_escape +/\//u; + +// escaped \0 is allowed inside a character class. +assertEquals(["\0"], /[\0]/u.exec("\0")); +// unless it is followed by another digit. +assertThrows("/[\\00]/u", SyntaxError); +assertThrows("/[\\01]/u", SyntaxError); +assertThrows("/[\\09]/u", SyntaxError); +assertEquals(["\u{0}1\u{0}a\u{0}"], /[1\0a]+/u.exec("b\u{0}1\u{0}a\u{0}2")); +// escaped \- is allowed inside a character class. +assertEquals(["-"], /[a\-z]/u.exec("12-34")); diff --git a/deps/v8/test/mjsunit/es6/unicode-regexp-unanchored-advance.js b/deps/v8/test/mjsunit/es6/unicode-regexp-unanchored-advance.js new file mode 100644 index 0000000000..c471122baf --- /dev/null +++ b/deps/v8/test/mjsunit/es6/unicode-regexp-unanchored-advance.js @@ -0,0 +1,6 @@ +// Copyright 2013 the V8 project 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 s = "a".repeat(1E7) + "\u1234"; +assertEquals(["\u1234", "\u1234"], /(\u1234)/u.exec(s)); diff --git a/deps/v8/test/mjsunit/es6/unicode-regexp-zero-length.js b/deps/v8/test/mjsunit/es6/unicode-regexp-zero-length.js new file mode 100644 index 0000000000..42bb2d71dc --- /dev/null +++ b/deps/v8/test/mjsunit/es6/unicode-regexp-zero-length.js @@ -0,0 +1,56 @@ +// 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. + +var L = "\ud800"; +var T = "\udc00"; +var x = "x"; + +var r = /()/g; // Global, but not unicode. +// Zero-length matches do not advance lastIndex. +assertEquals(["", ""], r.exec(L + T + L + T)); +assertEquals(0, r.lastIndex); +r.lastIndex = 1; +assertEquals(["", ""], r.exec(L + T + L + T)); +assertEquals(1, r.lastIndex); + +var u = /()/ug; // Global and unicode. +// Zero-length matches do not advance lastIndex. +assertEquals(["", ""], u.exec(L + T + L + T)); +assertEquals(0, u.lastIndex); +u.lastIndex = 1; +assertEquals(["", ""], u.exec(L + T + L + T)); +assertEquals(0, u.lastIndex); + +// However, with repeating matches, lastIndex does not matter. +// We do advance from match to match. +r.lastIndex = 2; +assertEquals(x + L + x + T + x + L + x + T + x, + (L + T + L + T).replace(r, "x")); + +// With unicode flag, we advance code point by code point. +u.lastIndex = 3; +assertEquals(x + L + T + x + L + T + x, + (L + T + L + T).replace(u, "x")); + +// Test that exhausting the global match cache is fine. +assertEquals((x + L + T).repeat(1000) + x, + (L + T).repeat(1000).replace(u, "x")); + +// Same thing for RegExp.prototype.match. +r.lastIndex = 1; +assertEquals(["","","","",""], (L + T + L + T).match(r)); +r.lastIndex = 2; +assertEquals(["","","","",""], (L + T + L + T).match(r)); + +u.lastIndex = 1; +assertEquals(["","",""], (L + T + L + T).match(u)); +u.lastIndex = 2; +assertEquals(["","",""], (L + T + L + T).match(u)); + +var expected = []; +for (var i = 0; i <= 1000; i++) expected.push(""); +assertEquals(expected, (L + T).repeat(1000).match(u)); + +// Also test RegExp.prototype.@@split. +assertEquals(["\u{12345}"], "\u{12345}".split(/(?:)/u)); |