summaryrefslogtreecommitdiff
path: root/deps/v8/test/mjsunit/es6
diff options
context:
space:
mode:
Diffstat (limited to 'deps/v8/test/mjsunit/es6')
-rw-r--r--deps/v8/test/mjsunit/es6/array-concat.js866
-rw-r--r--deps/v8/test/mjsunit/es6/array-length.js2
-rw-r--r--deps/v8/test/mjsunit/es6/block-for.js2
-rw-r--r--deps/v8/test/mjsunit/es6/classes-super.js15
-rw-r--r--deps/v8/test/mjsunit/es6/completion.js150
-rw-r--r--deps/v8/test/mjsunit/es6/generators-iteration.js71
-rw-r--r--deps/v8/test/mjsunit/es6/generators-objects.js12
-rw-r--r--deps/v8/test/mjsunit/es6/generators-runtime.js2
-rw-r--r--deps/v8/test/mjsunit/es6/generators-states.js27
-rw-r--r--deps/v8/test/mjsunit/es6/hasinstance-symbol.js12
-rw-r--r--deps/v8/test/mjsunit/es6/no-unicode-regexp-flag.js2
-rw-r--r--deps/v8/test/mjsunit/es6/object-assign.js33
-rw-r--r--deps/v8/test/mjsunit/es6/object-literals-method.js6
-rw-r--r--deps/v8/test/mjsunit/es6/regexp-tolength.js2
-rw-r--r--deps/v8/test/mjsunit/es6/regexp-tostring.js46
-rw-r--r--deps/v8/test/mjsunit/es6/symbols.js3
-rw-r--r--deps/v8/test/mjsunit/es6/tail-call-megatest.js292
-rw-r--r--deps/v8/test/mjsunit/es6/tail-call-proxies.js97
-rw-r--r--deps/v8/test/mjsunit/es6/tail-call-simple.js107
-rw-r--r--deps/v8/test/mjsunit/es6/tail-call.js386
-rw-r--r--deps/v8/test/mjsunit/es6/typedarray.js16
21 files changed, 2080 insertions, 69 deletions
diff --git a/deps/v8/test/mjsunit/es6/array-concat.js b/deps/v8/test/mjsunit/es6/array-concat.js
new file mode 100644
index 0000000000..bc9e1a00cc
--- /dev/null
+++ b/deps/v8/test/mjsunit/es6/array-concat.js
@@ -0,0 +1,866 @@
+// 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-proxies --harmony-reflect
+
+(function testArrayConcatArity() {
+ "use strict";
+ assertEquals(1, Array.prototype.concat.length);
+})();
+
+
+(function testArrayConcatNoPrototype() {
+ "use strict";
+ assertEquals(void 0, Array.prototype.concat.prototype);
+})();
+
+
+(function testArrayConcatDescriptor() {
+ "use strict";
+ var desc = Object.getOwnPropertyDescriptor(Array.prototype, 'concat');
+ assertEquals(false, desc.enumerable);
+})();
+
+
+(function testConcatArrayLike() {
+ "use strict";
+ var obj = {
+ "length": 6,
+ "1": "A",
+ "3": "B",
+ "5": "C"
+ };
+ obj[Symbol.isConcatSpreadable] = true;
+ var obj2 = { length: 3, "0": "0", "1": "1", "2": "2" };
+ var arr = ["X", "Y", "Z"];
+ assertEquals([void 0, "A", void 0, "B", void 0, "C",
+ { "length": 3, "0": "0", "1": "1", "2": "2" },
+ "X", "Y", "Z"], Array.prototype.concat.call(obj, obj2, arr));
+})();
+
+
+(function testConcatArrayLikeStringLength() {
+ "use strict";
+ var obj = {
+ "length": "6",
+ "1": "A",
+ "3": "B",
+ "5": "C"
+ };
+ obj[Symbol.isConcatSpreadable] = true;
+ var obj2 = { length: 3, "0": "0", "1": "1", "2": "2" };
+ var arr = ["X", "Y", "Z"];
+ assertEquals([void 0, "A", void 0, "B", void 0, "C",
+ { "length": 3, "0": "0", "1": "1", "2": "2" },
+ "X", "Y", "Z"], Array.prototype.concat.call(obj, obj2, arr));
+})();
+
+
+(function testConcatArrayLikeNegativeLength() {
+ "use strict";
+ var obj = {
+ "length": -6,
+ "1": "A",
+ "3": "B",
+ "5": "C"
+ };
+ obj[Symbol.isConcatSpreadable] = true;
+ assertEquals([], [].concat(obj));
+ obj.length = -6.7;
+ assertEquals([], [].concat(obj));
+ obj.length = "-6";
+ assertEquals([], [].concat(obj));
+})();
+
+
+(function testConcatArrayLikeToLengthThrows() {
+ "use strict";
+ var obj = {
+ "length": {valueOf: null, toString: null},
+ "1": "A",
+ "3": "B",
+ "5": "C"
+ };
+ obj[Symbol.isConcatSpreadable] = true;
+ var obj2 = { length: 3, "0": "0", "1": "1", "2": "2" };
+ var arr = ["X", "Y", "Z"];
+ assertThrows(function() {
+ Array.prototype.concat.call(obj, obj2, arr);
+ }, TypeError);
+})();
+
+
+(function testConcatArrayLikePrimitiveNonNumberLength() {
+ "use strict";
+ var obj = {
+ "1": "A",
+ "3": "B",
+ "5": "C"
+ };
+ obj[Symbol.isConcatSpreadable] = true;
+ obj.length = {toString: function() { return "SIX"; }, valueOf: null };
+ assertEquals([], [].concat(obj));
+ obj.length = {toString: null, valueOf: function() { return "SIX"; } };
+ assertEquals([], [].concat(obj));
+})();
+
+
+(function testConcatArrayLikeLengthToStringThrows() {
+ "use strict";
+ function MyError() {}
+ var obj = {
+ "length": { toString: function() {
+ throw new MyError();
+ }, valueOf: null
+ },
+ "1": "A",
+ "3": "B",
+ "5": "C"
+ };
+ obj[Symbol.isConcatSpreadable] = true;
+ assertThrows(function() {
+ [].concat(obj);
+ }, MyError);
+})();
+
+
+(function testConcatArrayLikeLengthValueOfThrows() {
+ "use strict";
+ function MyError() {}
+ var obj = {
+ "length": { valueOf: function() {
+ throw new MyError();
+ }, toString: null
+ },
+ "1": "A",
+ "3": "B",
+ "5": "C"
+};
+obj[Symbol.isConcatSpreadable] = true;
+assertThrows(function() {
+ [].concat(obj);
+}, MyError);
+})();
+
+
+(function testConcatHoleyArray() {
+ "use strict";
+ var arr = [];
+ arr[4] = "Item 4";
+ arr[8] = "Item 8";
+ var arr2 = [".", "!", "?"];
+ assertEquals([void 0, void 0, void 0, void 0, "Item 4", void 0, void 0,
+ void 0, "Item 8", ".", "!", "?"], arr.concat(arr2));
+})();
+
+
+(function testIsConcatSpreadableGetterThrows() {
+ "use strict";
+ function MyError() {}
+ var obj = {};
+ Object.defineProperty(obj, Symbol.isConcatSpreadable, {
+ get: function() { throw new MyError(); }
+ });
+
+ assertThrows(function() {
+ [].concat(obj);
+ }, MyError);
+
+ assertThrows(function() {
+ Array.prototype.concat.call(obj, 1, 2, 3);
+ }, MyError);
+})();
+
+
+(function testConcatLengthThrows() {
+ "use strict";
+ function MyError() {}
+ var obj = {};
+ obj[Symbol.isConcatSpreadable] = true;
+ Object.defineProperty(obj, "length", {
+ get: function() { throw new MyError(); }
+ });
+
+ assertThrows(function() {
+ [].concat(obj);
+ }, MyError);
+
+ assertThrows(function() {
+ Array.prototype.concat.call(obj, 1, 2, 3);
+ }, MyError);
+})();
+
+
+(function testConcatArraySubclass() {
+ "use strict";
+ // If @@isConcatSpreadable is not used, the value of IsArray(O)
+ // is used to determine the spreadable property.
+ class A extends Array {}
+ var obj = [].concat(new A(1, 2, 3), new A(4, 5, 6), new A(7, 8, 9));
+ assertEquals(9, obj.length);
+ for (var i = 0; i < obj.length; ++i) {
+ assertEquals(i + 1, obj[i]);
+ }
+
+ // TODO(caitp): when concat is called on instances of classes which extend
+ // Array, they should:
+ //
+ // - return an instance of the class, rather than an Array instance (if from
+ // same Realm)
+ // - always treat such classes as concat-spreadable
+})();
+
+
+(function testConcatArraySubclassOptOut() {
+ "use strict";
+ class A extends Array {
+ get [Symbol.isConcatSpreadable]() { return false; }
+ }
+ var obj = [].concat(new A(1, 2, 3), new A(4, 5, 6), new A(7, 8, 9));
+ assertEquals(3, obj.length);
+ assertEquals(3, obj[0].length);
+ assertEquals(3, obj[1].length);
+ assertEquals(3, obj[2].length);
+})();
+
+
+(function testConcatNonArray() {
+ "use strict";
+ class NonArray {
+ constructor() { Array.apply(this, arguments); }
+ };
+
+ var obj = new NonArray(1,2,3);
+ var result = Array.prototype.concat.call(obj, 4, 5, 6);
+ assertEquals(Array, result.constructor);
+ assertEquals([obj,4,5,6], result);
+ assertFalse(result instanceof NonArray);
+})();
+
+
+function testConcatTypedArray(type, elems, modulo) {
+ "use strict";
+ var items = new Array(elems);
+ var ta_by_len = new type(elems);
+ for (var i = 0; i < elems; ++i) {
+ ta_by_len[i] = items[i] = modulo === false ? i : elems % modulo;
+ }
+ var ta = new type(items);
+ assertEquals([ta, ta], [].concat(ta, ta));
+ ta[Symbol.isConcatSpreadable] = true;
+ assertEquals(items, [].concat(ta));
+
+ assertEquals([ta_by_len, ta_by_len], [].concat(ta_by_len, ta_by_len));
+ ta_by_len[Symbol.isConcatSpreadable] = true;
+ assertEquals(items, [].concat(ta_by_len));
+
+ // TypedArray with fake `length`.
+ ta = new type(1);
+ var defValue = ta[0];
+ var expected = new Array(4000);
+ expected[0] = defValue;
+
+ Object.defineProperty(ta, "length", { value: 4000 });
+ ta[Symbol.isConcatSpreadable] = true;
+ assertEquals(expected, [].concat(ta));
+}
+
+(function testConcatSmallTypedArray() {
+ var length = 1;
+ testConcatTypedArray(Uint8Array, length, Math.pow(2, 8));
+ testConcatTypedArray(Uint16Array, length, Math.pow(2, 16));
+ testConcatTypedArray(Uint32Array, length, Math.pow(2, 32));
+ testConcatTypedArray(Float32Array, length, false);
+ testConcatTypedArray(Float64Array, length, false);
+})();
+
+
+(function testConcatLargeTypedArray() {
+ var length = 4000;
+ testConcatTypedArray(Uint8Array, length, Math.pow(2, 8));
+ testConcatTypedArray(Uint16Array, length, Math.pow(2, 16));
+ testConcatTypedArray(Uint32Array, length, Math.pow(2, 32));
+ testConcatTypedArray(Float32Array, length, false);
+ testConcatTypedArray(Float64Array, length, false);
+})();
+
+
+(function testConcatStrictArguments() {
+ var args = (function(a, b, c) { "use strict"; return arguments; })(1,2,3);
+ args[Symbol.isConcatSpreadable] = true;
+ assertEquals([1, 2, 3, 1, 2, 3], [].concat(args, args));
+
+ Object.defineProperty(args, "length", { value: 6 });
+ assertEquals([1, 2, 3, void 0, void 0, void 0], [].concat(args));
+})();
+
+
+(function testConcatSloppyArguments() {
+ var args = (function(a, b, c) { return arguments; })(1,2,3);
+ args[Symbol.isConcatSpreadable] = true;
+ assertEquals([1, 2, 3, 1, 2, 3], [].concat(args, args));
+
+ Object.defineProperty(args, "length", { value: 6 });
+ assertEquals([1, 2, 3, void 0, void 0, void 0], [].concat(args));
+})();
+
+
+(function testConcatSloppyArgumentsWithDupes() {
+ var args = (function(a, a, a) { return arguments; })(1,2,3);
+ args[Symbol.isConcatSpreadable] = true;
+ assertEquals([1, 2, 3, 1, 2, 3], [].concat(args, args));
+
+ Object.defineProperty(args, "length", { value: 6 });
+ assertEquals([1, 2, 3, void 0, void 0, void 0], [].concat(args));
+})();
+
+
+(function testConcatSloppyArgumentsThrows() {
+ function MyError() {}
+ var args = (function(a) { return arguments; })(1,2,3);
+ Object.defineProperty(args, 0, {
+ get: function() { throw new MyError(); }
+ });
+ args[Symbol.isConcatSpreadable] = true;
+ assertThrows(function() {
+ return [].concat(args, args);
+ }, MyError);
+})();
+
+
+(function testConcatHoleySloppyArguments() {
+ var args = (function(a) { return arguments; })(1,2,3);
+ delete args[1];
+ args[Symbol.isConcatSpreadable] = true;
+ assertEquals([1, void 0, 3, 1, void 0, 3], [].concat(args, args));
+})();
+
+
+(function testConcatSpreadableStringWrapper() {
+ "use strict";
+ var str1 = new String("yuck\uD83D\uDCA9")
+ // String wrapper objects are not concat-spreadable by default
+ assertEquals([str1], [].concat(str1));
+
+ // String wrapper objects may be individually concat-spreadable
+ str1[Symbol.isConcatSpreadable] = true;
+ assertEquals(["y", "u", "c", "k", "\uD83D", "\uDCA9"],
+ [].concat(str1));
+
+ String.prototype[Symbol.isConcatSpreadable] = true;
+ // String wrapper objects may be concat-spreadable
+ assertEquals(["y", "u", "c", "k", "\uD83D", "\uDCA9"],
+ [].concat(new String("yuck\uD83D\uDCA9")));
+
+ // String values are never concat-spreadable
+ assertEquals(["yuck\uD83D\uDCA9"], [].concat("yuck\uD83D\uDCA9"));
+ delete String.prototype[Symbol.isConcatSpreadable];
+})();
+
+
+(function testConcatSpreadableBooleanWrapper() {
+ "use strict";
+ var bool = new Boolean(true)
+ // Boolean wrapper objects are not concat-spreadable by default
+ assertEquals([bool], [].concat(bool));
+
+ // Boolean wrapper objects may be individually concat-spreadable
+ bool[Symbol.isConcatSpreadable] = true;
+ bool.length = 3;
+ bool[0] = 1, bool[1] = 2, bool[2] = 3;
+ assertEquals([1, 2, 3], [].concat(bool));
+
+ Boolean.prototype[Symbol.isConcatSpreadable] = true;
+ // Boolean wrapper objects may be concat-spreadable
+ assertEquals([], [].concat(new Boolean(true)));
+ Boolean.prototype[0] = 1;
+ Boolean.prototype[1] = 2;
+ Boolean.prototype[2] = 3;
+ Boolean.prototype.length = 3;
+ assertEquals([1,2,3], [].concat(new Boolean(true)));
+
+ // Boolean values are never concat-spreadable
+ assertEquals([true], [].concat(true));
+ delete Boolean.prototype[Symbol.isConcatSpreadable];
+ delete Boolean.prototype[0];
+ delete Boolean.prototype[1];
+ delete Boolean.prototype[2];
+ delete Boolean.prototype.length;
+})();
+
+
+(function testConcatSpreadableNumberWrapper() {
+ "use strict";
+ var num = new Number(true)
+ // Number wrapper objects are not concat-spreadable by default
+ assertEquals([num], [].concat(num));
+
+ // Number wrapper objects may be individually concat-spreadable
+ num[Symbol.isConcatSpreadable] = true;
+ num.length = 3;
+ num[0] = 1, num[1] = 2, num[2] = 3;
+ assertEquals([1, 2, 3], [].concat(num));
+
+ Number.prototype[Symbol.isConcatSpreadable] = true;
+ // Number wrapper objects may be concat-spreadable
+ assertEquals([], [].concat(new Number(123)));
+ Number.prototype[0] = 1;
+ Number.prototype[1] = 2;
+ Number.prototype[2] = 3;
+ Number.prototype.length = 3;
+ assertEquals([1,2,3], [].concat(new Number(123)));
+
+ // Number values are never concat-spreadable
+ assertEquals([true], [].concat(true));
+ delete Number.prototype[Symbol.isConcatSpreadable];
+ delete Number.prototype[0];
+ delete Number.prototype[1];
+ delete Number.prototype[2];
+ delete Number.prototype.length;
+})();
+
+
+(function testConcatSpreadableFunction() {
+ "use strict";
+ var fn = function(a, b, c) {}
+ // Functions are not concat-spreadable by default
+ assertEquals([fn], [].concat(fn));
+
+ // Functions may be individually concat-spreadable
+ fn[Symbol.isConcatSpreadable] = true;
+ fn[0] = 1, fn[1] = 2, fn[2] = 3;
+ assertEquals([1, 2, 3], [].concat(fn));
+
+ Function.prototype[Symbol.isConcatSpreadable] = true;
+ // Functions may be concat-spreadable
+ assertEquals([void 0, void 0, void 0], [].concat(function(a,b,c) {}));
+ Function.prototype[0] = 1;
+ Function.prototype[1] = 2;
+ Function.prototype[2] = 3;
+ assertEquals([1,2,3], [].concat(function(a, b, c) {}));
+
+ delete Function.prototype[Symbol.isConcatSpreadable];
+ delete Function.prototype[0];
+ delete Function.prototype[1];
+ delete Function.prototype[2];
+})();
+
+
+(function testConcatSpreadableRegExp() {
+ "use strict";
+ var re = /abc/;
+ // RegExps are not concat-spreadable by default
+ assertEquals([re], [].concat(re));
+
+ // RegExps may be individually concat-spreadable
+ re[Symbol.isConcatSpreadable] = true;
+ re[0] = 1, re[1] = 2, re[2] = 3, re.length = 3;
+ assertEquals([1, 2, 3], [].concat(re));
+
+ // RegExps may be concat-spreadable
+ RegExp.prototype[Symbol.isConcatSpreadable] = true;
+ RegExp.prototype.length = 3;
+
+ assertEquals([void 0, void 0, void 0], [].concat(/abc/));
+ RegExp.prototype[0] = 1;
+ RegExp.prototype[1] = 2;
+ RegExp.prototype[2] = 3;
+ assertEquals([1,2,3], [].concat(/abc/));
+
+ delete RegExp.prototype[Symbol.isConcatSpreadable];
+ delete RegExp.prototype[0];
+ delete RegExp.prototype[1];
+ delete RegExp.prototype[2];
+ delete RegExp.prototype.length;
+})();
+
+
+(function testArrayConcatSpreadableSparseObject() {
+ "use strict";
+ var obj = { length: 5 };
+ obj[Symbol.isConcatSpreadable] = true;
+ assertEquals([void 0, void 0, void 0, void 0, void 0], [].concat(obj));
+
+ obj.length = 4000;
+ assertEquals(new Array(4000), [].concat(obj));
+})();
+
+
+// ES5 tests
+(function testArrayConcatES5() {
+ "use strict";
+ var poses;
+ var pos;
+
+ poses = [140, 4000000000];
+ while (pos = poses.shift()) {
+ var a = new Array(pos);
+ var array_proto = [];
+ a.__proto__ = array_proto;
+ assertEquals(pos, a.length);
+ a.push('foo');
+ assertEquals(pos + 1, a.length);
+ var b = ['bar'];
+ var c = a.concat(b);
+ assertEquals(pos + 2, c.length);
+ assertEquals("undefined", typeof(c[pos - 1]));
+ assertEquals("foo", c[pos]);
+ assertEquals("bar", c[pos + 1]);
+
+ // Can we fool the system by putting a number in a string?
+ var onetwofour = "124";
+ a[onetwofour] = 'doo';
+ assertEquals(a[124], 'doo');
+ c = a.concat(b);
+ assertEquals(c[124], 'doo');
+
+ // If we put a number in the prototype, then the spec says it should be
+ // copied on concat.
+ array_proto["123"] = 'baz';
+ assertEquals(a[123], 'baz');
+
+ c = a.concat(b);
+ assertEquals(pos + 2, c.length);
+ assertEquals("baz", c[123]);
+ assertEquals("undefined", typeof(c[pos - 1]));
+ assertEquals("foo", c[pos]);
+ assertEquals("bar", c[pos + 1]);
+
+ // When we take the number off the prototype it disappears from a, but
+ // the concat put it in c itself.
+ array_proto["123"] = undefined;
+ assertEquals("undefined", typeof(a[123]));
+ assertEquals("baz", c[123]);
+
+ // If the element of prototype is shadowed, the element on the instance
+ // should be copied, but not the one on the prototype.
+ array_proto[123] = 'baz';
+ a[123] = 'xyz';
+ assertEquals('xyz', a[123]);
+ c = a.concat(b);
+ assertEquals('xyz', c[123]);
+
+ // Non-numeric properties on the prototype or the array shouldn't get
+ // copied.
+ array_proto.moe = 'joe';
+ a.ben = 'jerry';
+ assertEquals(a["moe"], 'joe');
+ assertEquals(a["ben"], 'jerry');
+ c = a.concat(b);
+ // ben was not copied
+ assertEquals("undefined", typeof(c.ben));
+
+ // When we take moe off the prototype it disappears from all arrays.
+ array_proto.moe = undefined;
+ assertEquals("undefined", typeof(c.moe));
+
+ // Negative indices don't get concated.
+ a[-1] = 'minus1';
+ assertEquals("minus1", a[-1]);
+ assertEquals("undefined", typeof(a[0xffffffff]));
+ c = a.concat(b);
+ assertEquals("undefined", typeof(c[-1]));
+ assertEquals("undefined", typeof(c[0xffffffff]));
+ assertEquals(c.length, a.length + 1);
+ }
+
+ poses = [140, 4000000000];
+ while (pos = poses.shift()) {
+ var a = new Array(pos);
+ assertEquals(pos, a.length);
+ a.push('foo');
+ assertEquals(pos + 1, a.length);
+ var b = ['bar'];
+ var c = a.concat(b);
+ assertEquals(pos + 2, c.length);
+ assertEquals("undefined", typeof(c[pos - 1]));
+ assertEquals("foo", c[pos]);
+ assertEquals("bar", c[pos + 1]);
+
+ // Can we fool the system by putting a number in a string?
+ var onetwofour = "124";
+ a[onetwofour] = 'doo';
+ assertEquals(a[124], 'doo');
+ c = a.concat(b);
+ assertEquals(c[124], 'doo');
+
+ // If we put a number in the prototype, then the spec says it should be
+ // copied on concat.
+ Array.prototype["123"] = 'baz';
+ assertEquals(a[123], 'baz');
+
+ c = a.concat(b);
+ assertEquals(pos + 2, c.length);
+ assertEquals("baz", c[123]);
+ assertEquals("undefined", typeof(c[pos - 1]));
+ assertEquals("foo", c[pos]);
+ assertEquals("bar", c[pos + 1]);
+
+ // When we take the number off the prototype it disappears from a, but
+ // the concat put it in c itself.
+ Array.prototype["123"] = undefined;
+ assertEquals("undefined", typeof(a[123]));
+ assertEquals("baz", c[123]);
+
+ // If the element of prototype is shadowed, the element on the instance
+ // should be copied, but not the one on the prototype.
+ Array.prototype[123] = 'baz';
+ a[123] = 'xyz';
+ assertEquals('xyz', a[123]);
+ c = a.concat(b);
+ assertEquals('xyz', c[123]);
+
+ // Non-numeric properties on the prototype or the array shouldn't get
+ // copied.
+ Array.prototype.moe = 'joe';
+ a.ben = 'jerry';
+ assertEquals(a["moe"], 'joe');
+ assertEquals(a["ben"], 'jerry');
+ c = a.concat(b);
+ // ben was not copied
+ assertEquals("undefined", typeof(c.ben));
+ // moe was not copied, but we can see it through the prototype
+ assertEquals("joe", c.moe);
+
+ // When we take moe off the prototype it disappears from all arrays.
+ Array.prototype.moe = undefined;
+ assertEquals("undefined", typeof(c.moe));
+
+ // Negative indices don't get concated.
+ a[-1] = 'minus1';
+ assertEquals("minus1", a[-1]);
+ assertEquals("undefined", typeof(a[0xffffffff]));
+ c = a.concat(b);
+ assertEquals("undefined", typeof(c[-1]));
+ assertEquals("undefined", typeof(c[0xffffffff]));
+ assertEquals(c.length, a.length + 1);
+
+ }
+
+ a = [];
+ c = a.concat('Hello');
+ assertEquals(1, c.length);
+ assertEquals("Hello", c[0]);
+ assertEquals("Hello", c.toString());
+
+ // Check that concat preserves holes.
+ var holey = [void 0,'a',,'c'].concat(['d',,'f',[0,,2],void 0])
+ assertEquals(9, holey.length); // hole in embedded array is ignored
+ for (var i = 0; i < holey.length; i++) {
+ if (i == 2 || i == 5) {
+ assertFalse(i in holey);
+ } else {
+ assertTrue(i in holey);
+ }
+ }
+
+ // Polluted prototype from prior tests.
+ delete Array.prototype[123];
+
+ // Check that concat reads getters in the correct order.
+ var arr1 = [,2];
+ var arr2 = [1,3];
+ var r1 = [].concat(arr1, arr2); // [,2,1,3]
+ assertEquals([,2,1,3], r1);
+
+ // Make first array change length of second array.
+ Object.defineProperty(arr1, 0, {get: function() {
+ arr2.push("X");
+ return undefined;
+ }, configurable: true})
+ var r2 = [].concat(arr1, arr2); // [undefined,2,1,3,"X"]
+ assertEquals([undefined,2,1,3,"X"], r2);
+
+ // Make first array change length of second array massively.
+ arr2.length = 2;
+ Object.defineProperty(arr1, 0, {get: function() {
+ arr2[500000] = "X";
+ return undefined;
+ }, configurable: true})
+ var r3 = [].concat(arr1, arr2); // [undefined,2,1,3,"X"]
+ var expected = [undefined,2,1,3];
+ expected[500000 + 2] = "X";
+
+ assertEquals(expected, r3);
+
+ var arr3 = [];
+ var trace = [];
+ var expectedTrace = []
+ function mkGetter(i) { return function() { trace.push(i); }; }
+ arr3.length = 10000;
+ for (var i = 0; i < 100; i++) {
+ Object.defineProperty(arr3, i * i, {get: mkGetter(i)});
+ expectedTrace[i] = i;
+ expectedTrace[100 + i] = i;
+ }
+ var r4 = [0].concat(arr3, arr3);
+ assertEquals(1 + arr3.length * 2, r4.length);
+ assertEquals(expectedTrace, trace);
+
+ // Clean up.
+ delete Array.prototype[123];
+ delete Array.prototype["123"];
+ delete Array.prototype["moe"];
+})();
+
+
+
+
+////////////////////////////////////////////////////////////////////////////////
+// Tests with proxies
+
+// Note: concat does not currently support species so there is no difference
+// between [].concat(foo) and Array.prototype.concat.apply(foo).
+
+
+var log = [];
+var logger = {};
+var handler = new Proxy({}, logger);
+
+logger.get = function(t, trap, r) {
+ return function(...args) {
+ log.push([trap, ...args]);
+ return Reflect[trap](...args);
+ }
+};
+
+
+(function testUnspreadableNonArrayLikeProxy() {
+ var target = {0: "a", 1: "b"};
+ var obj = new Proxy(target, handler);
+
+ log.length = 0;
+ assertEquals([obj], [].concat(obj));
+ assertEquals(1, log.length);
+ for (var i in log) assertSame(target, log[i][1]);
+ assertEquals(["get", target, Symbol.isConcatSpreadable, obj], log[0]);
+
+ log.length = 0;
+ assertEquals([obj], Array.prototype.concat.apply(obj));
+ assertEquals(1, log.length);
+ for (var i in log) assertSame(target, log[i][1]);
+ assertEquals(["get", target, Symbol.isConcatSpreadable, obj], log[0]);
+})();
+
+
+(function testSpreadableNonArrayLikeProxy() {
+ var target = {0: "a", 1: "b", [Symbol.isConcatSpreadable]: "truish"};
+ var obj = new Proxy(target, handler);
+
+ log.length = 0;
+ assertEquals([], [].concat(obj));
+ assertEquals(2, log.length);
+ for (var i in log) assertSame(target, log[i][1]);
+ assertEquals(["get", target, Symbol.isConcatSpreadable, obj], log[0]);
+ assertEquals(["get", target, "length", obj], log[1]);
+
+ log.length = 0;
+ assertEquals([], Array.prototype.concat.apply(obj));
+ assertEquals(2, log.length);
+ for (var i in log) assertSame(target, log[i][1]);
+ assertEquals(["get", target, Symbol.isConcatSpreadable, obj], log[0]);
+ assertEquals(["get", target, "length", obj], log[1]);
+
+ target.length = 3;
+
+ log.length = 0;
+ assertEquals(["a", "b", undefined], [].concat(obj));
+ assertEquals(7, log.length);
+ for (var i in log) assertSame(target, log[i][1]);
+ assertEquals(["get", target, Symbol.isConcatSpreadable, obj], log[0]);
+ assertEquals(["get", target, "length", obj], log[1]);
+ assertEquals(["has", target, "0"], log[2]);
+ assertEquals(["get", target, "0", obj], log[3]);
+ assertEquals(["has", target, "1"], log[4]);
+ assertEquals(["get", target, "1", obj], log[5]);
+ assertEquals(["has", target, "2"], log[6]);
+
+ log.length = 0;
+ assertEquals(["a", "b", undefined], Array.prototype.concat.apply(obj));
+ assertEquals(7, log.length);
+ for (var i in log) assertSame(target, log[i][1]);
+ assertEquals(["get", target, Symbol.isConcatSpreadable, obj], log[0]);
+ assertEquals(["get", target, "length", obj], log[1]);
+ assertEquals(["has", target, "0"], log[2]);
+ assertEquals(["get", target, "0", obj], log[3]);
+ assertEquals(["has", target, "1"], log[4]);
+ assertEquals(["get", target, "1", obj], log[5]);
+ assertEquals(["has", target, "2"], log[6]);
+})();
+
+
+(function testUnspreadableArrayLikeProxy() {
+ var target = ["a", "b"];
+ target[Symbol.isConcatSpreadable] = "";
+ var obj = new Proxy(target, handler);
+
+ log.length = 0;
+ assertEquals([obj], [].concat(obj));
+ assertEquals(1, log.length);
+ for (var i in log) assertSame(target, log[i][1]);
+ assertEquals(["get", target, Symbol.isConcatSpreadable, obj], log[0]);
+
+ log.length = 0;
+ assertEquals([obj], Array.prototype.concat.apply(obj));
+ assertEquals(1, log.length);
+ for (var i in log) assertSame(target, log[i][1]);
+ assertEquals(["get", target, Symbol.isConcatSpreadable, obj], log[0]);
+})();
+
+
+(function testSpreadableArrayLikeProxy() {
+ var target = ["a", "b"];
+ target[Symbol.isConcatSpreadable] = undefined;
+ var obj = new Proxy(target, handler);
+
+ log.length = 0;
+ assertEquals(["a", "b"], [].concat(obj));
+ assertEquals(6, log.length);
+ for (var i in log) assertSame(target, log[i][1]);
+ assertEquals(["get", target, Symbol.isConcatSpreadable, obj], log[0]);
+ assertEquals(["get", target, "length", obj], log[1]);
+ assertEquals(["has", target, "0"], log[2]);
+ assertEquals(["get", target, "0", obj], log[3]);
+ assertEquals(["has", target, "1"], log[4]);
+ assertEquals(["get", target, "1", obj], log[5]);
+
+ log.length = 0;
+ assertEquals(["a", "b"], Array.prototype.concat.apply(obj));
+ assertEquals(6, log.length);
+ for (var i in log) assertSame(target, log[i][1]);
+ assertEquals(["get", target, Symbol.isConcatSpreadable, obj], log[0]);
+ assertEquals(["get", target, "length", obj], log[1]);
+ assertEquals(["has", target, "0"], log[2]);
+ assertEquals(["get", target, "0", obj], log[3]);
+ assertEquals(["has", target, "1"], log[4]);
+ assertEquals(["get", target, "1", obj], log[5]);
+})();
+
+
+(function testSpreadableArrayLikeProxyWithNontrivialLength() {
+ var getTrap = function(t, key) {
+ if (key === "length") return {[Symbol.toPrimitive]() {return 3}};
+ if (key === "2") return "baz";
+ if (key === "3") return "bar";
+ };
+ var target = [];
+ var obj = new Proxy(target, {get: getTrap, has: () => true});
+
+ assertEquals([undefined, undefined, "baz"], [].concat(obj));
+ assertEquals([undefined, undefined, "baz"], Array.prototype.concat.apply(obj))
+})();
+
+
+(function testSpreadableArrayLikeProxyWithBogusLength() {
+ var getTrap = function(t, key) {
+ if (key === "length") return Symbol();
+ if (key === "2") return "baz";
+ if (key === "3") return "bar";
+ };
+ var target = [];
+ var obj = new Proxy(target, {get: getTrap, has: () => true});
+
+ assertThrows(() => [].concat(obj), TypeError);
+ assertThrows(() => Array.prototype.concat.apply(obj), TypeError);
+})();
diff --git a/deps/v8/test/mjsunit/es6/array-length.js b/deps/v8/test/mjsunit/es6/array-length.js
index cc3b88105c..06efe00901 100644
--- a/deps/v8/test/mjsunit/es6/array-length.js
+++ b/deps/v8/test/mjsunit/es6/array-length.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-tolength
-
// Test array functions do not cause infinite loops when length is negative,
// max_value, etc.
diff --git a/deps/v8/test/mjsunit/es6/block-for.js b/deps/v8/test/mjsunit/es6/block-for.js
index c7a23e8d32..d953d376f0 100644
--- a/deps/v8/test/mjsunit/es6/block-for.js
+++ b/deps/v8/test/mjsunit/es6/block-for.js
@@ -25,8 +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-completion
-
"use strict";
function props(x) {
diff --git a/deps/v8/test/mjsunit/es6/classes-super.js b/deps/v8/test/mjsunit/es6/classes-super.js
new file mode 100644
index 0000000000..7bdf4ba86c
--- /dev/null
+++ b/deps/v8/test/mjsunit/es6/classes-super.js
@@ -0,0 +1,15 @@
+// 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.
+
+"use strict";
+
+class Test {
+ m() {
+ super.length = 10;
+ }
+}
+
+var array = [];
+Test.prototype.m.call(array);
+assertEquals(10, array.length);
diff --git a/deps/v8/test/mjsunit/es6/completion.js b/deps/v8/test/mjsunit/es6/completion.js
new file mode 100644
index 0000000000..05565bfb45
--- /dev/null
+++ b/deps/v8/test/mjsunit/es6/completion.js
@@ -0,0 +1,150 @@
+// 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: --harmony-sloppy-let --no-legacy-const
+
+
+function assertUndef(x) {
+ assertEquals(undefined, x);
+}
+
+
+// IfStatement [13.6.7]
+
+assertUndef(eval('42; if (true) ; else 0;')); // ES5: 42
+assertUndef(eval('42; if (true) ;')); // ES5: 42
+assertUndef(eval('42; if (false) 0;')); // ES5: 42
+
+assertEquals(1, eval('42; if (true) 1;'));
+assertEquals(1, eval('42; if (true) 1; else 0;'));
+assertEquals(0, eval('42; if (false) 1; else 0;'));
+
+
+// IterationStatement [13.7]
+
+assertUndef(eval('42; do ; while (false);')); // ES5: 42
+assertUndef(eval('42; var x = 1; do ; while (x--);')); // ES5: 42
+assertUndef(eval('42; while (false) 0;')); // ES5: 42
+assertUndef(eval('42; while (true) break;')); // ES5: 42
+assertUndef(eval('42; bla: while (true) break bla;')); // ES5: 42
+assertUndef(eval('42; var x = 1; while (x--) ;')); // ES5: 42
+assertUndef(eval('42; for (; false; ) 0;')); // ES5: 42
+assertUndef(eval('42; for (var x = 1; x; x--) ;')); // ES5: 42
+assertUndef(eval('42; for (var x in ["foo", "bar"]) ;'));
+assertUndef(eval('42; for (var x of ["foo", "bar"]) ;'));
+assertUndef(eval('42; for (let x = 1; x; x--) ;'));
+assertUndef(eval('42; for (let x in ["foo", "bar"]) ;'));
+assertUndef(eval('42; for (let x of ["foo", "bar"]) ;'));
+assertUndef(eval('42; for (const x in ["foo", "bar"]) ;'));
+assertUndef(eval('42; for (const x of ["foo", "bar"]) ;'));
+
+assertEquals(1, eval('42; var x = 10; do x--; while (x);'));
+assertEquals(1, eval('42; var x = 10; while (x) x--;'));
+assertEquals(1, eval('42; for (var x = 10; x; x--) x;'));
+assertEquals(1, eval('42; for (var x = 10; x; --x) x;'));
+assertEquals(1, eval('42; for (let x = 10; x; --x) x;'));
+assertEquals(1, eval('42; var y = 2; for (var x in ["foo", "bar"]) y--;'));
+assertEquals(1, eval('42; var y = 2; for (const x in ["foo", "bar"]) y--;'));
+assertEquals(1, eval('42; var y = 2; for (let x in ["foo", "bar"]) y--;'));
+assertEquals(1, eval('42; var y = 2; for (var x of ["foo", "bar"]) y--;'));
+assertEquals(1, eval('42; var y = 2; for (const x of ["foo", "bar"]) y--;'));
+assertEquals(1, eval('42; var y = 2; for (let x of ["foo", "bar"]) y--;'));
+
+
+// WithStatement [13.11.7]
+
+assertUndef(eval('42; with ({}) ;')); // ES5: 42
+
+assertEquals(1, eval('42; with ({}) 1;'));
+
+
+// SwitchStatement [13.12.11]
+
+assertUndef(eval('42; switch (0) {};')); // ES5: 42
+assertUndef(eval('42; switch (0) { case 1: 1; };')); // ES5: 42
+assertUndef(eval('42; switch (0) { case 0: ; };')); // ES5: 42
+assertUndef(eval('42; switch (0) { default: ; };')); // ES5: 42
+assertUndef(eval('42; switch (0) { case 0: break; }')); // ES5: 42
+
+assertEquals(1, eval('42; switch (0) { case 0: 1; }'));
+assertEquals(1, eval('42; switch (0) { case 0: 1; break; }'));
+assertEquals(1, eval('42; switch (0) { case 0: 1; case 666: break; }'));
+assertEquals(2, eval('42; switch (0) { case 0: 1; case 666: 2; break; }'));
+
+
+// TryStatement [13.15.8]
+
+assertUndef(eval('42; try { } catch(e) { };')); // ES5: 42
+assertUndef(eval('42; try { } catch(e) { 0; };')); // ES5: 42
+assertUndef(eval('42; try { throw "" } catch(e) { };')); // ES5: 42
+assertUndef(eval('42; try { throw "" } catch(e) { } finally { };')); // ES5: 42
+assertUndef(eval('42; try { } finally { 666 };')); // ES5: 42
+
+
+// Some combinations
+
+assertUndef(eval('42; switch (0) { case 0: if (true) break; }')); // ES5: 42
+assertUndef(eval('42; switch (0) { case 0: 1; if (true) ; }')); // ES5: 1
+assertUndef(eval('42; switch (0) { case 0: 1; try { break } catch(e) { }; }')); // ES5: 1
+
+assertEquals(0, eval('42; switch (0) { case 0: 0; case 1: break; }'));
+assertEquals(0, eval('42; while (1) { 0; break; }'))
+assertEquals(0, eval('42; bla: while (1) { 0; break bla; }'))
+assertEquals(0, eval('42; while (1) { with ({}) { 0; break; } }'))
+assertEquals(0, eval('42; while (1) { try { 0; break } catch(e) {666} }'))
+assertEquals(0, eval(
+ '42; while (1) { try { 0; break } catch(e) {666} finally {666} }'))
+assertEquals(0, eval(
+ '42; while (1) { try { throw "" } catch(e) {666} finally {0; break} }'))
+assertEquals(0, eval(
+ '42; while (1) { try { throw "" } catch(e) {0; break} finally {666} }'))
+assertEquals(0, eval(
+ '42; while (1) { try { 666 } finally {0; break} }'));
+assertEquals(0, eval(
+ '42; while (1) { try { 666; break } finally {0; break} }'));
+assertEquals(0, eval(
+ '42; lab: try { 666; break lab } finally {0; break lab}'));
+assertEquals(undefined, eval(
+ 'var b = 1; ' +
+ 'outer: while (1) { while (1) { if (b--) 42; else break outer; }; 666 }'));
+
+// The following is not what ES6 says, but see ES bug 4540.
+assertUndef(eval('42; switch (0) { case 0: 1; if (true) break; }')); // ES5: 1
+
+
+
+////////////////////////////////////////////////////////////////////////////////
+//
+// The following are copied from webkit/eval-throw-return and adapted.
+
+function throwFunc() {
+ throw "";
+}
+
+function throwOnReturn(){
+ 1;
+ return throwFunc();
+}
+
+function twoFunc() {
+ 2;
+}
+
+assertEquals(1, eval("1;"));
+assertUndef(eval("1; try { foo = [2,3,throwFunc(), 4]; } catch (e){}"));
+assertUndef(eval("1; try { 2; throw ''; } catch (e){}"));
+assertUndef(eval("1; try { 2; throwFunc(); } catch (e){}"));
+assertEquals(3, eval("1; try { 2; throwFunc(); } catch (e){3;} finally {}"));
+assertEquals(3, eval("1; try { 2; throwFunc(); } catch (e){3;} finally {4;}"));
+assertUndef(eval("function blah() { 1; }; blah();"));
+assertUndef(eval("var x = 1;"));
+assertEquals(1, eval("if (true) { 1; } else { 2; }"));
+assertEquals(2, eval("if (false) { 1; } else { 2; }"));
+assertUndef(eval("try{1; if (true) { 2; throw ''; } else { 2; }} catch(e){}"));
+assertEquals(2, eval("1; var i = 0; do { ++i; 2; } while(i!=1);"));
+assertUndef(eval(
+ "try{1; var i = 0; do { ++i; 2; throw ''; } while (i!=1);} catch(e){}"));
+assertUndef(eval("1; try{2; throwOnReturn();} catch(e){}"));
+assertUndef(eval("1; twoFunc();"));
+assertEquals(2, eval("1; with ( { a: 0 } ) { 2; }"));
diff --git a/deps/v8/test/mjsunit/es6/generators-iteration.js b/deps/v8/test/mjsunit/es6/generators-iteration.js
index faeb68380f..ae4c682e7e 100644
--- a/deps/v8/test/mjsunit/es6/generators-iteration.js
+++ b/deps/v8/test/mjsunit/es6/generators-iteration.js
@@ -101,9 +101,9 @@ function TestGenerator(g, expected_values_for_next,
testThrow(function*() { return yield* g(); });
if (g instanceof GeneratorFunction) {
- testNext(function() { return new g(); });
- testSend(function() { return new g(); });
- testThrow(function() { return new g(); });
+ testNext(g);
+ testSend(g);
+ testThrow(g);
}
}
@@ -259,18 +259,6 @@ TestGenerator(
[1, 2, undefined]);
TestGenerator(
- function g18() {
- function* g() { yield this.x; yield this.y; }
- var iter = new g;
- iter.x = 1;
- iter.y = 2;
- return iter;
- },
- [1, 2, undefined],
- "foo",
- [1, 2, undefined]);
-
-TestGenerator(
function* g19() {
var x = 1;
yield x;
@@ -409,39 +397,17 @@ TestGenerator(
"foo",
[42, undefined]);
-// Test that yield* re-yields received results without re-boxing.
-function TestDelegatingYield() {
- function results(results) {
- var i = 0;
- function next() {
- return results[i++];
- }
- var iter = { next: next };
- var ret = {};
- ret[Symbol.iterator] = function() { return iter; };
- return ret;
- }
- function* yield_results(expected) {
- return yield* results(expected);
- }
- function collect_results(iterable) {
- var iter = iterable[Symbol.iterator]();
- var ret = [];
- var result;
- do {
- result = iter.next();
- ret.push(result);
- } while (!result.done);
- return ret;
- }
- // We have to put a full result for the end, because the return will re-box.
- var expected = [{value: 1}, 13, "foo", {value: 34, done: true}];
-
- // Sanity check.
- assertEquals(expected, collect_results(results(expected)));
- assertEquals(expected, collect_results(yield_results(expected)));
+// Test that yield* validates iterator results.
+function TestDelegatingYield(junk) {
+ var iterator = {next: () => junk};
+ var iterable = {[Symbol.iterator]: () => iterator};
+ function* g() { return yield* iterable };
+ assertThrows(() => g().next(), TypeError);
}
TestDelegatingYield();
+TestDelegatingYield(null);
+TestDelegatingYield(42);
+TestDelegatingYield(true);
function TestTryCatch(instantiate) {
function* g() { yield 1; try { yield 2; } catch (e) { yield e; } yield 3; }
@@ -693,3 +659,16 @@ function TestRecursion() {
assertThrows(TestThrowRecursion, Error);
}
TestRecursion();
+
+
+// Test yield* on non-iterable objects.
+function* g(junk) { return yield* junk }
+var non_iterables = [
+ 42,
+ {[Symbol.iterator]: 42},
+ {[Symbol.iterator]: () => 42},
+ {[Symbol.iterator]: () => ({next: 42})},
+];
+for (let junk of non_iterables) {
+ assertThrows(() => g(junk).next(), TypeError);
+}
diff --git a/deps/v8/test/mjsunit/es6/generators-objects.js b/deps/v8/test/mjsunit/es6/generators-objects.js
index 9390776761..f304738841 100644
--- a/deps/v8/test/mjsunit/es6/generators-objects.js
+++ b/deps/v8/test/mjsunit/es6/generators-objects.js
@@ -59,18 +59,12 @@ function TestGeneratorObject() {
assertEquals("[object Generator]", String(iter));
assertEquals([], Object.getOwnPropertyNames(iter));
assertTrue(iter !== g());
-
- // g() is the same as new g().
- iter = new g();
- assertSame(g.prototype, Object.getPrototypeOf(iter));
- assertTrue(iter instanceof g);
- assertEquals("Generator", %_ClassOf(iter));
- assertEquals("[object Generator]", String(iter));
assertEquals("[object Generator]", Object.prototype.toString.call(iter));
var gf = iter.__proto__.constructor;
assertEquals("[object GeneratorFunction]", Object.prototype.toString.call(gf));
- assertEquals([], Object.getOwnPropertyNames(iter));
- assertTrue(iter !== new g());
+
+ // generators are not constructable.
+ assertThrows(()=>new g());
}
TestGeneratorObject();
diff --git a/deps/v8/test/mjsunit/es6/generators-runtime.js b/deps/v8/test/mjsunit/es6/generators-runtime.js
index 98015b7f7c..5c426b21fd 100644
--- a/deps/v8/test/mjsunit/es6/generators-runtime.js
+++ b/deps/v8/test/mjsunit/es6/generators-runtime.js
@@ -99,7 +99,7 @@ function TestGeneratorObjectPrototype() {
assertSame(GeneratorObjectPrototype,
Object.getPrototypeOf((function*(){yield 1}).prototype));
- var expected_property_names = ["next", "throw", "constructor"];
+ var expected_property_names = ["next", "return", "throw", "constructor"];
var found_property_names =
Object.getOwnPropertyNames(GeneratorObjectPrototype);
diff --git a/deps/v8/test/mjsunit/es6/generators-states.js b/deps/v8/test/mjsunit/es6/generators-states.js
index 0a2173a919..4e8c58029a 100644
--- a/deps/v8/test/mjsunit/es6/generators-states.js
+++ b/deps/v8/test/mjsunit/es6/generators-states.js
@@ -25,6 +25,7 @@ function* throwGenerator() { yield iter.throw(new Bar); }
// Throw on a suspendedStart iterator.
iter = nextGenerator();
assertThrows(function() { iter.throw(new Foo) }, Foo)
+assertIteratorIsClosed(iter);
assertThrows(function() { iter.throw(new Foo) }, Foo)
assertIteratorIsClosed(iter);
@@ -65,3 +66,29 @@ iter = (function* () {
assertIteratorResult(3, false, iter.next());
assertIteratorResult(4, false, iter.next());
assertIteratorIsClosed(iter);
+
+
+// A return that doesn't close.
+{
+ let g = function*() { try {return 42} finally {yield 43} };
+
+ let x = g();
+ assertEquals({value: 43, done: false}, x.next());
+ assertEquals({value: 42, done: true}, x.next());
+}
+{
+ let x;
+ let g = function*() { try {return 42} finally {x.throw(666)} };
+
+ x = g();
+ assertThrows(() => x.next(), TypeError); // Still executing.
+}
+{
+ let x;
+ let g = function*() {
+ try {return 42} finally {try {x.throw(666)} catch(e) {}}
+ };
+
+ x = g();
+ assertEquals({value: 42, done: true}, x.next());
+}
diff --git a/deps/v8/test/mjsunit/es6/hasinstance-symbol.js b/deps/v8/test/mjsunit/es6/hasinstance-symbol.js
new file mode 100644
index 0000000000..6783d8deef
--- /dev/null
+++ b/deps/v8/test/mjsunit/es6/hasinstance-symbol.js
@@ -0,0 +1,12 @@
+// 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.
+
+// Verify that the hasInstance symbol is installed on function prototype.
+// Test262 makes deeper tests.
+
+(function TestHasInstance() {
+ var a = Array();
+ assertTrue(Array[Symbol.hasInstance](a));
+ assertFalse(Function.prototype[Symbol.hasInstance].call());
+})();
diff --git a/deps/v8/test/mjsunit/es6/no-unicode-regexp-flag.js b/deps/v8/test/mjsunit/es6/no-unicode-regexp-flag.js
index b56a4b56dd..035627c4d4 100644
--- a/deps/v8/test/mjsunit/es6/no-unicode-regexp-flag.js
+++ b/deps/v8/test/mjsunit/es6/no-unicode-regexp-flag.js
@@ -7,7 +7,7 @@
// mjsunit/es6/regexp-flags tests that the property is there when the
// flag is on.
-// Flags: --harmony-regexp
+// Flags: --harmony-regexps --no-harmony-unicode-regexps
'use strict';
diff --git a/deps/v8/test/mjsunit/es6/object-assign.js b/deps/v8/test/mjsunit/es6/object-assign.js
index d56cb0d1cf..1fec766dd1 100644
--- a/deps/v8/test/mjsunit/es6/object-assign.js
+++ b/deps/v8/test/mjsunit/es6/object-assign.js
@@ -138,3 +138,36 @@ assertSame(Object.assign(o, {}), o);
assertThrows(function() { return Object.assign(target, source); }, ErrorB);
assertEquals(log, "b");
})();
+
+(function add_to_source() {
+ var target = {set k1(v) { source.k3 = 100; }};
+ var source = {k1:10};
+ Object.defineProperty(source, "k2",
+ {value: 20, enumerable: false, configurable: true});
+ Object.assign(target, source);
+ assertEquals(undefined, target.k2);
+ assertEquals(undefined, target.k3);
+})();
+
+(function reconfigure_enumerable_source() {
+ var target = {set k1(v) {
+ Object.defineProperty(source, "k2", {value: 20, enumerable: true});
+ }};
+ var source = {k1:10};
+ Object.defineProperty(source, "k2",
+ {value: 20, enumerable: false, configurable: true});
+ Object.assign(target, source);
+ assertEquals(20, target.k2);
+})();
+
+(function propagate_assign_failure() {
+ var target = {set k1(v) { throw "fail" }};
+ var source = {k1:10};
+ assertThrows(()=>Object.assign(target, source));
+})();
+
+(function propagate_read_failure() {
+ var target = {};
+ var source = {get k1() { throw "fail" }};
+ assertThrows(()=>Object.assign(target, source));
+})();
diff --git a/deps/v8/test/mjsunit/es6/object-literals-method.js b/deps/v8/test/mjsunit/es6/object-literals-method.js
index e4527cb776..90bc51ec03 100644
--- a/deps/v8/test/mjsunit/es6/object-literals-method.js
+++ b/deps/v8/test/mjsunit/es6/object-literals-method.js
@@ -239,16 +239,14 @@ function assertIteratorResult(value, done, result) {
})();
-(function TestGeneratorConstructable() {
+(function TestGeneratorNotConstructable() {
var object = {
*method() {
yield 1;
}
};
- var g = new object.method();
- assertIteratorResult(1, false, g.next());
- assertIteratorResult(undefined, true, g.next());
+ assertThrows(()=>new object.method());
})();
diff --git a/deps/v8/test/mjsunit/es6/regexp-tolength.js b/deps/v8/test/mjsunit/es6/regexp-tolength.js
index d9e967ba27..f7cfe928af 100644
--- a/deps/v8/test/mjsunit/es6/regexp-tolength.js
+++ b/deps/v8/test/mjsunit/es6/regexp-tolength.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-tolength
-
'use strict';
let regexp = /x/g;
diff --git a/deps/v8/test/mjsunit/es6/regexp-tostring.js b/deps/v8/test/mjsunit/es6/regexp-tostring.js
new file mode 100644
index 0000000000..3deeeb7ed8
--- /dev/null
+++ b/deps/v8/test/mjsunit/es6/regexp-tostring.js
@@ -0,0 +1,46 @@
+// 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 log = [];
+
+var fake =
+ {
+ get source() {
+ log.push("p");
+ return {
+ toString: function() {
+ log.push("ps");
+ return "pattern";
+ }
+ };
+ },
+ get flags() {
+ log.push("f");
+ return {
+ toString: function() {
+ log.push("fs");
+ return "flags";
+ }
+ };
+ }
+ }
+
+function testThrows(x) {
+ try {
+ RegExp.prototype.toString.call(x);
+ } catch (e) {
+ assertTrue(/incompatible receiver/.test(e.message));
+ return;
+ }
+ assertUnreachable();
+}
+
+testThrows(1);
+testThrows(null);
+Number.prototype.source = "a";
+Number.prototype.flags = "b";
+testThrows(1);
+
+assertEquals("/pattern/flags", RegExp.prototype.toString.call(fake));
+assertEquals(["p", "ps", "f", "fs"], log);
diff --git a/deps/v8/test/mjsunit/es6/symbols.js b/deps/v8/test/mjsunit/es6/symbols.js
index d502a83681..38338575a0 100644
--- a/deps/v8/test/mjsunit/es6/symbols.js
+++ b/deps/v8/test/mjsunit/es6/symbols.js
@@ -441,8 +441,9 @@ TestGetOwnPropertySymbolsWithProto()
function TestWellKnown() {
var symbols = [
+ "hasInstance",
// TODO(rossberg): reactivate once implemented.
- // "hasInstance", "isConcatSpreadable", "isRegExp",
+ // "isConcatSpreadable", "isRegExp",
"iterator", /* "toStringTag", */ "unscopables"
]
diff --git a/deps/v8/test/mjsunit/es6/tail-call-megatest.js b/deps/v8/test/mjsunit/es6/tail-call-megatest.js
new file mode 100644
index 0000000000..005796195a
--- /dev/null
+++ b/deps/v8/test/mjsunit/es6/tail-call-megatest.js
@@ -0,0 +1,292 @@
+// 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 --harmony-tailcalls --no-turbo-inlining
+
+
+Error.prepareStackTrace = (error,stack) => {
+ error.strace = stack;
+ return error.message + "\n at " + stack.join("\n at ");
+}
+
+
+function CheckStackTrace(expected) {
+ var e = new Error();
+ e.stack; // prepare stack trace
+ var stack = e.strace;
+ assertEquals("CheckStackTrace", stack[0].getFunctionName());
+ for (var i = 0; i < expected.length; i++) {
+ assertEquals(expected[i].name, stack[i + 1].getFunctionName());
+ }
+}
+%NeverOptimizeFunction(CheckStackTrace);
+
+
+function CheckArguments(expected, args) {
+ args = Array.prototype.slice.call(args);
+ assertEquals(expected, args);
+}
+%NeverOptimizeFunction(CheckArguments);
+
+
+var CAN_INLINE_COMMENT = "// Let it be inlined.";
+var DONT_INLINE_COMMENT = (function() {
+ var line = "// Don't inline. Don't inline. Don't inline. Don't inline.";
+ for (var i = 0; i < 4; i++) {
+ line += "\n " + line;
+ }
+ return line;
+})();
+
+
+function ident_source(source, ident) {
+ ident = " ".repeat(ident);
+ return ident + source.replace(/\n/gi, "\n" + ident);
+}
+
+var global = Function('return this')();
+var the_receiver = {receiver: 1};
+
+function run_tests() {
+ function inlinable_comment(inlinable) {
+ return inlinable ? CAN_INLINE_COMMENT : DONT_INLINE_COMMENT;
+ }
+
+ var f_cfg_sloppy = {
+ func_name: 'f',
+ source_template: function(cfg) {
+ var receiver = cfg.f_receiver != undefined ? cfg.f_receiver
+ : "global";
+ var lines = [
+ `function f(a) {`,
+ ` ${inlinable_comment(cfg.f_inlinable)}`,
+ ` assertEquals(${receiver}, this);`,
+ ` CheckArguments([${cfg.f_args}], arguments);`,
+ ` CheckStackTrace([f, test]);`,
+ ` %DeoptimizeNow();`,
+ ` CheckArguments([${cfg.f_args}], arguments);`,
+ ` CheckStackTrace([f, test]);`,
+ ` return 42;`,
+ `}`,
+ ];
+ return lines.join("\n");
+ },
+ };
+
+ var f_cfg_strict = {
+ func_name: 'f',
+ source_template: function(cfg) {
+ var receiver = cfg.f_receiver != undefined ? cfg.f_receiver
+ : "undefined";
+ var lines = [
+ `function f(a) {`,
+ ` "use strict";`,
+ ` ${inlinable_comment(cfg.f_inlinable)}`,
+ ` assertEquals(${receiver}, this);`,
+ ` CheckArguments([${cfg.f_args}], arguments);`,
+ ` CheckStackTrace([f, test]);`,
+ ` %DeoptimizeNow();`,
+ ` CheckArguments([${cfg.f_args}], arguments);`,
+ ` CheckStackTrace([f, test]);`,
+ ` return 42;`,
+ `}`,
+ ];
+ return lines.join("\n");
+ },
+ };
+
+ var f_cfg_possibly_eval = {
+ func_name: 'eval',
+ source_template: function(cfg) {
+ var receiver = cfg.f_receiver != undefined ? cfg.f_receiver
+ : "global";
+ var lines = [
+ `function f(a) {`,
+ ` ${inlinable_comment(cfg.f_inlinable)}`,
+ ` assertEquals(${receiver}, this);`,
+ ` CheckArguments([${cfg.f_args}], arguments);`,
+ ` CheckStackTrace([f, test]);`,
+ ` %DeoptimizeNow();`,
+ ` CheckArguments([${cfg.f_args}], arguments);`,
+ ` CheckStackTrace([f, test]);`,
+ ` return 42;`,
+ `}`,
+ `var eval = f;`,
+ ];
+ return lines.join("\n");
+ },
+ };
+
+ var f_cfg_bound = {
+ func_name: 'bound',
+ source_template: function(cfg) {
+ var lines = [
+ `function f(a) {`,
+ ` "use strict";`,
+ ` ${inlinable_comment(cfg.f_inlinable)}`,
+ ` assertEquals(receiver, this);`,
+ ` CheckArguments([${cfg.f_args}], arguments);`,
+ ` CheckStackTrace([f, test]);`,
+ ` %DeoptimizeNow();`,
+ ` CheckArguments([${cfg.f_args}], arguments);`,
+ ` CheckStackTrace([f, test]);`,
+ ` return 42;`,
+ `}`,
+ `var receiver = {a: 153};`,
+ `var bound = f.bind(receiver);`,
+ ];
+ return lines.join("\n");
+ },
+ };
+
+ var f_cfg_proxy = {
+ func_name: 'p',
+ source_template: function(cfg) {
+ var receiver = cfg.f_receiver != undefined ? cfg.f_receiver
+ : "global";
+ var lines = [
+ `function f(a) {`,
+ ` ${inlinable_comment(cfg.f_inlinable)}`,
+ ` assertEquals(${receiver}, this);`,
+ ` CheckArguments([${cfg.f_args}], arguments);`,
+ ` CheckStackTrace([f, test]);`,
+ ` %DeoptimizeNow();`,
+ ` CheckArguments([${cfg.f_args}], arguments);`,
+ ` CheckStackTrace([f, test]);`,
+ ` return 42;`,
+ `}`,
+ `var p = new Proxy(f, {});`,
+ ];
+ return lines.join("\n");
+ },
+ };
+
+ var g_cfg_normal = {
+ receiver: undefined,
+ source_template: function(cfg) {
+ var lines = [
+ `function g(a) {`,
+ ` "use strict";`,
+ ` ${inlinable_comment(cfg.g_inlinable)}`,
+ ` CheckArguments([${cfg.g_args}], arguments);`,
+ ` return ${cfg.f_name}(${cfg.f_args});`,
+ `}`,
+ ];
+ return lines.join("\n");
+ },
+ };
+
+
+ var g_cfg_function_apply = {
+ receiver: "the_receiver",
+ source_template: function(cfg) {
+ var lines = [
+ `function g(a) {`,
+ ` "use strict";`,
+ ` ${inlinable_comment(cfg.g_inlinable)}`,
+ ` CheckArguments([${cfg.g_args}], arguments);`,
+ ` return ${cfg.f_name}.apply(the_receiver, [${cfg.f_args}]);`,
+ `}`,
+ ];
+ return lines.join("\n");
+ },
+ };
+
+
+ var g_cfg_function_call = {
+ receiver: "the_receiver",
+ source_template: function(cfg) {
+ var f_args = "the_receiver";
+ if (cfg.f_args !== "") f_args += ", ";
+ f_args += cfg.f_args;
+
+ var lines = [
+ `function g(a) {`,
+ ` "use strict";`,
+ ` ${inlinable_comment(cfg.g_inlinable)}`,
+ ` CheckArguments([${cfg.g_args}], arguments);`,
+ ` return ${cfg.f_name}.call(${f_args});`,
+ `}`,
+ ];
+ return lines.join("\n");
+ },
+ };
+
+
+ function test_template(cfg) {
+ var f_source = cfg.f_source_template(cfg);
+ var g_source = cfg.g_source_template(cfg);
+ f_source = ident_source(f_source, 2);
+ g_source = ident_source(g_source, 2);
+
+ var lines = [
+ `(function() {`,
+ f_source,
+ g_source,
+ ` function test() {`,
+ ` "use strict";`,
+ ` assertEquals(42, g(${cfg.g_args}));`,
+ ` }`,
+ ` ${cfg.f_inlinable ? "%SetForceInlineFlag(f)" : ""};`,
+ ` ${cfg.g_inlinable ? "%SetForceInlineFlag(g)" : ""};`,
+ ``,
+ ` test();`,
+ ` %OptimizeFunctionOnNextCall(test);`,
+ ` %OptimizeFunctionOnNextCall(f);`,
+ ` %OptimizeFunctionOnNextCall(g);`,
+ ` test();`,
+ `})();`,
+ ``,
+ ];
+ var source = lines.join("\n");
+ return source;
+ }
+
+ // TODO(v8:4698), TODO(ishell): support all commented cases.
+ 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];
+ var f_variants = [
+ f_cfg_sloppy,
+ f_cfg_strict,
+ f_cfg_bound,
+ f_cfg_proxy,
+ f_cfg_possibly_eval,
+ ];
+ var g_variants = [
+ g_cfg_normal,
+ g_cfg_function_call,
+ g_cfg_function_apply,
+ ];
+
+ f_variants.forEach((f_cfg) => {
+ g_variants.forEach((g_cfg) => {
+ f_args_variants.forEach((f_args) => {
+ g_args_variants.forEach((g_args) => {
+ f_inlinable_variants.forEach((f_inlinable) => {
+ g_inlinable_variants.forEach((g_inlinable) => {
+ var cfg = {
+ f_source_template: f_cfg.source_template,
+ f_inlinable,
+ f_args,
+ f_name: f_cfg.func_name,
+ f_receiver: g_cfg.receiver,
+ g_source_template: g_cfg.source_template,
+ g_inlinable,
+ g_args,
+ };
+ var source = test_template(cfg);
+ print("====================");
+ print(source);
+ eval(source);
+ });
+ });
+ });
+ });
+ });
+ });
+}
+
+run_tests();
diff --git a/deps/v8/test/mjsunit/es6/tail-call-proxies.js b/deps/v8/test/mjsunit/es6/tail-call-proxies.js
new file mode 100644
index 0000000000..25f9fcfbe7
--- /dev/null
+++ b/deps/v8/test/mjsunit/es6/tail-call-proxies.js
@@ -0,0 +1,97 @@
+// 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 --harmony-tailcalls --harmony-proxies
+"use strict";
+
+Error.prepareStackTrace = (e,s) => s;
+
+function CheckStackTrace(expected) {
+ var stack = (new Error()).stack;
+ assertEquals("CheckStackTrace", stack[0].getFunctionName());
+ for (var i = 0; i < expected.length; i++) {
+ assertEquals(expected[i].name, stack[i + 1].getFunctionName());
+ }
+}
+
+
+// Tail call proxy function when caller does not have an arguments
+// adaptor frame.
+(function test() {
+ // Caller and callee have same number of arguments.
+ function f1(a) {
+ CheckStackTrace([f1, test]);
+ return 10 + a;
+ }
+ var p1 = new Proxy(f1, {});
+ function g1(a) { return p1(2); }
+ assertEquals(12, g1(1));
+
+ // Caller has more arguments than callee.
+ function f2(a) {
+ CheckStackTrace([f2, test]);
+ return 10 + a;
+ }
+ var p2 = new Proxy(f2, {});
+ function g2(a, b, c) { return p2(2); }
+ assertEquals(12, g2(1, 2, 3));
+
+ // Caller has less arguments than callee.
+ function f3(a, b, c) {
+ CheckStackTrace([f3, test]);
+ return 10 + a + b + c;
+ }
+ var p3 = new Proxy(f3, {});
+ function g3(a) { return p3(2, 3, 4); }
+ assertEquals(19, g3(1));
+
+ // Callee has arguments adaptor frame.
+ function f4(a, b, c) {
+ CheckStackTrace([f4, test]);
+ return 10 + a;
+ }
+ var p4 = new Proxy(f4, {});
+ function g4(a) { return p4(2); }
+ assertEquals(12, g4(1));
+})();
+
+
+// Tail call proxy function when caller has an arguments adaptor frame.
+(function test() {
+ // Caller and callee have same number of arguments.
+ function f1(a) {
+ CheckStackTrace([f1, test]);
+ return 10 + a;
+ }
+ var p1 = new Proxy(f1, {});
+ function g1(a) { return p1(2); }
+ assertEquals(12, g1());
+
+ // Caller has more arguments than callee.
+ function f2(a) {
+ CheckStackTrace([f2, test]);
+ return 10 + a;
+ }
+ var p2 = new Proxy(f2, {});
+ function g2(a, b, c) { return p2(2); }
+ assertEquals(12, g2());
+
+ // Caller has less arguments than callee.
+ function f3(a, b, c) {
+ CheckStackTrace([f3, test]);
+ return 10 + a + b + c;
+ }
+ var p3 = new Proxy(f3, {});
+ function g3(a) { return p3(2, 3, 4); }
+ assertEquals(19, g3());
+
+ // Callee has arguments adaptor frame.
+ function f4(a, b, c) {
+ CheckStackTrace([f4, test]);
+ return 10 + a;
+ }
+ var p4 = new Proxy(f4, {});
+ function g4(a) { return p4(2); }
+ assertEquals(12, g4());
+})();
diff --git a/deps/v8/test/mjsunit/es6/tail-call-simple.js b/deps/v8/test/mjsunit/es6/tail-call-simple.js
new file mode 100644
index 0000000000..d2890b0212
--- /dev/null
+++ b/deps/v8/test/mjsunit/es6/tail-call-simple.js
@@ -0,0 +1,107 @@
+// 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 --harmony-tailcalls --stack-size=100
+
+//
+// Tail calls work only in strict mode.
+//
+(function() {
+ function f(n) {
+ if (n <= 0) {
+ return "foo";
+ }
+ return f(n - 1);
+ }
+ assertThrows(()=>{ f(1e5) });
+ %OptimizeFunctionOnNextCall(f);
+ assertThrows(()=>{ f(1e5) });
+})();
+
+
+//
+// Tail call normal functions.
+//
+(function() {
+ "use strict";
+ function f(n) {
+ if (n <= 0) {
+ return "foo";
+ }
+ return f(n - 1);
+ }
+ assertEquals("foo", f(1e5));
+ %OptimizeFunctionOnNextCall(f);
+ assertEquals("foo", f(1e5));
+})();
+
+
+(function() {
+ "use strict";
+ function f(n){
+ if (n <= 0) {
+ return "foo";
+ }
+ return g(n - 1);
+ }
+ function g(n){
+ if (n <= 0) {
+ return "bar";
+ }
+ return f(n - 1);
+ }
+ assertEquals("foo", f(1e5));
+ assertEquals("bar", f(1e5 + 1));
+ %OptimizeFunctionOnNextCall(f);
+ assertEquals("foo", f(1e5));
+ assertEquals("bar", f(1e5 + 1));
+})();
+
+
+//
+// Tail call bound functions.
+//
+(function() {
+ "use strict";
+ function f0(n) {
+ if (n <= 0) {
+ return "foo";
+ }
+ return f_bound(n - 1);
+ }
+ var f_bound = f0.bind({});
+ function f(n) {
+ return f_bound(n);
+ }
+ assertEquals("foo", f(1e5));
+ %OptimizeFunctionOnNextCall(f);
+ assertEquals("foo", f(1e5));
+})();
+
+
+(function() {
+ "use strict";
+ function f0(n){
+ if (n <= 0) {
+ return "foo";
+ }
+ return g_bound(n - 1);
+ }
+ function g0(n){
+ if (n <= 0) {
+ return "bar";
+ }
+ return f_bound(n - 1);
+ }
+ var f_bound = f0.bind({});
+ var g_bound = g0.bind({});
+ function f(n) {
+ return f_bound(n);
+ }
+ assertEquals("foo", f(1e5));
+ assertEquals("bar", f(1e5 + 1));
+ %OptimizeFunctionOnNextCall(f);
+ assertEquals("foo", f(1e5));
+ assertEquals("bar", f(1e5 + 1));
+})();
diff --git a/deps/v8/test/mjsunit/es6/tail-call.js b/deps/v8/test/mjsunit/es6/tail-call.js
new file mode 100644
index 0000000000..e9539c37ba
--- /dev/null
+++ b/deps/v8/test/mjsunit/es6/tail-call.js
@@ -0,0 +1,386 @@
+// 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 --harmony-tailcalls
+"use strict";
+
+Error.prepareStackTrace = (error,stack) => {
+ error.strace = stack;
+ return error.message + "\n at " + stack.join("\n at ");
+}
+
+
+function CheckStackTrace(expected) {
+ var e = new Error();
+ e.stack; // prepare stack trace
+ var stack = e.strace;
+ assertEquals("CheckStackTrace", stack[0].getFunctionName());
+ for (var i = 0; i < expected.length; i++) {
+ assertEquals(expected[i].name, stack[i + 1].getFunctionName());
+ }
+}
+
+function f(expected_call_stack, a, b) {
+ CheckStackTrace(expected_call_stack);
+ return a;
+}
+
+function f_153(expected_call_stack, a) {
+ CheckStackTrace(expected_call_stack);
+ return 153;
+}
+
+
+// Tail call when caller does not have an arguments adaptor frame.
+(function() {
+ // Caller and callee have same number of arguments.
+ function f1(a) {
+ CheckStackTrace([f1, test]);
+ return 10 + a;
+ }
+ function g1(a) { return f1(2); }
+
+ // Caller has more arguments than callee.
+ function f2(a) {
+ CheckStackTrace([f2, test]);
+ return 10 + a;
+ }
+ function g2(a, b, c) { return f2(2); }
+
+ // Caller has less arguments than callee.
+ function f3(a, b, c) {
+ CheckStackTrace([f3, test]);
+ return 10 + a + b + c;
+ }
+ function g3(a) { return f3(2, 3, 4); }
+
+ // Callee has arguments adaptor frame.
+ function f4(a, b, c) {
+ CheckStackTrace([f4, test]);
+ return 10 + a;
+ }
+ function g4(a) { return f4(2); }
+
+ function test() {
+ assertEquals(12, g1(1));
+ assertEquals(12, g2(1, 2, 3));
+ assertEquals(19, g3(1));
+ assertEquals(12, g4(1));
+ }
+ test();
+ %OptimizeFunctionOnNextCall(test);
+ test();
+})();
+
+
+// Tail call when caller has an arguments adaptor frame.
+(function() {
+ // Caller and callee have same number of arguments.
+ function f1(a) {
+ CheckStackTrace([f1, test]);
+ return 10 + a;
+ }
+ function g1(a) { return f1(2); }
+
+ // Caller has more arguments than callee.
+ function f2(a) {
+ CheckStackTrace([f2, test]);
+ return 10 + a;
+ }
+ function g2(a, b, c) { return f2(2); }
+
+ // Caller has less arguments than callee.
+ function f3(a, b, c) {
+ CheckStackTrace([f3, test]);
+ return 10 + a + b + c;
+ }
+ function g3(a) { return f3(2, 3, 4); }
+
+ // Callee has arguments adaptor frame.
+ function f4(a, b, c) {
+ CheckStackTrace([f4, test]);
+ return 10 + a;
+ }
+ function g4(a) { return f4(2); }
+
+ function test() {
+ assertEquals(12, g1());
+ assertEquals(12, g2());
+ assertEquals(19, g3());
+ assertEquals(12, g4());
+ }
+ test();
+ %OptimizeFunctionOnNextCall(test);
+ test();
+})();
+
+
+// Tail call bound function when caller does not have an arguments
+// adaptor frame.
+(function() {
+ // Caller and callee have same number of arguments.
+ function f1(a) {
+ assertEquals(153, this.a);
+ CheckStackTrace([f1, test]);
+ return 10 + a;
+ }
+ var b1 = f1.bind({a: 153});
+ function g1(a) { return b1(2); }
+
+ // Caller has more arguments than callee.
+ function f2(a) {
+ assertEquals(153, this.a);
+ CheckStackTrace([f2, test]);
+ return 10 + a;
+ }
+ var b2 = f2.bind({a: 153});
+ function g2(a, b, c) { return b2(2); }
+
+ // Caller has less arguments than callee.
+ function f3(a, b, c) {
+ assertEquals(153, this.a);
+ CheckStackTrace([f3, test]);
+ return 10 + a + b + c;
+ }
+ var b3 = f3.bind({a: 153});
+ function g3(a) { return b3(2, 3, 4); }
+
+ // Callee has arguments adaptor frame.
+ function f4(a, b, c) {
+ assertEquals(153, this.a);
+ CheckStackTrace([f4, test]);
+ return 10 + a;
+ }
+ var b4 = f4.bind({a: 153});
+ function g4(a) { return b4(2); }
+
+ function test() {
+ assertEquals(12, g1(1));
+ assertEquals(12, g2(1, 2, 3));
+ assertEquals(19, g3(1));
+ assertEquals(12, g4(1));
+ }
+ test();
+ %OptimizeFunctionOnNextCall(test);
+ test();
+})();
+
+
+// Tail call bound function when caller has an arguments adaptor frame.
+(function() {
+ // Caller and callee have same number of arguments.
+ function f1(a) {
+ assertEquals(153, this.a);
+ CheckStackTrace([f1, test]);
+ return 10 + a;
+ }
+ var b1 = f1.bind({a: 153});
+ function g1(a) { return b1(2); }
+
+ // Caller has more arguments than callee.
+ function f2(a) {
+ assertEquals(153, this.a);
+ CheckStackTrace([f2, test]);
+ return 10 + a;
+ }
+ var b2 = f2.bind({a: 153});
+ function g2(a, b, c) { return b2(2); }
+
+ // Caller has less arguments than callee.
+ function f3(a, b, c) {
+ assertEquals(153, this.a);
+ CheckStackTrace([f3, test]);
+ return 10 + a + b + c;
+ }
+ var b3 = f3.bind({a: 153});
+ function g3(a) { return b3(2, 3, 4); }
+
+ // Callee has arguments adaptor frame.
+ function f4(a, b, c) {
+ assertEquals(153, this.a);
+ CheckStackTrace([f4, test]);
+ return 10 + a;
+ }
+ var b4 = f4.bind({a: 153});
+ function g4(a) { return b4(2); }
+
+ function test() {
+ assertEquals(12, g1());
+ assertEquals(12, g2());
+ assertEquals(19, g3());
+ assertEquals(12, g4());
+ }
+ test();
+ %OptimizeFunctionOnNextCall(test);
+ test();
+})();
+
+
+// Tail calling via various expressions.
+(function() {
+ function g1(a) {
+ return f([f, g1, test], false) || f([f, test], true);
+ }
+
+ function g2(a) {
+ return f([f, g2, test], true) && f([f, test], true);
+ }
+
+ function g3(a) {
+ return f([f, g3, test], 13), f([f, test], 153);
+ }
+
+ function test() {
+ assertEquals(true, g1());
+ assertEquals(true, g2());
+ assertEquals(153, g3());
+ }
+ test();
+ %OptimizeFunctionOnNextCall(test);
+ test();
+})();
+
+
+// Test tail calls from try-catch constructs.
+(function() {
+ function tc1(a) {
+ try {
+ f_153([f_153, tc1, test]);
+ return f_153([f_153, tc1, test]);
+ } catch(e) {
+ f_153([f_153, tc1, test]);
+ }
+ }
+
+ function tc2(a) {
+ try {
+ f_153([f_153, tc2, test]);
+ throw new Error("boom");
+ } catch(e) {
+ f_153([f_153, tc2, test]);
+ return f_153([f_153, test]);
+ }
+ }
+
+ function tc3(a) {
+ try {
+ f_153([f_153, tc3, test]);
+ throw new Error("boom");
+ } catch(e) {
+ f_153([f_153, tc3, test]);
+ }
+ f_153([f_153, tc3, test]);
+ return f_153([f_153, test]);
+ }
+
+ function test() {
+ assertEquals(153, tc1());
+ assertEquals(153, tc2());
+ assertEquals(153, tc3());
+ }
+ test();
+ %OptimizeFunctionOnNextCall(test);
+ test();
+})();
+
+
+// Test tail calls from try-finally constructs.
+(function() {
+ function tf1(a) {
+ try {
+ f_153([f_153, tf1, test]);
+ return f_153([f_153, tf1, test]);
+ } finally {
+ f_153([f_153, tf1, test]);
+ }
+ }
+
+ function tf2(a) {
+ try {
+ f_153([f_153, tf2, test]);
+ throw new Error("boom");
+ } finally {
+ f_153([f_153, tf2, test]);
+ return f_153([f_153, test]);
+ }
+ }
+
+ function tf3(a) {
+ try {
+ f_153([f_153, tf3, test]);
+ } finally {
+ f_153([f_153, tf3, test]);
+ }
+ return f_153([f_153, test]);
+ }
+
+ function test() {
+ assertEquals(153, tf1());
+ assertEquals(153, tf2());
+ assertEquals(153, tf3());
+ }
+ test();
+ %OptimizeFunctionOnNextCall(test);
+ test();
+})();
+
+
+// Test tail calls from try-catch-finally constructs.
+(function() {
+ function tcf1(a) {
+ try {
+ f_153([f_153, tcf1, test]);
+ return f_153([f_153, tcf1, test]);
+ } catch(e) {
+ } finally {
+ f_153([f_153, tcf1, test]);
+ }
+ }
+
+ function tcf2(a) {
+ try {
+ f_153([f_153, tcf2, test]);
+ throw new Error("boom");
+ } catch(e) {
+ f_153([f_153, tcf2, test]);
+ return f_153([f_153, tcf2, test]);
+ } finally {
+ f_153([f_153, tcf2, test]);
+ }
+ }
+
+ function tcf3(a) {
+ try {
+ f_153([f_153, tcf3, test]);
+ throw new Error("boom");
+ } catch(e) {
+ f_153([f_153, tcf3, test]);
+ } finally {
+ f_153([f_153, tcf3, test]);
+ return f_153([f_153, test]);
+ }
+ }
+
+ function tcf4(a) {
+ try {
+ f_153([f_153, tcf4, test]);
+ throw new Error("boom");
+ } catch(e) {
+ f_153([f_153, tcf4, test]);
+ } finally {
+ f_153([f_153, tcf4, test]);
+ }
+ return f_153([f_153, test]);
+ }
+
+ function test() {
+ assertEquals(153, tcf1());
+ assertEquals(153, tcf2());
+ assertEquals(153, tcf3());
+ assertEquals(153, tcf4());
+ }
+ test();
+ %OptimizeFunctionOnNextCall(test);
+ test();
+})();
diff --git a/deps/v8/test/mjsunit/es6/typedarray.js b/deps/v8/test/mjsunit/es6/typedarray.js
index c43ba1c4bf..e6a949ca59 100644
--- a/deps/v8/test/mjsunit/es6/typedarray.js
+++ b/deps/v8/test/mjsunit/es6/typedarray.js
@@ -529,6 +529,8 @@ function TestTypedArraySet() {
assertThrows(function() { a.set(0); }, TypeError);
assertThrows(function() { a.set(0, 1); }, TypeError);
+
+ assertEquals(1, a.set.length);
}
TestTypedArraySet();
@@ -672,7 +674,6 @@ function TestDataViewConstructor() {
// error cases
assertThrows(function() { new DataView(ab, -1); }, RangeError);
- assertThrows(function() { new DataView(ab, 1, -1); }, RangeError);
assertThrows(function() { new DataView(); }, TypeError);
assertThrows(function() { new DataView([]); }, TypeError);
assertThrows(function() { new DataView(ab, 257); }, RangeError);
@@ -693,6 +694,19 @@ function TestDataViewPropertyTypeChecks() {
CheckProperty("buffer");
CheckProperty("byteOffset");
CheckProperty("byteLength");
+
+ function CheckGetSetLength(name) {
+ assertEquals(1, DataView.prototype["get" + name].length);
+ assertEquals(2, DataView.prototype["set" + name].length);
+ }
+ CheckGetSetLength("Int8");
+ CheckGetSetLength("Uint8");
+ CheckGetSetLength("Int16");
+ CheckGetSetLength("Uint16");
+ CheckGetSetLength("Int32");
+ CheckGetSetLength("Uint32");
+ CheckGetSetLength("Float32");
+ CheckGetSetLength("Float64");
}