Created
July 23, 2020 20:04
-
-
Save ridiculousfish/f1510a2e1a18c1286a01f4538f5d9c87 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| /** | |
| * Copyright (c) Facebook, Inc. and its affiliates. | |
| * | |
| * This source code is licensed under the MIT license found in the | |
| * LICENSE file in the root directory of this source tree. | |
| */ | |
| // RUN: %hermes -target=HBC -O %s | %FileCheck --match-full-lines %s | |
| // RUN: %hermes -target=HBC -O -emit-binary -out %t.hbc %s && %hermes %t.hbc | %FileCheck --match-full-lines %s | |
| "use strict"; | |
| // Performs a nested array comparison between the two arrays. | |
| function arrayEquals(a, b) { | |
| if (a.length !== b.length) { | |
| return false; | |
| } | |
| for (var i = 0; i < a.length; ++i) { | |
| if (Array.isArray(a[i]) && Array.isArray(b[i])) { | |
| if (!arrayEquals(a[i], b[i])) { | |
| return false; | |
| } | |
| } else { | |
| if (a[i] !== b[i]) { | |
| return false; | |
| } | |
| } | |
| } | |
| return true; | |
| } | |
| print('toString'); | |
| // CHECK-LABEL: toString | |
| print(Array(1,2,3).toString()); | |
| // CHECK-NEXT: 1,2,3 | |
| print('empty', Array().toString()); | |
| // CHECK-NEXT: empty | |
| // Overwrite join and make sure it fails over to Object.prototype.toString(). | |
| var a = Array(1,2,3); | |
| a.join = null; | |
| print(a.toString()); | |
| // CHECK-NEXT: [object Array] | |
| var ots = Object.prototype.toString; | |
| Object.prototype.toString = null; | |
| print(a.toString()); | |
| // CHECK-NEXT: [object Array] | |
| Object.prototype.toString = ots; | |
| var a = [1,2]; | |
| a.push(a); | |
| print(a.toString()); | |
| // CHECK-NEXT: 1,2, | |
| var a = [1,2]; | |
| var b = [3,4,a]; | |
| a.push(b); | |
| print(a.toString()); | |
| // CHECK-NEXT: 1,2,3,4, | |
| var a = [1,2]; | |
| var b = [3,4]; | |
| var c = [5,6,b]; | |
| b.push(c); | |
| a.push(b); | |
| print(a.toString()); | |
| // CHECK-NEXT: 1,2,3,4,5,6, | |
| print('of'); | |
| // CHECK-LABEL: of | |
| print(Array.of(1,2,3)); | |
| // CHECK-NEXT: 1,2,3 | |
| print(Array.of('asdf', {})); | |
| // CHECK-NEXT: asdf,[object Object] | |
| print(Array.of.call(Math.sin, 1, 2, 3)); | |
| // CHECK-NEXT: 1,2,3 | |
| print(Array.of.call(Math.sin.bind(), 1, 2, 3)); | |
| // CHECK-NEXT: 1,2,3 | |
| print(Array.of.call(Math.sin.bind().bind(), 1, 2, 3)); | |
| // CHECK-NEXT: 1,2,3 | |
| print(Array.of(), "EMPTY"); | |
| // CHECK-NEXT: EMPTY | |
| var res = Array.of.call(Object, 1, 2, 3); | |
| print(Array.isArray(res), res[0], res[1], res[2]); | |
| // CHECK-NEXT: false 1 2 3 | |
| var f = function() {} | |
| var res = Array.of.call(f, 1, 2, 3); | |
| print(res instanceof f, res[0], res[1], res[2]); | |
| // CHECK-NEXT: true 1 2 3 | |
| var res = Array.of.call(f.bind(), 1, 2, 3); | |
| print(res instanceof f, res[0], res[1], res[2]); | |
| // CHECK-NEXT: true 1 2 3 | |
| print('from'); | |
| // CHECK-LABEL: from | |
| var emptyRes = Array.from([]); | |
| print(emptyRes.length); | |
| // CHECK-NEXT: 0 | |
| emptyRes = Array.from(""); | |
| print(emptyRes.length); | |
| // CHECK-NEXT: 0 | |
| emptyRes = Array.from({}); | |
| print(emptyRes.length); | |
| // CHECK-NEXT: 0 | |
| var fromRes = Array.from('foo'); | |
| print(fromRes); | |
| // CHECK-NEXT: f,o,o | |
| print(fromRes.length); | |
| // CHECK-NEXT: 3 | |
| print(Array.from(new Set(['foo', 1]))); | |
| // CHECK-NEXT: foo,1 | |
| print(Array.from([1, 2, 3], function(x) { return x + 1; })); | |
| // CHECK-NEXT: 2,3,4 | |
| print(Array.from({length: 5}, function(v, i) { return i; })); | |
| // CHECK-NEXT: 0,1,2,3,4 | |
| var thisObj = {a : "hello"}; | |
| Array.from([0, 1], function() { print(this.a); return 0;}, thisObj); | |
| // CHECK-NEXT: hello | |
| // CHECK-NEXT: hello | |
| // user-defined iterator | |
| var iterable = {}; | |
| iterable[Symbol.iterator] = function () { | |
| var step = 0; | |
| var iterator = { | |
| next: function() { | |
| if (step == 5) { | |
| return {value: undefined, done: true}; | |
| } else { | |
| return {value: step++, done: false}; | |
| } | |
| } | |
| }; | |
| return iterator; | |
| } | |
| var iterableArr = Array.from(iterable); | |
| print(iterableArr); | |
| // CHECK-NEXT: 0,1,2,3,4 | |
| print(iterableArr.length); | |
| // CHECK-NEXT: 5 | |
| iterableArr = Array.from(iterable, function(x, i) { return x + i; }); | |
| print(iterableArr); | |
| // CHECK-NEXT: 0,2,4,6,8 | |
| print(iterableArr.length); | |
| // CHECK-NEXT: 5 | |
| Array.from(iterable, function() { print(this.a); return 0;}, thisObj); | |
| // CHECK-NEXT: hello | |
| // CHECK-NEXT: hello | |
| // CHECK-NEXT: hello | |
| // CHECK-NEXT: hello | |
| // CHECK-NEXT: hello | |
| function testThisAsConstructor(items) { | |
| var ctor = function() {return {hello : "hello"};}; | |
| var res = Array.from.call(ctor, items); | |
| print(res.length); | |
| print(res.hello); | |
| } | |
| testThisAsConstructor([1, 2]); | |
| // CHECK-NEXT: 2 | |
| // CHECK-NEXT: hello | |
| testThisAsConstructor({1: 1, 2: 2, length: 2}); | |
| // CHECK-NEXT: 2 | |
| // CHECK-NEXT: hello | |
| testThisAsConstructor(iterable); | |
| // CHECK-NEXT: 5 | |
| // CHECK-NEXT: hello | |
| print('toLocaleString'); | |
| // CHECK-LABEL: toLocaleString | |
| print([1,2,3].toLocaleString()); | |
| // CHECK-NEXT: 1,2,3 | |
| var n = 0; | |
| var obj = {toLocaleString: function() {++n; return 1337;}}; | |
| print([1,2,obj,3,obj].toLocaleString()); | |
| print(n); | |
| // CHECK-NEXT: 1,2,1337,3,1337 | |
| // CHECK-NEXT: 2 | |
| var a = [1,2]; | |
| a.push(a); | |
| print(a.toLocaleString()); | |
| // CHECK-NEXT: 1,2, | |
| var a = [1,2]; | |
| var b = [3,4,a]; | |
| a.push(b); | |
| print(a.toLocaleString()); | |
| // CHECK-NEXT: 1,2,3,4, | |
| var a = [1,2]; | |
| var b = [3,4]; | |
| var c = [5,6,b]; | |
| b.push(c); | |
| a.push(b); | |
| print(a.toLocaleString()); | |
| // CHECK-NEXT: 1,2,3,4,5,6, | |
| try {[{toLocaleString:1}].toLocaleString()} | |
| catch(e) {print('caught', e.name, e.message);} | |
| // CHECK-NEXT: caught TypeError {{.*}} | |
| print('concat'); | |
| // CHECK-LABEL: concat | |
| print([1,2].concat([3,4])); | |
| // CHECK-NEXT: 1,2,3,4 | |
| print([].concat([3,4])); | |
| // CHECK-NEXT: 3,4 | |
| print([1,2].concat([])); | |
| // CHECK-NEXT: 1,2 | |
| print('empty', [].concat([])); | |
| // CHECK-NEXT: empty | |
| print(['a','b'].concat(['c','d'], 'efg', 123, {})); | |
| // CHECK-NEXT: a,b,c,d,efg,123,[object Object] | |
| var a = [1,2].concat([[3,4],[5,6]]); | |
| print(a[0], a[1], a[2][0], a[2][1], a[3][0], a[3][1]); | |
| // CHECK-NEXT: 1 2 3 4 5 6 | |
| print([1,2].concat(3, {0: 4, 1: 5, length: 2})); | |
| // CHECK-NEXT: 1,2,3,[object Object] | |
| var a = [1,,]; | |
| a.__proto__[1] = 2; | |
| print(a.concat(3)); | |
| // CHECK-NEXT: 1,2,3 | |
| delete a.__proto__[1]; | |
| var a = [1,2,3] | |
| a = []; | |
| print(typeof a.concat(100)[0]); | |
| // CHECK-NEXT: number | |
| Array.prototype[1] = 1; | |
| var x = []; | |
| x.length = 2; | |
| var a = x.concat(); | |
| print(a.hasOwnProperty('1')); | |
| // CHECK-NEXT: true | |
| delete Array.prototype[1]; | |
| var args = []; | |
| for (var i = 0; i < 1000; ++i) args.push([]); | |
| Array.prototype.concat.apply([], args); | |
| print('copyWithin'); | |
| // CHECK-LABEL: copyWithin | |
| print([1,2,3,4,5].copyWithin(0,3,4)); | |
| // CHECK-NEXT: 4,2,3,4,5 | |
| print([4,2,3,4,5].copyWithin(1,3)); | |
| // CHECK-NEXT: 4,4,5,4,5 | |
| print([1,2,3,4,5].copyWithin(-2)); | |
| // CHECK-NEXT: 1,2,3,1,2 | |
| print([1,2,3,4,5].copyWithin(1)); | |
| // CHECK-NEXT: 1,1,2,3,4 | |
| print([1,2,3,4,5].copyWithin(1)); | |
| // CHECK-NEXT: 1,1,2,3,4 | |
| print([1,2,,,5].copyWithin(0,2,4)); | |
| // CHECK-NEXT: ,,,,5 | |
| print([1,2,3,4,5].copyWithin(-2, -3, -1)); | |
| // CHECK-NEXT: 1,2,3,3,4 | |
| print([1,2,3,4,5].copyWithin(-100, -1, -3)); | |
| // CHECK-NEXT: 1,2,3,4,5 | |
| print([1,2,3,4,5].copyWithin(100, -1, -3)); | |
| // CHECK-NEXT: 1,2,3,4,5 | |
| print([1,2,3,4,5].copyWithin(-2, -1, -3)); | |
| // CHECK-NEXT: 1,2,3,4,5 | |
| print([].copyWithin(-2, -1, -3), "EMPTY"); | |
| // CHECK-NEXT: EMPTY | |
| var res = [].copyWithin.call({length: 5, 3: 1}, 0, 3); | |
| print(res[0], res[1], res[2], res[3], res[4], res.length); | |
| // CHECK-NEXT: 1 undefined undefined 1 undefined 5 | |
| print('join'); | |
| // CHECK-LABEL: join | |
| print(Array(1,2,3).join()); | |
| // CHECK-NEXT: 1,2,3 | |
| print(Array(1,2,3).join(',')); | |
| // CHECK-NEXT: 1,2,3 | |
| print(Array(1,2,3).join(':')); | |
| // CHECK-NEXT: 1:2:3 | |
| print(Array(1,2,Array(3,4),5).join(':')); | |
| // CHECK-NEXT: 1:2:3,4:5 | |
| print(Array(1,2,3).join(' SEPARATOR ')); | |
| // CHECK-NEXT: 1 SEPARATOR 2 SEPARATOR 3 | |
| print('empty', Array().join()); | |
| // CHECK-NEXT: empty | |
| print('empty', Array().join('::::')); | |
| // CHECK-NEXT: empty | |
| print(Array(null,2,undefined,3,null).join('-')); | |
| // CHECK-NEXT: -2--3- | |
| print('pop'); | |
| // CHECK-LABEL: pop | |
| var a = Array(1,2,3); | |
| print(a.pop(), a.length, a[0], a[1], a[2]); | |
| // CHECK-NEXT: 3 2 1 2 undefined | |
| print(a.pop(), a.length, a[0], a[1], a[2]); | |
| // CHECK-NEXT: 2 1 1 undefined undefined | |
| print(a.pop(), a.length, a[0], a[1], a[2]); | |
| // CHECK-NEXT: 1 0 undefined undefined undefined | |
| print(a.pop(), a.length, a[0], a[1], a[2]); | |
| // CHECK-NEXT: undefined 0 undefined undefined undefined | |
| print(a.pop(), a.length, a[0], a[1], a[2]); | |
| // CHECK-NEXT: undefined 0 undefined undefined undefined | |
| // Test recursion of pop re-entering itself. | |
| var a = []; | |
| Object.defineProperty(a, 9, { | |
| get: Array.prototype.pop, | |
| }); | |
| try { | |
| print(a.pop()); | |
| } catch (e) { | |
| // Infinite recursion, should throw call stack exceeded. | |
| print(e.name); | |
| } | |
| // CHECK-NEXT: RangeError | |
| print('push'); | |
| // CHECK-LABEL: push | |
| var a = [1,2,3]; | |
| print(a.push(1834), a.toString()); | |
| // CHECK-NEXT: 4 1,2,3,1834 | |
| print(a.push('abcd', 746, 133), a.toString()); | |
| // CHECK-NEXT: 7 1,2,3,1834,abcd,746,133 | |
| print(a.push(), a.toString()); | |
| // CHECK-NEXT: 7 1,2,3,1834,abcd,746,133 | |
| print(a.pop(), a.toString()); | |
| // CHECK-NEXT: 133 1,2,3,1834,abcd,746 | |
| print(a.push('last'), a.toString()); | |
| // CHECK-NEXT: 7 1,2,3,1834,abcd,746,last | |
| var a = [,,,'x','y','z']; | |
| print(a) | |
| // CHECK-NEXT: ,,,x,y,z | |
| print(a.push(1,2,3), a); | |
| // CHECK-NEXT: 9 ,,,x,y,z,1,2,3 | |
| var a = {3: 'x', 4: 'y', length: 5}; | |
| Array.prototype.push.call(a, 'z', 'last'); | |
| print(a.length, a[5], a[6]); | |
| // CHECK-NEXT: 7 z last | |
| var a = Array(0xfffffffe); | |
| print(a.length); | |
| // CHECK-NEXT: 4294967294 | |
| a.push('arrEnd'); | |
| print(a.length, a[4294967294]); | |
| // CHECK-NEXT: 4294967295 arrEnd | |
| try { a.push('a','b','c'); } catch (e) { print('caught', e.name) } | |
| // CHECK-NEXT: caught RangeError | |
| print(a[4294967295], a[4294967296], a[4294967297]); | |
| // CHECK-NEXT: a b c | |
| Array.prototype[1] = 'asdf'; | |
| Object.defineProperty(Array.prototype, '1', { | |
| value: 'asdf', | |
| writable: false, | |
| configurable: true, | |
| }); | |
| var a = []; | |
| try { a.push('x','y','z'); } catch (e) { print('caught', e.name) } | |
| // CHECK-NEXT: caught TypeError | |
| delete Array.prototype[1]; | |
| Object.defineProperty(Array.prototype, '1', { | |
| get: function() { return 'asdf'; }, | |
| set: function() { print('setter'); }, | |
| configurable: true, | |
| }); | |
| var a = []; | |
| print(a.push(1,2), a); | |
| // CHECK-NEXT: setter | |
| // CHECK-NEXT: 2 1,asdf | |
| delete Array.prototype[1]; | |
| var a = []; | |
| a[0] = 'x1'; | |
| a[10000] = 'x2'; | |
| print(a.push('last'), a[0], a[10000], a[10001]); | |
| // CHECK-NEXT: 10002 x1 x2 last | |
| a = null; | |
| var a = {length: 2**53 - 1}; | |
| try { a.push(1); } catch (e) { print('caught', e.name) } | |
| // CHECK-NEXT: caught TypeError | |
| print('reverse'); | |
| // CHECK-LABEL: reverse | |
| var a = [1,2,3]; | |
| print(a.reverse(), a); | |
| // CHECK-NEXT: 3,2,1 3,2,1 | |
| print([1,2].reverse()); | |
| // CHECK-NEXT: 2,1 | |
| print('empty', [].reverse()); | |
| // CHECK-NEXT: empty | |
| print([12,13,14,15,16,17,18].reverse()); | |
| // CHECK-NEXT: 18,17,16,15,14,13,12 | |
| print([,,,1].reverse()); | |
| // CHECK-NEXT: 1,,, | |
| print([,,1,,5,7,,].reverse()); | |
| // CHECK-NEXT: ,7,5,,1,, | |
| var a = {}; | |
| a[0] = 'a'; | |
| a[1] = 'b'; | |
| a[5] = 'c'; | |
| a.length = 6; | |
| Array.prototype.reverse.call(a); | |
| print(a[0], a[4], a[5]); | |
| // CHECK-NEXT: c b a | |
| var a = [0, 1, 2, 3]; | |
| Object.defineProperty(a, 3, { | |
| get: function() { | |
| delete a[1]; | |
| return -1; | |
| }, | |
| set: function() { print('setter'); } | |
| }); | |
| a.reverse(); | |
| print(a); | |
| // CHECK-NEXT: setter | |
| // CHECK-NEXT: -1,2,,-1 | |
| var a = [0, 1]; | |
| Object.defineProperty(a, 0, { | |
| get: function() { | |
| a.pop(); | |
| return -1; | |
| } | |
| }); | |
| a.reverse(); | |
| print(a); | |
| // CHECK-NEXT: ,-1 | |
| var a = []; | |
| Object.defineProperties(a, { | |
| '0': { | |
| get: function() { | |
| print('getter 0'); | |
| return a.val_0; | |
| }, | |
| set: function(v) { a.val_0 = v; } | |
| }, | |
| '1': { | |
| get: function() { | |
| print('getter 1'); | |
| return a.val_1; | |
| }, | |
| set: function(v) { a.val_1 = v; } | |
| }, | |
| }); | |
| a[0] = 0; | |
| a[1] = 1; | |
| a.reverse(); | |
| print(a); | |
| // CHECK-NEXT: getter 0 | |
| // CHECK-NEXT: getter 1 | |
| // CHECK-NEXT: getter 0 | |
| // CHECK-NEXT: getter 1 | |
| // CHECK-NEXT: 1,0 | |
| var a = [0, 1, 2, 3, 4, 5, 6]; | |
| Object.defineProperties(a, { | |
| '0': { | |
| get: function() { | |
| a.pop(); | |
| return -1; | |
| } | |
| }, | |
| '1': { | |
| set: function() { a.push('a'); } | |
| }, | |
| '2': { | |
| get: function() { | |
| a.push('b'); | |
| return -2; | |
| }, | |
| set: function() { a.pop(); } | |
| } | |
| }); | |
| a.reverse(); | |
| print(a); | |
| // CHECK-NEXT: ,,-2,3,-2,,-1,a | |
| print('shift'); | |
| // CHECK-LABEL: shift | |
| var a = [1,2,3]; | |
| print(a.shift(), a, a.length); | |
| // CHECK-NEXT: 1 2,3 2 | |
| print(a.shift(), a, a.length); | |
| // CHECK-NEXT: 2 3 1 | |
| print(a.shift(), a, a.length); | |
| // CHECK-NEXT: 3 0 | |
| print(a.shift(), a, a.length); | |
| // CHECK-NEXT: undefined 0 | |
| print(a.shift(), a, a.length); | |
| // CHECK-NEXT: undefined 0 | |
| print('slice'); | |
| // CHECK-LABEL: slice | |
| var a = ['a','b','c','d','e']; | |
| print(a.slice(1, 3), a.slice(1,3).length, a); | |
| // CHECK-NEXT: b,c 2 a,b,c,d,e | |
| print(a.slice(1)); | |
| // CHECK-NEXT: b,c,d,e | |
| print(a.slice(1, 1000)); | |
| // CHECK-NEXT: b,c,d,e | |
| print(a.slice()); | |
| // CHECK-NEXT: a,b,c,d,e | |
| print(a.slice(-1000)); | |
| // CHECK-NEXT: a,b,c,d,e | |
| print(a.slice(-1000, 1000)); | |
| // CHECK-NEXT: a,b,c,d,e | |
| print(a.slice(4, 1000)); | |
| // CHECK-NEXT: e | |
| print('empty', a.slice(4, -1000)); | |
| // CHECK-NEXT: empty | |
| var a = []; | |
| print('empty', a.slice(4, 1000)); | |
| // CHECK-NEXT: empty | |
| print('empty', a.slice(-10, 10)); | |
| // CHECK-NEXT: empty | |
| print('empty', a.slice()); | |
| // CHECK-NEXT: empty | |
| print('sort'); | |
| // CHECK-LABEL: sort | |
| print('empty', [].sort()); | |
| // CHECK-NEXT: empty | |
| print([1,2].sort()); | |
| // CHECK-NEXT: 1,2 | |
| print([2,1].sort()); | |
| // CHECK-NEXT: 1,2 | |
| print([2,13].sort()); | |
| // CHECK-NEXT: 13,2 | |
| print([2,13].sort(function(x,y) {return x - y})); | |
| // CHECK-NEXT: 2,13 | |
| print(['a', 'aaa', 'aa'].sort(function(x,y) {return x.length - y.length})); | |
| // CHECK-NEXT: a,aa,aaa | |
| print([4,3,5,1,8,6,7,2].sort()); | |
| // CHECK-NEXT: 1,2,3,4,5,6,7,8 | |
| print([8,7,6,5,4,3,2,1].sort()); | |
| // CHECK-NEXT: 1,2,3,4,5,6,7,8 | |
| print([,undefined,,8,,,7,6,5,4,3,2,1].sort()); | |
| // CHECK-NEXT: 1,2,3,4,5,6,7,8,,,,, | |
| print([8,32,86,25,71,92,66,68,97,52].sort(function(x,y) {return y - x;})); | |
| // CHECK-NEXT: 97,92,86,71,68,66,52,32,25,8 | |
| print([ | |
| 93,62,92,70,2,64,61,16,85,18,3,18,59,35,54,9,31,50,67,37,82,6,36 | |
| ].sort(function(x,y) {return x - y;})); | |
| // CHECK-NEXT: 2,3,6,9,16,18,18,31,35,36,37,50,54,59,61,62,64,67,70,82,85,92,93 | |
| var a = {0: 'c', 1: 'b', 2: 'a', 3: 'f', 4: 'd', 5: 'g', 6: 'e'}; | |
| a.length = 7; | |
| print(Array.prototype.join.call(Array.prototype.sort.call(a), '')); | |
| // CHECK-NEXT: abcdefg | |
| var a = {0: 2, 1: 13}; | |
| a.length = 2; | |
| print(Array.prototype.join.call(Array.prototype.sort.call(a))); | |
| // CHECK-NEXT: 13,2 | |
| var a = {0: 2, 1: 13}; | |
| a.length = 2; | |
| print(Array.prototype.join.call(Array.prototype.sort.call(a, function(x,y) { | |
| return x - y; | |
| }))); | |
| // CHECK-NEXT: 2,13 | |
| try { [1,2,3].sort(null); } catch(e) { print('caught', e.name); } | |
| // CHECK-NEXT: caught TypeError | |
| var badobj = { | |
| get length() { throw RangeError("Don't get the length"); } | |
| } | |
| try { [].sort.call(badobj, null); } catch(e) { print('caught', e.name); } | |
| // CHECK-NEXT: caught TypeError | |
| try { [1].sort(12); } catch(e) { print('caught', e.name); } | |
| // CHECK-NEXT: caught TypeError | |
| try { [].sort(true); } catch(e) { print('caught', e.name); } | |
| // CHECK-NEXT: caught TypeError | |
| try { [1,2,3].sort({}); } catch(e) { print('caught', e.name); } | |
| // CHECK-NEXT: caught TypeError | |
| var a = [{}, {}]; | |
| a.__defineGetter__(1, function() { a.length = 0; return 0; }); | |
| a.sort(); | |
| print('sorting', a, 'did not crash'); | |
| // CHECK-NEXT: sorting did not crash | |
| print('splice'); | |
| // CHECK-LABEL: splice | |
| var a = ['a','b','c','d']; | |
| print(a.splice(), a); | |
| // CHECK-NEXT: a,b,c,d | |
| var a = ['a','b','c','d']; | |
| print(a.splice(1), a); | |
| // CHECK-NEXT: b,c,d a | |
| var a = ['a','b','c','d']; | |
| print(a.splice(1, 2), a); | |
| // CHECK-NEXT: b,c a,d | |
| var a = ['a','b','c','d']; | |
| print(a.splice(1, 2, 'x'), a); | |
| // CHECK-NEXT: b,c a,x,d | |
| var a = ['a','b','c','d']; | |
| print(a.splice(1, 2, 'x', 'y', 'z'), a); | |
| // CHECK-NEXT: b,c a,x,y,z,d | |
| var a = ['a','b','c','d']; | |
| print(a.splice(1, 1000, 'x', 'y', 'z'), a); | |
| // CHECK-NEXT: b,c,d a,x,y,z | |
| var a = ['a','b','c','d']; | |
| print(a.splice(-1, 1, 'x', 'y', 'z'), a); | |
| // CHECK-NEXT: d a,b,c,x,y,z | |
| var a = ['a','b','c','d']; | |
| print(a.splice(-1, 1, 'x', 'y', 'z'), a); | |
| // CHECK-NEXT: d a,b,c,x,y,z | |
| var a = ['a','b','c','d']; | |
| print(a.splice(2, 0, 'x', 'y', 'z'), a); | |
| // CHECK-NEXT: a,b,x,y,z,c,d | |
| var a = ['a','b','c','d']; | |
| print(a.splice(2, -100, 'x', 'y', 'z'), a); | |
| // CHECK-NEXT: a,b,x,y,z,c,d | |
| var a = ['a',,'b',,,'c']; | |
| print(a.splice(0, 3, 'x', 'y'), a); | |
| // CHECK-NEXT: a,,b x,y,,,c | |
| print('unshift'); | |
| // CHECK-LABEL: unshift | |
| var a = [1,2,3]; | |
| print(a.unshift('a', 'b'), a); | |
| // CHECK-NEXT: 5 a,b,1,2,3 | |
| print(a.unshift(), a); | |
| // CHECK-NEXT: 5 a,b,1,2,3 | |
| print(a.unshift('c'), a); | |
| // CHECK-NEXT: 6 c,a,b,1,2,3 | |
| var a = []; | |
| print(a.unshift(1,2,3), a); | |
| // CHECK-NEXT: 3 1,2,3 | |
| var a = []; | |
| print(a.unshift(0,0,0,0,0,0,0,0,0,0), a); | |
| // CHECK-NEXT 10 0,0,0,0,0,0,0,0,0,0 | |
| print('indexOf'); | |
| // CHECK-LABEL: indexOf | |
| var a = ['a','b','c','b','x']; | |
| print(a.indexOf('b')); | |
| // CHECK-NEXT: 1 | |
| print(a.indexOf('b', 0)); | |
| // CHECK-NEXT: 1 | |
| print(a.indexOf('b', -2)); | |
| // CHECK-NEXT: 3 | |
| print(a.indexOf('b', 2)); | |
| // CHECK-NEXT: 3 | |
| print(a.indexOf('b', -1)); | |
| // CHECK-NEXT: -1 | |
| print(a.indexOf('b', 4)); | |
| // CHECK-NEXT: -1 | |
| print(a.indexOf('d')); | |
| // CHECK-NEXT: -1 | |
| var a = []; | |
| print(a.indexOf('a', -1)); | |
| // CHECK-NEXT: -1 | |
| print(a.indexOf('a', 4)); | |
| // CHECK-NEXT: -1 | |
| print(a.indexOf('a')); | |
| // CHECK-NEXT: -1 | |
| print(1 / [true].indexOf(true, -0)); | |
| //CHECK-NEXT: Infinity | |
| print('lastIndexOf'); | |
| // CHECK-LABEL: lastIndexOf | |
| var a = ['a','b','c','b','x']; | |
| print(a.lastIndexOf('b')); | |
| // CHECK-NEXT: 3 | |
| print(a.lastIndexOf('b', 0)); | |
| // CHECK-NEXT: -1 | |
| print(a.lastIndexOf('b', -2)); | |
| // CHECK-NEXT: 3 | |
| print(a.lastIndexOf('b', 2)); | |
| // CHECK-NEXT: 1 | |
| print(a.lastIndexOf('b', -1)); | |
| // CHECK-NEXT: 3 | |
| print(a.lastIndexOf('b', 4)); | |
| // CHECK-NEXT: 3 | |
| print(a.lastIndexOf('d')); | |
| // CHECK-NEXT: -1 | |
| var a = []; | |
| print(a.lastIndexOf('a', -1)); | |
| // CHECK-NEXT: -1 | |
| print(a.lastIndexOf('a', 4)); | |
| // CHECK-NEXT: -1 | |
| print(a.lastIndexOf('a')); | |
| // CHECK-NEXT: -1 | |
| print('every'); | |
| // CHECK-LABEL: every | |
| print([1,2,3].every(function(x) {return x < 4})); | |
| // CHECK-NEXT: true | |
| print([1,2,3].every(function(x) {return x < 2})); | |
| // CHECK-NEXT: false | |
| print([].every(function(x) {return false})); | |
| // CHECK-NEXT: true | |
| print(['!', '@', '#'].every(function(x, i, arr) { | |
| print(this, x, i, arr); | |
| return x === '!'; | |
| }, 'thisval')); | |
| // CHECK-NEXT: thisval ! 0 !,@,# | |
| // CHECK-NEXT: thisval @ 1 !,@,# | |
| // CHECK-NEXT: false | |
| try {[1].every(1)} catch(e) {print('caught', e.name, e.message);} | |
| // CHECK-NEXT: caught TypeError {{.*}} | |
| print('some'); | |
| // CHECK-LABEL: some | |
| print([1,2,3].some(function(x) {return x < 4})); | |
| // CHECK-NEXT: true | |
| print([1,2,3].some(function(x) {return x < 2})); | |
| // CHECK-NEXT: true | |
| print([1,2,3].some(function(x) {return x < 0})); | |
| // CHECK-NEXT: false | |
| print([].some(function(x) {return false})); | |
| // CHECK-NEXT: false | |
| print(['!', '@', '#'].some(function(x, i, arr) { | |
| print(this, x, i, arr); | |
| return x === '!'; | |
| }, 'thisval')); | |
| // CHECK-NEXT: thisval ! 0 !,@,# | |
| // CHECK-NEXT: true | |
| print('foreach'); | |
| // CHECK-LABEL: foreach | |
| print(['!', '@', '#'].forEach(function(x, i, arr) { | |
| print(this, x, i, arr); | |
| return x === '!'; | |
| })); | |
| // CHECK-NEXT: undefined ! 0 !,@,# | |
| // CHECK-NEXT: undefined @ 1 !,@,# | |
| // CHECK-NEXT: undefined # 2 !,@,# | |
| // CHECK-NEXT: undefined | |
| print(['!', '@', '#'].forEach(function(x, i, arr) { | |
| print(this, x, i, arr); | |
| return x === '!'; | |
| }, 'thisval')); | |
| // CHECK-NEXT: thisval ! 0 !,@,# | |
| // CHECK-NEXT: thisval @ 1 !,@,# | |
| // CHECK-NEXT: thisval # 2 !,@,# | |
| // CHECK-NEXT: undefined | |
| try {[1].forEach(1)} catch(e) {print('caught', e.name, e.message);} | |
| // CHECK-NEXT: caught TypeError {{.*}} | |
| print('map'); | |
| // CHECK-LABEL: map | |
| print(['!', '@', '#'].map(function(x, i, arr) { | |
| print(this, x, i, arr); | |
| return x === '!'; | |
| })); | |
| // CHECK-NEXT: undefined ! 0 !,@,# | |
| // CHECK-NEXT: undefined @ 1 !,@,# | |
| // CHECK-NEXT: undefined # 2 !,@,# | |
| // CHECK-NEXT: true,false,false | |
| print(['!', '@', '#'].map(function(x, i, arr) { | |
| print(this, x, i, arr); | |
| return x === '!'; | |
| }, 'thisval')); | |
| // CHECK-NEXT: thisval ! 0 !,@,# | |
| // CHECK-NEXT: thisval @ 1 !,@,# | |
| // CHECK-NEXT: thisval # 2 !,@,# | |
| // CHECK-NEXT: true,false,false | |
| try {[1].map(1)} catch(e) {print('caught', e.name, e.message);} | |
| // CHECK-NEXT: caught TypeError {{.*}} | |
| print('filter'); | |
| // CHECK-LABEL: filter | |
| var a = [1,2,3]; | |
| print(a.filter(function(x) {return x === 2})); | |
| // CHECK-NEXT: 2 | |
| print(a.filter(function(x) {return x !== 2})); | |
| // CHECK-NEXT: 1,3 | |
| print(a.filter(function() {return true})); | |
| // CHECK-NEXT: 1,2,3 | |
| print('empty', a.filter(function() {return false})); | |
| // CHECK-NEXT: empty | |
| var a = []; | |
| print('empty', a.filter(function() {return true})); | |
| // CHECK-NEXT: empty | |
| print(['!', '@', '#'].filter(function(x, i, arr) { | |
| print(this, x, i, arr); | |
| return x === '!'; | |
| }, 'thisval')); | |
| // CHECK-NEXT: thisval ! 0 !,@,# | |
| // CHECK-NEXT: thisval @ 1 !,@,# | |
| // CHECK-NEXT: thisval # 2 !,@,# | |
| // CHECK-NEXT: ! | |
| var a = [null,2,3]; | |
| var acc = {get: function() {return 1000}}; | |
| Object.defineProperty(a, 0, acc); | |
| print(a.filter(function(x) {return x === 1000})); | |
| // CHECK-NEXT: 1000 | |
| var a = {}; | |
| a[0] = 1239; | |
| a[3] = 18583; | |
| a.length = 6; | |
| print(Array.prototype.filter.call(a, function(x) {return x === 1239})); | |
| // CHECK-NEXT: 1239 | |
| try {[1].filter(1)} catch(e) {print('caught', e.name, e.message);} | |
| // CHECK-NEXT: caught TypeError {{.*}} | |
| print('fill'); | |
| // CHECK-LABEL: fill | |
| var a = Array(3); | |
| a.fill(); | |
| print(a[0], a[1], a[2]); | |
| // CHECK-NEXT: undefined undefined undefined | |
| a.fill(1); | |
| print(a[0], a[1], a[2]); | |
| // CHECK-NEXT: 1 1 1 | |
| a.fill(2, 0, a.length); | |
| print(a[0], a[1], a[2]); | |
| // CHECK-NEXT: 2 2 2 | |
| a.fill(3, -1); | |
| print(a[0], a[1], a[2]); | |
| // CHECK-NEXT: 2 2 3 | |
| a.fill(4, 1, -1); | |
| print(a[0], a[1], a[2]); | |
| // CHECK-NEXT: 2 4 3 | |
| var a = {}; | |
| a[0] = 1; | |
| a[3] = 2; | |
| a.length = 6; | |
| Array.prototype.fill.call(a, 0); | |
| print(a[0], a[1], a[2], a[3], a[4], a[5]); | |
| // CHECK-NEXT: 0 0 0 0 0 0 | |
| print('Pop from large array'); | |
| // CHECK-LABEL: Pop from large array | |
| // This caused a crash with SegmentedArray used as the backing storage. | |
| // It was due to an off-by-one error in SegmentedArray::decreaseSize. | |
| var a = Array(4097).fill(); | |
| // This pop causes the backing storage to shrink to only be inline storage. | |
| a.pop(); | |
| print(a[a.length - 1]); | |
| // CHECK-NEXT: undefined | |
| a = Array(5121).fill(); | |
| // This pop causes the backing storage to shrink to one segment instead of 2. | |
| a.pop(); | |
| print(a[a.length - 1]); | |
| // CHECK-NEXT: undefined | |
| print('find'); | |
| // CHECK-LABEL: find | |
| print(Array.prototype.find.length); | |
| // CHECK-NEXT: 1 | |
| print([].find(function(){})); | |
| // CHECK-NEXT: undefined | |
| print([1,2,3].find(function(v){ return v === 4 })); | |
| // CHECK-NEXT: undefined | |
| print([0,1,2].find(function(v){ return v })); | |
| // CHECK-NEXT: 1 | |
| print(['a','b','c'].find(function(v, k, obj) { | |
| print(this, v, k, obj); | |
| return v === 'b'; | |
| }, 'thisarg')); | |
| // CHECK-NEXT: thisarg a 0 a,b,c | |
| // CHECK-NEXT: thisarg b 1 a,b,c | |
| // CHECK-NEXT: b | |
| print(Array.prototype.find.call( | |
| {0:'a',1:'b',length:3}, | |
| function(v) { return v === 'b'; } | |
| )); | |
| // CHECK-NEXT: b | |
| print('findIndex'); | |
| // CHECK-LABEL: findIndex | |
| print(Array.prototype.findIndex.length); | |
| // CHECK-NEXT: 1 | |
| print([].findIndex(function(){})); | |
| // CHECK-NEXT: -1 | |
| print([1,2,3].findIndex(function(v){ return v === 4 })); | |
| // CHECK-NEXT: -1 | |
| print([0,1,2].findIndex(function(v){ return v })); | |
| // CHECK-NEXT: 1 | |
| print(['a','b','c'].findIndex(function(v, k, obj) { | |
| print(this, v, k, obj); | |
| return v === 'b'; | |
| }, 'thisarg')); | |
| // CHECK-NEXT: thisarg a 0 a,b,c | |
| // CHECK-NEXT: thisarg b 1 a,b,c | |
| // CHECK-NEXT: 1 | |
| print(Array.prototype.findIndex.call( | |
| {0:'a',1:'b',length:3}, | |
| function(v) { return v === 'b'; } | |
| )); | |
| // CHECK-NEXT: 1 | |
| print('reduce'); | |
| // CHECK-LABEL: reduce | |
| var a = [1,2,3,4]; | |
| print(a.reduce(function(x,y) {return x + y})); | |
| // CHECK-NEXT: 10 | |
| print(a.reduce(function(x,y) {return x + y}, 100)); | |
| // CHECK-NEXT: 110 | |
| print(a.reduce(function(x,y) {return x * y})); | |
| // CHECK-NEXT: 24 | |
| var a = []; | |
| print(a.reduce(function() {}, 10)); | |
| // CHECK-NEXT: 10 | |
| var a = [,,,,1,2,,,,3,,4,,,]; | |
| print(a.reduce(function(x,y) {return x + y})); | |
| // CHECK-NEXT: 10 | |
| print(a.reduce(function(x,y) {return x + y}, 100)); | |
| // CHECK-NEXT: 110 | |
| print(['!', '@', '#'].reduce(function(x, y, i, arr) { | |
| print(this, x, y, i, arr); | |
| return x + y; | |
| }, '**')); | |
| // CHECK-NEXT: undefined ** ! 0 !,@,# | |
| // CHECK-NEXT: undefined **! @ 1 !,@,# | |
| // CHECK-NEXT: undefined **!@ # 2 !,@,# | |
| // CHECK-NEXT: **!@# | |
| try {[1].reduce(1)} catch(e) {print('caught', e.name, e.message);} | |
| // CHECK-NEXT: caught TypeError {{.*}} | |
| var a = Array(10); | |
| try {print(a.reduce(function(){}));} catch(e) {print('caught', e.name, e.message)} | |
| // CHECK-NEXT: caught TypeError {{.*}} | |
| print('reduceRight'); | |
| // CHECK-LABEL: reduceRight | |
| var a = [1,2,3,4]; | |
| print(a.reduceRight(function(x,y) {return x + y})); | |
| // CHECK-NEXT: 10 | |
| print(a.reduceRight(function(x,y) {return x + y}, 100)); | |
| // CHECK-NEXT: 110 | |
| print(a.reduceRight(function(x,y) {return x * y})); | |
| // CHECK-NEXT: 24 | |
| var a = []; | |
| print(a.reduceRight(function() {}, 10)); | |
| // CHECK-NEXT: 10 | |
| var a = [,,,,1,2,,,,3,,4,,,]; | |
| print(a.reduceRight(function(x,y) {return x + y})); | |
| // CHECK-NEXT: 10 | |
| print(a.reduceRight(function(x,y) {return x + y}, 100)); | |
| // CHECK-NEXT: 110 | |
| print(['!', '@', '#'].reduceRight(function(x, y, i, arr) { | |
| print(this, x, y, i, arr); | |
| return x + y; | |
| }, '**')); | |
| // CHECK-NEXT: undefined ** # 2 !,@,# | |
| // CHECK-NEXT: undefined **# @ 1 !,@,# | |
| // CHECK-NEXT: undefined **#@ ! 0 !,@,# | |
| // CHECK-NEXT: **#@! | |
| var a = Array(10); | |
| try {print(a.reduceRight(function(){}));} catch(e) {print('caught', e.name, e.message)} | |
| // CHECK-NEXT: caught TypeError {{.*}} | |
| try {[1].reduceRight(1)} catch(e) {print('caught', e.name, e.message);} | |
| // CHECK-NEXT: caught TypeError {{.*}} | |
| try {print(a.reduce(function(){}));} catch(e) {print('caught', e.name, e.message)} | |
| // CHECK-NEXT: caught TypeError {{.*}} | |
| print('includes'); | |
| // CHECK-LABEL: includes | |
| print([1,2,3,4].includes(1)); | |
| // CHECK-NEXT: true | |
| print([1,2,3,4].includes(1, Infinity)); | |
| // CHECK-NEXT: false | |
| print([1,2,3,4].includes(1, 1)); | |
| // CHECK-NEXT: false | |
| print([1,2,3,4].includes(1, -2)); | |
| // CHECK-NEXT: false | |
| print([1,2,3,4].includes(1, -4)); | |
| // CHECK-NEXT: true | |
| print([1,2,3,4].includes(3)); | |
| // CHECK-NEXT: true | |
| print([1,2,3,4].includes(4)); | |
| // CHECK-NEXT: true | |
| print([1,2,3,4].includes(4, -1)); | |
| // CHECK-NEXT: true | |
| print([1,2,3,4].includes(4, 3)); | |
| // CHECK-NEXT: true | |
| print([1,2,3,4].includes({})); | |
| // CHECK-NEXT: false | |
| print([1,2,3,4].includes(10)); | |
| // CHECK-NEXT: false | |
| print([].includes(10)); | |
| // CHECK-NEXT: false | |
| print(Array.prototype.includes.call({length: 3, 0: 'a', 1: 'b', 2: 'c'}, 'a')); | |
| // CHECK-NEXT: true | |
| var o = {}; | |
| print([,,,o,,,].includes(o)); | |
| // CHECK-NEXT: true | |
| print('flat'); | |
| // CHECK-LABEL: flat | |
| print([].flat().length); | |
| // CHECK-NEXT: 0 | |
| print(arrayEquals([1,2,3].flat(), [1,2,3])); | |
| // CHECK-NEXT: true | |
| print(arrayEquals([1,[2,3]].flat(), [1,2,3])); | |
| // CHECK-NEXT: true | |
| print(arrayEquals([1,[2,[3]]].flat(), [1,2,[3]])); | |
| // CHECK-NEXT: true | |
| print(arrayEquals([1,[2,[3,[4]]]].flat(0), [1,[2,[3,[4]]]])); | |
| // CHECK-NEXT: true | |
| print(arrayEquals([1,[2,[3,[4]]]].flat(), [1,2,[3,[4]]])); | |
| // CHECK-NEXT: true | |
| print(arrayEquals([1,[2,[3,[4]]]].flat(1), [1,2,[3,[4]]])); | |
| // CHECK-NEXT: true | |
| print(arrayEquals([1,[2,[3,[4]]]].flat(2), [1,2,3,[4]])); | |
| // CHECK-NEXT: true | |
| print(arrayEquals([1,[2,[3,[4]]]].flat(Infinity), [1,2,3,4])); | |
| // CHECK-NEXT: true | |
| var a = [1]; | |
| for (var i = 0; i < 1000; ++i) { | |
| a = [a]; | |
| } | |
| try { a.flat(Infinity); } catch(e) { print('caught', e.name) } | |
| // CHECK-NEXT: caught RangeError | |
| print('flatMap'); | |
| // CHECK-LABEL: flatMap | |
| print([].flatMap(() => { throw Error('fail') }).length); | |
| // CHECK-NEXT: 0 | |
| print(arrayEquals([1,2,3].flatMap(x => x+1), [2,3,4])); | |
| // CHECK-NEXT: true | |
| print(arrayEquals([1,2,3].flatMap(function(x) { | |
| return x + this; | |
| }, 100), [101, 102, 103])); | |
| // CHECK-NEXT: true | |
| print(arrayEquals([1,2,3].flatMap(function(x) { | |
| return [x, x+this]; | |
| }, 100), [1,101,2,102,3,103])); | |
| // CHECK-NEXT: true |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment