diff options
Diffstat (limited to 'deps/v8/test/mjsunit/es6')
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"); } |