Upload Kmake

This commit is contained in:
Gorochu
2026-05-26 23:36:42 -07:00
parent ba051b2f74
commit 555ec72358
41615 changed files with 13344630 additions and 1 deletions

35
deps/v8/test/mjsunit/BUILD.gn vendored Normal file
View File

@ -0,0 +1,35 @@
# Copyright 2018 the V8 project authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
group("v8_mjsunit") {
testonly = true
data_deps = [
"../../:d8",
"../../tools/:v8_testrunner",
]
data = [
"./",
"../../tools/arguments.mjs",
"../../tools/clusterfuzz/foozzie/v8_mock.js",
"../../tools/clusterfuzz/foozzie/v8_mock_archs.js",
"../../tools/clusterfuzz/foozzie/v8_mock_webassembly.js",
"../../tools/codemap.mjs",
"../../tools/sourcemap.mjs",
"../../tools/consarray.mjs",
"../../tools/csvparser.mjs",
"../../tools/dumpcpp.mjs",
"../../tools/js/helper.mjs",
"../../tools/logreader.mjs",
"../../tools/profile.mjs",
"../../tools/profile_view.mjs",
"../../tools/splaytree.mjs",
"../../tools/system-analyzer/log/",
"../../tools/system-analyzer/processor.mjs",
"../../tools/system-analyzer/timeline.mjs",
"../../tools/system-analyzer/helper.mjs",
"../../tools/tickprocessor.mjs",
]
}

View File

@ -0,0 +1,192 @@
// Copyright 2012 the V8 project authors. All rights reserved.
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following
// disclaimer in the documentation and/or other materials provided
// with the distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// Flags: --allow-natives-syntax
// Handy abbreviations.
var dp = Object.defineProperty;
var gop = Object.getOwnPropertyDescriptor;
function getter() { return 111; }
function setter(x) { print(222); }
function anotherGetter() { return 333; }
function anotherSetter(x) { print(444); }
var obj1, obj2, obj3, obj4;
// Two objects with the same getter.
obj1 = {};
dp(obj1, "alpha", { get: getter });
obj2 = {};
dp(obj2, "alpha", { get: getter });
assertTrue(%HaveSameMap(obj1, obj2));
// Two objects with the same getter, oldskool.
obj1 = {};
obj1.__defineGetter__("bravo", getter);
assertEquals(getter, obj1.__lookupGetter__("bravo"));
obj2 = {};
obj2.__defineGetter__("bravo", getter);
assertEquals(getter, obj2.__lookupGetter__("bravo"));
assertTrue(%HaveSameMap(obj1, obj2));
// Two objects with the same setter.
obj1 = {};
dp(obj1, "charlie", { set: setter });
obj2 = {};
dp(obj2, "charlie", { set: setter });
assertTrue(%HaveSameMap(obj1, obj2));
// Two objects with the same setter, oldskool.
obj1 = {};
obj1.__defineSetter__("delta", setter);
assertEquals(setter, obj1.__lookupSetter__("delta"));
obj2 = {};
obj2.__defineSetter__("delta", setter);
assertEquals(setter, obj2.__lookupSetter__("delta"));
assertTrue(%HaveSameMap(obj1, obj2));
// Two objects with the same getter and setter.
obj1 = {};
dp(obj1, "foxtrot", { get: getter, set: setter });
obj2 = {};
dp(obj2, "foxtrot", { get: getter, set: setter });
assertTrue(%HaveSameMap(obj1, obj2));
// Two objects with the same getter and setter, set separately.
obj1 = {};
dp(obj1, "golf", { get: getter, configurable: true });
dp(obj1, "golf", { set: setter, configurable: true });
obj2 = {};
dp(obj2, "golf", { get: getter, configurable: true });
dp(obj2, "golf", { set: setter, configurable: true });
assertTrue(%HaveSameMap(obj1, obj2));
// Two objects with the same getter and setter, set separately, oldskool.
obj1 = {};
obj1.__defineGetter__("hotel", getter);
obj1.__defineSetter__("hotel", setter);
obj2 = {};
obj2.__defineGetter__("hotel", getter);
obj2.__defineSetter__("hotel", setter);
assertTrue(%HaveSameMap(obj1, obj2));
// Attribute-only change, shouldn't affect previous descriptor properties.
obj1 = {};
dp(obj1, "india", { get: getter, configurable: true, enumerable: true });
assertEquals(getter, gop(obj1, "india").get);
assertTrue(gop(obj1, "india").configurable);
assertTrue(gop(obj1, "india").enumerable);
dp(obj1, "india", { enumerable: false });
assertEquals(getter, gop(obj1, "india").get);
assertTrue(gop(obj1, "india").configurable);
assertFalse(gop(obj1, "india").enumerable);
// Attribute-only change, shouldn't affect objects with previously shared maps.
obj1 = {};
dp(obj1, "juliet", { set: setter, configurable: true, enumerable: false });
assertEquals(setter, gop(obj1, "juliet").set);
assertTrue(gop(obj1, "juliet").configurable);
assertFalse(gop(obj1, "juliet").enumerable);
obj2 = {};
dp(obj2, "juliet", { set: setter, configurable: true, enumerable: false });
assertEquals(setter, gop(obj2, "juliet").set);
assertTrue(gop(obj2, "juliet").configurable);
assertFalse(gop(obj2, "juliet").enumerable);
dp(obj1, "juliet", { set: setter, configurable: false, enumerable: true });
assertEquals(setter, gop(obj1, "juliet").set);
assertFalse(gop(obj1, "juliet").configurable);
assertTrue(gop(obj1, "juliet").enumerable);
assertEquals(setter, gop(obj2, "juliet").set);
assertTrue(gop(obj2, "juliet").configurable);
assertFalse(gop(obj2, "juliet").enumerable);
// Two objects with the different getters.
obj1 = {};
dp(obj1, "kilo", { get: getter });
obj2 = {};
dp(obj2, "kilo", { get: anotherGetter });
assertEquals(getter, gop(obj1, "kilo").get);
assertEquals(anotherGetter, gop(obj2, "kilo").get);
assertFalse(%HaveSameMap(obj1, obj2));
// Two objects with the same getters and different setters.
obj1 = {};
dp(obj1, "lima", { get: getter, set: setter });
obj2 = {};
dp(obj2, "lima", { get: getter, set: anotherSetter });
assertEquals(setter, gop(obj1, "lima").set);
assertEquals(anotherSetter, gop(obj2, "lima").set);
assertFalse(%HaveSameMap(obj1, obj2));
// Even 'undefined' is a kind of getter.
obj1 = {};
dp(obj1, "mike", { get: undefined });
assertTrue("mike" in obj1);
assertEquals(undefined, gop(obj1, "mike").get);
assertEquals(undefined, obj1.__lookupGetter__("mike"));
assertEquals(undefined, gop(obj1, "mike").set);
assertEquals(undefined, obj1.__lookupSetter__("mike"));
// Even 'undefined' is a kind of setter.
obj1 = {};
dp(obj1, "november", { set: undefined });
assertTrue("november" in obj1);
assertEquals(undefined, gop(obj1, "november").get);
assertEquals(undefined, obj1.__lookupGetter__("november"));
assertEquals(undefined, gop(obj1, "november").set);
assertEquals(undefined, obj1.__lookupSetter__("november"));
// Redefining a data property.
obj1 = {};
obj1.oscar = 12345;
dp(obj1, "oscar", { set: setter });
assertEquals(setter, gop(obj1, "oscar").set);
// Re-adding the same getter/attributes pair.
obj1 = {};
dp(obj1, "papa", { get: getter, configurable: true });
dp(obj1, "papa", { get: getter, set: setter, configurable: true });
assertEquals(getter, gop(obj1, "papa").get);
assertEquals(setter, gop(obj1, "papa").set);
assertTrue(gop(obj1, "papa").configurable);
assertFalse(gop(obj1, "papa").enumerable);
// Two objects with the same getter on the prototype chain.
obj1 = {};
dp(obj1, "quebec", { get: getter });
obj2 = Object.create(obj1);
obj3 = Object.create(obj2);
obj4 = Object.create(obj2);
assertTrue(%HaveSameMap(obj3, obj4));
// Two objects with the same setter on the prototype chain.
obj1 = {};
dp(obj1, "romeo", { set: setter });
obj2 = Object.create(obj1);
obj3 = Object.create(obj2);
obj4 = Object.create(obj2);
assertTrue(%HaveSameMap(obj3, obj4));

View File

@ -0,0 +1,51 @@
// Copyright 2014 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
(function TestGetter() {
var o = {
get x() {}
};
var desc = Object.getOwnPropertyDescriptor(o, 'x');
assertEquals('function', typeof desc.get);
assertFalse('prototype' in desc.get);
assertThrows(function() {
new desc.get();
}, TypeError);
})();
(function TestSetter() {
var o = {
set x(_) {}
};
var desc = Object.getOwnPropertyDescriptor(o, 'x');
assertEquals('function', typeof desc.set);
assertFalse('prototype' in desc.set);
assertThrows(function() {
new desc.set();
}, TypeError);
})();
(function TestBoth() {
var o = {
get x() {},
set x(_) {}
};
var desc = Object.getOwnPropertyDescriptor(o, 'x');
assertEquals('function', typeof desc.get);
assertEquals('function', typeof desc.set);
assertFalse('prototype' in desc.get);
assertFalse('prototype' in desc.set);
assertThrows(function() {
new desc.get();
}, TypeError);
assertThrows(function() {
new desc.set();
}, TypeError);
})();

View File

@ -0,0 +1,72 @@
// Copyright 2010 the V8 project authors. All rights reserved.
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following
// disclaimer in the documentation and/or other materials provided
// with the distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// Test that installing a getter on the global object instead of a
// normal property works.
x = 0;
function getX() { return x; }
for (var i = 0; i < 10; i++) {
assertEquals(i < 5 ? 0 : 42, getX());
if (i == 4) this.__defineGetter__("x", function() { return 42; });
}
// Test that installing a setter on the global object instead of a
// normal property works.
y = 0;
var setter_y;
function setY(value) { y = value; }
for (var i = 0; i < 10; i++) {
setY(i);
assertEquals(i < 5 ? i : 2 * i, y);
if (i == 4) {
this.__defineSetter__("y", function(value) { setter_y = 2 * value; });
this.__defineGetter__("y", function() { return setter_y; });
}
}
// Test that replacing a getter with a normal property works as
// expected.
this.__defineGetter__("z", function() { return 42; });
function getZ() { return z; }
for (var i = 0; i < 10; i++) {
assertEquals(i < 5 ? 42 : 0, getZ());
if (i == 4) {
delete z;
z = 0;
}
}

View File

@ -0,0 +1,346 @@
// Copyright 2024 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 --additive-safe-int-feedback
// Flags: --turbofan --no-always-turbofan
const maxAdditiveSafeInteger = 4503599627370495; // 2^52 - 1
const minAdditiveSafeInteger = - 4503599627370496; // - 2^52
// If one of the inputs is a constant in the additive safe range,
// we can use AdditiveSafeInteger.
(function() {
function foo(a) {
return a + 1;
}
%PrepareFunctionForOptimization(foo);
assertEquals(1231234567891, foo(1231234567890));
assertEquals(1231234567891, foo(1231234567890));
%OptimizeFunctionOnNextCall(foo);
assertEquals(1231234567891, foo(1231234567890));
assertOptimized(foo);
// We don't deopt in the maximum value.
assertEquals(maxAdditiveSafeInteger, foo(maxAdditiveSafeInteger - 1));
assertOptimized(foo);
// Nor in the minimum.
assertEquals(minAdditiveSafeInteger + 1, foo(minAdditiveSafeInteger));
assertOptimized(foo);
// We deopt if we overflow!
assertEquals(maxAdditiveSafeInteger + 1, foo(maxAdditiveSafeInteger));
assertUnoptimized(foo);
// Optimize again.
%OptimizeFunctionOnNextCall(foo);
assertEquals(1231234567891, foo(1231234567890));
assertOptimized(foo);
// This time we don't overflow, since we use
// Float64Add.
assertEquals(maxAdditiveSafeInteger + 1, foo(maxAdditiveSafeInteger));
assertOptimized(foo);
// Don't deopt with doubles.
assertEquals(2.5, foo(1.5));
assertOptimized(foo);
})();
// Deopt if input is a double.
(function() {
function foo(a) {
return a + 1;
}
%PrepareFunctionForOptimization(foo);
assertEquals(1231234567891, foo(1231234567890));
assertEquals(1231234567891, foo(1231234567890));
%OptimizeFunctionOnNextCall(foo);
assertEquals(1231234567891, foo(1231234567890));
assertOptimized(foo);
// Deopt if input is a double.
assertEquals(2.5, foo(1.5));
assertUnoptimized(foo);
// Optimize again.
%OptimizeFunctionOnNextCall(foo);
assertEquals(1231234567891, foo(1231234567890));
assertOptimized(foo);
// Don't deopt with doubles anymore.
assertEquals(2.5, foo(1.5));
assertOptimized(foo);
})();
// If we don't know statically that one of the inputs is
// in the additive safe range, we fallback to float64 add.
(function() {
function foo(a, b) {
return a + b;
}
%PrepareFunctionForOptimization(foo);
assertEquals(1231234567891, foo(1231234567890, 1));
assertEquals(1231234567891, foo(1231234567890, 1));
%OptimizeFunctionOnNextCall(foo);
assertEquals(1231234567891, foo(1231234567890, 1));
assertOptimized(foo);
// We don't deopt in overflow.
assertEquals(maxAdditiveSafeInteger + 1, foo(maxAdditiveSafeInteger, 1));
assertOptimized(foo);
// Don't deopt with doubles.
assertEquals(2.5, foo(1.5, 1));
assertOptimized(foo);
})();
// We deopt in minus zero.
(function() {
function foo(a) {
return a + 1;
}
%PrepareFunctionForOptimization(foo);
assertEquals(1231234567891, foo(1231234567890));
assertEquals(1231234567891, foo(1231234567890));
%OptimizeFunctionOnNextCall(foo);
assertEquals(1231234567891, foo(1231234567890));
assertOptimized(foo);
// TODO(victorgomes): If we know one of the inputs is
// definitely not minus zero, we could avoid deopting here.
assertEquals(1, foo(-0));
assertUnoptimized(foo);
// Optimize again.
%OptimizeFunctionOnNextCall(foo);
assertEquals(1231234567891, foo(1231234567890));
assertOptimized(foo);
// Don't deopt with doubles.
assertEquals(2.5, foo(1.5));
assertOptimized(foo);
})();
// Optimize to AdditiveSafeInteger if one of the inputs is truncated, since it is
// in the safe integer range.
(function() {
function foo(a, b) {
return a + (b | 0);
}
%PrepareFunctionForOptimization(foo);
assertEquals(1231234567891, foo(1231234567890, 1));
assertEquals(1231234567891, foo(1231234567890, 1));
%OptimizeFunctionOnNextCall(foo);
assertEquals(1231234567891, foo(1231234567890, 1));
assertOptimized(foo);
// We don't deopt in the maximum value.
assertEquals(maxAdditiveSafeInteger, foo(maxAdditiveSafeInteger - 1, 1));
assertOptimized(foo);
// Nor in the minimum.
assertEquals(minAdditiveSafeInteger + 1, foo(minAdditiveSafeInteger, 1));
assertOptimized(foo);
// We deopt if we overflow!
assertEquals(maxAdditiveSafeInteger + 1, foo(maxAdditiveSafeInteger, 1));
assertUnoptimized(foo);
// Optimize again.
%OptimizeFunctionOnNextCall(foo);
assertEquals(1231234567891, foo(1231234567890, 1));
assertOptimized(foo);
// This time we don't overflow, since we use
// Float64Add.
assertEquals(maxAdditiveSafeInteger + 1, foo(maxAdditiveSafeInteger, 1));
assertOptimized(foo);
// Don't deopt with doubles.
assertEquals(2.5, foo(1.5, 1));
assertOptimized(foo);
})();
// Optimize when the result is pass to another add, since we know the result of
// the add is in the safe integer range.
(function() {
function foo(a, b) {
return 1 + a + b;
}
%PrepareFunctionForOptimization(foo);
assertEquals(1231234567892, foo(1231234567890, 1));
assertEquals(1231234567892, foo(1231234567890, 1));
%OptimizeFunctionOnNextCall(foo);
assertEquals(1231234567892, foo(1231234567890, 1));
assertOptimized(foo);
// We don't deopt in the maximum value.
assertEquals(maxAdditiveSafeInteger, foo(maxAdditiveSafeInteger - 2, 1));
assertOptimized(foo);
// Nor in the minimum.
assertEquals(minAdditiveSafeInteger + 2, foo(minAdditiveSafeInteger, 1));
assertOptimized(foo);
// Overflow the second add to ensure that we optimize with additive safe int add.
assertEquals(maxAdditiveSafeInteger + 1, foo(maxAdditiveSafeInteger - 1, 1));
assertUnoptimized(foo);
// Optimize again.
%OptimizeFunctionOnNextCall(foo);
assertEquals(1231234567892, foo(1231234567890, 1));
assertOptimized(foo);
// This time we don't overflow, since we useFloat64Add.
assertEquals(maxAdditiveSafeInteger + 1, foo(maxAdditiveSafeInteger - 1, 1));
assertOptimized(foo);
// But we can still deopt the first add.
assertEquals(maxAdditiveSafeInteger + 2, foo(maxAdditiveSafeInteger, 1));
assertUnoptimized(foo);
// Optimize again.
%OptimizeFunctionOnNextCall(foo);
assertEquals(1231234567892, foo(1231234567890, 1));
assertOptimized(foo);
// This time no deopts.
assertEquals(maxAdditiveSafeInteger + 1, foo(maxAdditiveSafeInteger - 1, 1));
assertEquals(maxAdditiveSafeInteger + 2, foo(maxAdditiveSafeInteger, 1));
assertOptimized(foo);
// Don't deopt with doubles.
assertEquals(3.5, foo(1.5, 1));
assertOptimized(foo);
})();
// This also works if the known input is the middle one.
(function() {
function foo(a, b) {
return a + 1 + b;
}
%PrepareFunctionForOptimization(foo);
assertEquals(1231234567892, foo(1231234567890, 1));
assertEquals(1231234567892, foo(1231234567890, 1));
%OptimizeFunctionOnNextCall(foo);
assertEquals(1231234567892, foo(1231234567890, 1));
assertOptimized(foo);
// We don't deopt in the maximum value.
assertEquals(maxAdditiveSafeInteger, foo(maxAdditiveSafeInteger - 2, 1));
assertOptimized(foo);
// Nor in the minimum.
assertEquals(minAdditiveSafeInteger + 2, foo(minAdditiveSafeInteger, 1));
assertOptimized(foo);
// Overflow the second add to ensure that we optimize with additive safe int add.
assertEquals(maxAdditiveSafeInteger + 1, foo(maxAdditiveSafeInteger - 1, 1));
assertUnoptimized(foo);
// Optimize again.
%OptimizeFunctionOnNextCall(foo);
assertEquals(1231234567892, foo(1231234567890, 1));
assertOptimized(foo);
// This time we don't overflow, since we useFloat64Add.
assertEquals(maxAdditiveSafeInteger + 1, foo(maxAdditiveSafeInteger - 1, 1));
assertOptimized(foo);
// But we can still deopt the first add.
assertEquals(maxAdditiveSafeInteger + 2, foo(maxAdditiveSafeInteger, 1));
assertUnoptimized(foo);
// Optimize again.
%OptimizeFunctionOnNextCall(foo);
assertEquals(1231234567892, foo(1231234567890, 1));
assertOptimized(foo);
// This time no deopts.
assertEquals(maxAdditiveSafeInteger + 1, foo(maxAdditiveSafeInteger - 1, 1));
assertEquals(maxAdditiveSafeInteger + 2, foo(maxAdditiveSafeInteger, 1));
assertOptimized(foo);
// Don't deopt with doubles.
assertEquals(3.5, foo(1.5, 1));
assertOptimized(foo);
})();
// Since add is not an associative operation in JS, unfortunately, we don't
// optimize the first add.
(function() {
function foo(a, b) {
return a + b + 1;
}
%PrepareFunctionForOptimization(foo);
assertEquals(1231234567892, foo(1231234567890, 1));
assertEquals(1231234567892, foo(1231234567890, 1));
%OptimizeFunctionOnNextCall(foo);
assertEquals(1231234567892, foo(1231234567890, 1));
assertOptimized(foo);
// Overflow the second add to ensure that we optimize with additive safe int add.
assertEquals(maxAdditiveSafeInteger + 1, foo(maxAdditiveSafeInteger - 1, 1));
assertUnoptimized(foo);
// Optimize again.
%OptimizeFunctionOnNextCall(foo);
assertEquals(1231234567892, foo(1231234567890, 1));
assertOptimized(foo);
// This time we don't overflow, since we use Float64Add.
assertEquals(maxAdditiveSafeInteger + 1, foo(maxAdditiveSafeInteger - 1, 1));
assertOptimized(foo);
// And we cannot deopt by overflowing the first one.
assertEquals(maxAdditiveSafeInteger + 2, foo(maxAdditiveSafeInteger, 1));
assertOptimized(foo);
// Don't deopt with doubles.
assertEquals(3.5, foo(1.5, 1));
assertOptimized(foo);
})();
// Don't need to deopt in overflow if we are truncating the result.
(function() {
function foo(a) {
return a + 1 | 0;
}
%PrepareFunctionForOptimization(foo);
assertEquals(1231234567891 | 0, foo(1231234567890, 1));
assertEquals(1231234567891 | 0, foo(1231234567890, 1));
%OptimizeFunctionOnNextCall(foo);
assertEquals(1231234567891 | 0, foo(1231234567890, 1));
assertOptimized(foo);
// We don't deopt in the maximum value.
assertEquals(maxAdditiveSafeInteger | 0, foo(maxAdditiveSafeInteger - 1));
assertOptimized(foo);
// Nor in the minimum.
assertEquals(minAdditiveSafeInteger + 1 | 0, foo(minAdditiveSafeInteger));
assertOptimized(foo);
// We don't deopt in overflow!
assertEquals(maxAdditiveSafeInteger + 1 | 0, foo(maxAdditiveSafeInteger));
assertOptimized(foo);
// Deopt with doubles.
assertEquals(2, foo(1.5));
assertUnoptimized(foo);
// Optimize again.
%OptimizeFunctionOnNextCall(foo);
assertEquals(1231234567891 | 0, foo(1231234567890, 1));
assertOptimized(foo);
// Don't deopt with doubles anymore.
assertEquals(2, foo(1.5, 1));
assertOptimized(foo);
})();

View File

@ -0,0 +1,120 @@
// Copyright 2013 the V8 project authors. All rights reserved.
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following
// disclaimer in the documentation and/or other materials provided
// with the distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// Flags: --allow-natives-syntax --nouse-osr --expose-gc
// Test loop barrier when folding allocations.
function f() {
var elem1 = [1,2,3];
for (var i=0; i < 100000; i++) {
var bar = [1];
}
var elem2 = [1,2,3];
return elem2;
}
%PrepareFunctionForOptimization(f);
f(); f(); f();
%OptimizeFunctionOnNextCall(f);
var result = f();
gc();
assertEquals(result[2], 3);
// Test allocation folding of doubles.
function doubles() {
var elem1 = [1.1, 1.2];
var elem2 = [2.1, 2.2];
return elem2;
}
%PrepareFunctionForOptimization(doubles);
doubles(); doubles(); doubles();
%OptimizeFunctionOnNextCall(doubles);
result = doubles();
gc();
assertEquals(result[1], 2.2);
// Test allocation folding of doubles into non-doubles.
function doubles_int() {
var elem1 = [2, 3];
var elem2 = [2.1, 3.1];
return elem2;
}
%PrepareFunctionForOptimization(doubles_int);
doubles_int(); doubles_int(); doubles_int();
%OptimizeFunctionOnNextCall(doubles_int);
result = doubles_int();
gc();
assertEquals(result[1], 3.1);
// Test allocation folding over a branch.
function branch_int(left) {
var elem1 = [1, 2];
var elem2;
if (left) {
elem2 = [3, 4];
} else {
elem2 = [5, 6];
}
return elem2;
}
%PrepareFunctionForOptimization(branch_int);
branch_int(1); branch_int(1); branch_int(1);
%OptimizeFunctionOnNextCall(branch_int);
result = branch_int(1);
var result2 = branch_int(0);
gc();
assertEquals(result[1], 4);
assertEquals(result2[1], 6);
// Test to almost exceed the Page::MaxRegularHeapObjectSize limit.
function boom() {
var a1 = new Array(84632);
var a2 = new Array(84632);
var a3 = new Array(84632);
return [ a1, a2, a3 ];
}
%PrepareFunctionForOptimization(boom);
boom(); boom(); boom();
%OptimizeFunctionOnNextCall(boom);
boom();

View File

@ -0,0 +1,579 @@
// Copyright 2012 the V8 project authors. All rights reserved.
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following
// disclaimer in the documentation and/or other materials provided
// with the distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// Flags: --allow-natives-syntax --expose-gc --turbofan --no-always-turbofan
var elements_kind = {
fast_smi_only : 'fast smi only elements',
fast : 'fast elements',
fast_double : 'fast double elements',
dictionary : 'dictionary elements',
external_byte : 'external byte elements',
external_unsigned_byte : 'external unsigned byte elements',
external_short : 'external short elements',
external_unsigned_short : 'external unsigned short elements',
external_int : 'external int elements',
external_unsigned_int : 'external unsigned int elements',
external_float : 'external float elements',
external_double : 'external double elements',
external_pixel : 'external pixel elements'
}
function getKind(obj) {
if (%HasSmiElements(obj)) return elements_kind.fast_smi_only;
if (%HasObjectElements(obj)) return elements_kind.fast;
if (%HasDoubleElements(obj)) return elements_kind.fast_double;
if (%HasDictionaryElements(obj)) return elements_kind.dictionary;
}
function isHoley(obj) {
if (%HasHoleyElements(obj)) return true;
return false;
}
function assertKind(expected, obj, name_opt) {
assertEquals(expected, getKind(obj), name_opt);
}
function assertHoley(obj, name_opt) {
assertEquals(true, isHoley(obj), name_opt);
}
function assertNotHoley(obj, name_opt) {
assertEquals(false, isHoley(obj), name_opt);
}
obj = [];
assertNotHoley(obj);
assertKind(elements_kind.fast_smi_only, obj);
obj = [1, 2, 3];
assertNotHoley(obj);
assertKind(elements_kind.fast_smi_only, obj);
obj = new Array();
assertNotHoley(obj);
assertKind(elements_kind.fast_smi_only, obj);
obj = new Array(0);
assertHoley(obj);
assertKind(elements_kind.fast_smi_only, obj);
obj = new Array(2);
assertHoley(obj);
assertKind(elements_kind.fast_smi_only, obj);
obj = new Array(1,2,3);
assertNotHoley(obj);
assertKind(elements_kind.fast_smi_only, obj);
obj = new Array(1, "hi", 2, undefined);
assertNotHoley(obj);
assertKind(elements_kind.fast, obj);
function fastliteralcase(literal, value) {
literal[0] = value;
return literal;
}
function get_standard_literal() {
var literal = [1, 2, 3];
return literal;
}
%PrepareFunctionForOptimization(get_standard_literal);
// Case: [1,2,3] as allocation site
obj = fastliteralcase(get_standard_literal(), 1);
assertKind(elements_kind.fast_smi_only, obj);
obj = fastliteralcase(get_standard_literal(), 1.5);
assertKind(elements_kind.fast_double, obj);
obj = fastliteralcase(get_standard_literal(), 2);
assertKind(elements_kind.fast_double, obj);
// The test below is in a loop because arrays that live
// at global scope without the chance of being recreated
// don't have allocation site information attached.
for (i = 0; i < 2; i++) {
obj = fastliteralcase([5, 3, 2], 1.5);
assertKind(elements_kind.fast_double, obj);
obj = fastliteralcase([3, 6, 2], 1.5);
assertKind(elements_kind.fast_double, obj);
// Note: thanks to pessimistic transition store stubs, we'll attempt
// to transition to the most general elements kind seen at a particular
// store site. So, the elements kind will be double.
obj = fastliteralcase([2, 6, 3], 2);
assertKind(elements_kind.fast_double, obj);
}
// Verify that we will not pretransition the double->fast path.
obj = fastliteralcase(get_standard_literal(), "elliot");
assertKind(elements_kind.fast, obj);
obj = fastliteralcase(get_standard_literal(), 3);
assertKind(elements_kind.fast, obj);
// Make sure this works in optimized code too.
%OptimizeFunctionOnNextCall(get_standard_literal);
get_standard_literal();
obj = get_standard_literal();
assertKind(elements_kind.fast, obj);
function fastliteralcase_smifast(value) {
var literal = [1, 2, 3, 4];
literal[0] = value;
return literal;
}
obj = fastliteralcase_smifast(1);
assertKind(elements_kind.fast_smi_only, obj);
obj = fastliteralcase_smifast("carter");
assertKind(elements_kind.fast, obj);
obj = fastliteralcase_smifast(2);
assertKind(elements_kind.fast, obj);
// Case: make sure transitions from packed to holey are tracked
function fastliteralcase_smiholey(index, value) {
var literal = [1, 2, 3, 4];
literal[index] = value;
return literal;
}
obj = fastliteralcase_smiholey(5, 1);
assertKind(elements_kind.fast_smi_only, obj);
assertHoley(obj);
obj = fastliteralcase_smiholey(0, 1);
assertKind(elements_kind.fast_smi_only, obj);
assertHoley(obj);
function newarraycase_smidouble(value) {
var a = new Array();
a[0] = value;
return a;
}
// Case: new Array() as allocation site, smi->double
obj = newarraycase_smidouble(1);
assertKind(elements_kind.fast_smi_only, obj);
obj = newarraycase_smidouble(1.5);
assertKind(elements_kind.fast_double, obj);
obj = newarraycase_smidouble(2);
assertKind(elements_kind.fast_double, obj);
function newarraycase_smiobj(value) {
var a = new Array();
a[0] = value;
return a;
}
// Case: new Array() as allocation site, smi->fast
obj = newarraycase_smiobj(1);
assertKind(elements_kind.fast_smi_only, obj);
obj = newarraycase_smiobj("gloria");
assertKind(elements_kind.fast, obj);
obj = newarraycase_smiobj(2);
assertKind(elements_kind.fast, obj);
function newarraycase_length_smidouble(value) {
var a = new Array(3);
a[0] = value;
return a;
}
// Case: new Array(length) as allocation site
obj = newarraycase_length_smidouble(1);
assertKind(elements_kind.fast_smi_only, obj);
obj = newarraycase_length_smidouble(1.5);
assertKind(elements_kind.fast_double, obj);
obj = newarraycase_length_smidouble(2);
assertKind(elements_kind.fast_double, obj);
// Try to continue the transition to fast object.
// TODO(mvstanton): re-enable commented out code when
// v8_flags.pretenuring_call_new is turned on in the build.
obj = newarraycase_length_smidouble("coates");
assertKind(elements_kind.fast, obj);
obj = newarraycase_length_smidouble(2);
// assertKind(elements_kind.fast, obj);
function newarraycase_length_smiobj(value) {
var a = new Array(3);
a[0] = value;
return a;
}
// Case: new Array(<length>) as allocation site, smi->fast
obj = newarraycase_length_smiobj(1);
assertKind(elements_kind.fast_smi_only, obj);
obj = newarraycase_length_smiobj("gloria");
assertKind(elements_kind.fast, obj);
obj = newarraycase_length_smiobj(2);
assertKind(elements_kind.fast, obj);
function newarraycase_list_smidouble(value) {
var a = new Array(1, 2, 3);
a[0] = value;
return a;
}
obj = newarraycase_list_smidouble(1);
assertKind(elements_kind.fast_smi_only, obj);
obj = newarraycase_list_smidouble(1.5);
assertKind(elements_kind.fast_double, obj);
obj = newarraycase_list_smidouble(2);
assertKind(elements_kind.fast_double, obj);
function newarraycase_list_smiobj(value) {
var a = new Array(4, 5, 6);
a[0] = value;
return a;
}
obj = newarraycase_list_smiobj(1);
assertKind(elements_kind.fast_smi_only, obj);
obj = newarraycase_list_smiobj("coates");
assertKind(elements_kind.fast, obj);
obj = newarraycase_list_smiobj(2);
assertKind(elements_kind.fast, obj);
// Perform a gc because without it the test below can experience an
// allocation failure at an inconvenient point. Allocation mementos get
// cleared on gc, and they can't deliver elements kind feedback when that
// happens.
gc();
// Case: array constructor calls with out of date feedback.
// The boilerplate should incorporate all feedback, but the input array
// should be minimally transitioned based on immediate need.
(function() {
function foo(i) {
// We have two cases, one for literals one for constructed arrays.
var a = (i == 0)
? [1, 2, 3]
: new Array(1, 2, 3);
return a;
}
for (var i = 0; i < 2; i++) {
a = foo(i);
b = foo(i);
b[5] = 1; // boilerplate goes holey
assertHoley(foo(i));
a[0] = 3.5; // boilerplate goes holey double
assertKind(elements_kind.fast_double, a);
assertNotHoley(a);
var c = foo(i);
assertKind(elements_kind.fast_double, c);
assertHoley(c);
}
})();
function newarraycase_onearg(len, value) {
var a = new Array(len);
a[0] = value;
return a;
}
obj = newarraycase_onearg(5, 3.5);
assertKind(elements_kind.fast_double, obj);
obj = newarraycase_onearg(10, 5);
assertKind(elements_kind.fast_double, obj);
obj = newarraycase_onearg(0, 5);
assertKind(elements_kind.fast_double, obj);
// Verify that cross context calls work
var realmA = Realm.current();
var realmB = Realm.create();
assertEquals(0, realmA);
assertEquals(1, realmB);
function instanceof_check(type) {
assertTrue(new type() instanceof type);
assertTrue(new type(5) instanceof type);
assertTrue(new type(1,2,3) instanceof type);
}
function instanceof_check2(type) {
assertTrue(new type() instanceof type);
assertTrue(new type(5) instanceof type);
assertTrue(new type(1,2,3) instanceof type);
}
%PrepareFunctionForOptimization(instanceof_check);
var realmBArray = Realm.eval(realmB, "Array");
// Two calls with Array because ES6 instanceof desugars into a load of Array,
// and load has a premonomorphic state.
instanceof_check(Array);
instanceof_check(Array);
instanceof_check(realmBArray);
// instanceof_check2 is here because the call site goes through a state.
// Since instanceof_check(Array) was first called with the current context
// Array function, it went from (uninit->Array) then (Array->megamorphic).
// We'll get a different state traversal if we start with realmBArray.
// It'll go (uninit->realmBArray) then (realmBArray->megamorphic). Recognize
// that state "Array" implies an AllocationSite is present, and code is
// configured to use it.
// Two calls with realmBArray because ES6 instanceof desugars into a load of
// realmBArray, and load has a premonomorphic state.
instanceof_check2(realmBArray);
instanceof_check2(realmBArray);
instanceof_check2(Array);
%OptimizeFunctionOnNextCall(instanceof_check);
// No de-opt will occur because HCallNewArray wasn't selected, on account of
// the call site not being monomorphic to Array.
instanceof_check(Array);
assertOptimized(instanceof_check);
instanceof_check(realmBArray);
assertOptimized(instanceof_check);
// Try to optimize again, but first clear all type feedback, and allow it
// to be monomorphic on first call. Only after optimizing do we introduce
// realmBArray. This should deopt the method.
%PrepareFunctionForOptimization(instanceof_check);
%DeoptimizeFunction(instanceof_check);
%ClearFunctionFeedback(instanceof_check);
instanceof_check(Array);
instanceof_check(Array);
%PrepareFunctionForOptimization(instanceof_check);
%OptimizeFunctionOnNextCall(instanceof_check);
instanceof_check(Array);
assertOptimized(instanceof_check);
instanceof_check(realmBArray);
assertUnoptimized(instanceof_check);
// Perform a gc because without it the test below can experience an
// allocation failure at an inconvenient point. Allocation mementos get
// cleared on gc, and they can't deliver elements kind feedback when that
// happens.
gc();
// Case: make sure nested arrays benefit from allocation site feedback as
// well.
(function() {
// Make sure we handle nested arrays
function get_nested_literal() {
var literal = [[1,2,3,4], [2], [3]];
return literal;
}
obj = get_nested_literal();
assertKind(elements_kind.fast, obj);
obj[0][0] = 3.5;
obj[2][0] = "hello";
obj = get_nested_literal();
assertKind(elements_kind.fast_double, obj[0]);
assertKind(elements_kind.fast_smi_only, obj[1]);
assertKind(elements_kind.fast, obj[2]);
// A more complex nested literal case.
function get_deep_nested_literal() {
var literal = [[1], [[2], "hello"], 3, [4]];
return literal;
}
obj = get_deep_nested_literal();
assertKind(elements_kind.fast_smi_only, obj[1][0]);
obj[0][0] = 3.5;
obj[1][0][0] = "goodbye";
assertKind(elements_kind.fast_double, obj[0]);
assertKind(elements_kind.fast, obj[1][0]);
obj = get_deep_nested_literal();
assertKind(elements_kind.fast_double, obj[0]);
assertKind(elements_kind.fast, obj[1][0]);
})();
// Perform a gc because without it the test below can experience an
// allocation failure at an inconvenient point. Allocation mementos get
// cleared on gc, and they can't deliver elements kind feedback when that
// happens.
gc();
// Make sure object literals with array fields benefit from the type feedback
// that allocation mementos provide.
(function() {
// A literal in an object
function get_object_literal() {
var literal = {
array: [1,2,3],
data: 3.5
};
return literal;
}
obj = get_object_literal();
assertKind(elements_kind.fast_smi_only, obj.array);
// Force double transition.
obj.array[1] = 3.5;
assertKind(elements_kind.fast_double, obj.array);
// Transition information should be fed back to the inner literal.
obj = get_object_literal();
assertKind(elements_kind.fast_double, obj.array);
function get_nested_object_literal() {
var literal = {
array: [[1],[2],[3]],
data: 3.5
};
return literal;
}
obj = get_nested_object_literal();
assertKind(elements_kind.fast, obj.array);
assertKind(elements_kind.fast_smi_only, obj.array[1]);
obj.array[1][0] = 3.5;
assertKind(elements_kind.fast_double, obj.array[1]);
obj = get_nested_object_literal();
assertKind(elements_kind.fast_double, obj.array[1]);
%OptimizeFunctionOnNextCall(get_nested_object_literal);
get_nested_object_literal();
obj = get_nested_object_literal();
assertKind(elements_kind.fast_double, obj.array[1]);
// Make sure we handle nested arrays
function get_nested_literal() {
var literal = [[1,2,3,4], [2], [3]];
return literal;
}
obj = get_nested_literal();
assertKind(elements_kind.fast, obj);
obj[0][0] = 3.5;
obj[2][0] = "hello";
obj = get_nested_literal();
assertKind(elements_kind.fast_double, obj[0]);
assertKind(elements_kind.fast_smi_only, obj[1]);
assertKind(elements_kind.fast, obj[2]);
// A more complex nested literal case.
function get_deep_nested_literal() {
var literal = [[1], [[2], "hello"], 3, [4]];
return literal;
}
obj = get_deep_nested_literal();
assertKind(elements_kind.fast_smi_only, obj[1][0]);
obj[0][0] = 3.5;
obj[1][0][0] = "goodbye";
assertKind(elements_kind.fast_double, obj[0]);
assertKind(elements_kind.fast, obj[1][0]);
obj = get_deep_nested_literal();
assertKind(elements_kind.fast_double, obj[0]);
assertKind(elements_kind.fast, obj[1][0]);
})();
// Test gathering allocation site feedback for generic ics.
(function() {
function make() { return new Array(); }
function foo(a, i) { a[0] = i; }
var a = make();
assertKind(elements_kind.fast_smi_only, a);
// Make the keyed store ic go generic.
foo("howdy", 1);
foo(a, 3.5);
var b = make();
assertKind(elements_kind.fast_double, b);
})();
(function TestBoilerplateMapDeprecation() {
function literal() {
return { a: 1, b: 2 };
}
literal();
literal();
let instance = literal();
assertKind(elements_kind.fast_smi_only, [instance.a, instance.b]);
// Create literal instances with double insteand of smi values.
for (let i = 0; i < 1000; i++) {
instance = literal();
instance.a = 1.2;
assertKind(elements_kind.fast_double, [instance.a, instance.b]);
}
// After deprecating the original boilerplate map we should get heap numbers
// back for the original unmodified literal as well.
for (let i =0; i < 100; i++) {
instance = literal();
assertKind(elements_kind.fast_double, [instance.a, instance.b]);
}
})();
(function TestInnerBoilerplateMapDeprecation() {
// Create a literal where the inner literals cause a map deprecation of the
// previous inner literal.
function literal() {
return [
{xA2A:false, a: 1, b: 2, c: 3, d: 4.1},
{xA2A:false, a: 1, b: 2, c: 3, d: 4.1},
{xA2A:false, a: 1, b: 2, c: 3, d: 4.1},
{xA2A:false, a: 1, b: 2, c: 3, d: 4.1},
{xA2A:false, a: 1.1, b: 2, c: 3, d: 4.1},
{xA2A:false, a: 1.1, b: 2, c: 3, d: 4.1},
{xA2A:false, a: 1.1, b: 2, c: 3, d: 4.1},
{xA2A:false, a: 1.1, b: 2, c: 3, d: 4.1},
{xA2A:false, a: 1.1, b: 2, c: 3, d: 4.1},
{xA2A:false, a: 1.1, b: 2, c: 3, d: 4.1},
{xA2A:false, a: 1.1, b: 2, c: 3, d: 4.1},
{xA2A:false, a: 1.1, b: 2, c: 3, d: 4.1},
{xA2A:false, a: 1.1, b: 2, c: 3, d: 4.1},
{xA2A:false, a: 1.1, b: 2, c: 3, d: 4.1}
];
};
let instance = literal();
// Make sure all sub-literals are migrated properly.
for (let i = 0; i < instance.length; i++) {
let sub_literal = instance[i];
assertKind(elements_kind.fast_double, [sub_literal.a]);
assertKind(elements_kind.fast_smi_only, [sub_literal.b]);
assertKind(elements_kind.fast_smi_only, [sub_literal.c]);
assertKind(elements_kind.fast_double, [sub_literal.d]);
}
instance = literal();
instance = literal();
instance = literal();
for (let i = 0; i < instance.length; i++) {
let sub_literal = instance[i];
assertKind(elements_kind.fast_double, [sub_literal.a]);
assertKind(elements_kind.fast_smi_only, [sub_literal.b]);
assertKind(elements_kind.fast_smi_only, [sub_literal.c]);
assertKind(elements_kind.fast_double, [sub_literal.d]);
}
})();

View File

@ -0,0 +1,39 @@
// Copyright 2008 the V8 project authors. All rights reserved.
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following
// disclaimer in the documentation and/or other materials provided
// with the distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// This is a test of making an API call after an exception thrown in JavaScript
// has been bypassed by a return in the finally block.
function foo() {
try {
throw "bar";
} finally {
return "baz";
}
}
foo();
print({});

View File

@ -0,0 +1,44 @@
// Copyright 2010 the V8 project authors. All rights reserved.
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following
// disclaimer in the documentation and/or other materials provided
// with the distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// Flags: --expose-gc
// Test that safepoint tables are correctly generated for apply with
// arguments in the case where arguments adaption is needed.
function f(x, y) {
if (x == 149999) gc();
return x + y;
}
function g() {
f.apply(this, arguments);
}
for (var i = 0; i < 150000; i++) {
g(i);
}

226
deps/v8/test/mjsunit/apply.js vendored Normal file
View File

@ -0,0 +1,226 @@
// Copyright 2008 the V8 project authors. All rights reserved.
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following
// disclaimer in the documentation and/or other materials provided
// with the distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// Flags: --allow-natives-syntax
function f0() {
return this;
}
function f1(a) {
return a;
}
assertSame(this, f0.apply(), "1-0");
assertSame(this, f0.apply(this), "2a");
assertSame(this, f0.apply(this, new Array(1)), "2b");
assertSame(this, f0.apply(this, new Array(2)), "2c");
assertSame(this, f0.apply(this, new Array(4242)), "2d");
assertSame(this, f0.apply(null), "3a");
assertSame(this, f0.apply(null, new Array(1)), "3b");
assertSame(this, f0.apply(null, new Array(2)), "3c");
assertSame(this, f0.apply(this, new Array(4242)), "3d");
assertSame(this, f0.apply(void 0), "4a");
assertSame(this, f0.apply(void 0, new Array(1)), "4b");
assertSame(this, f0.apply(void 0, new Array(2)), "4c");
assertEquals(void 0, f1.apply(), "1-1");
assertEquals(void 0, f1.apply(this), "5a");
assertEquals(void 0, f1.apply(this, new Array(1)), "5b");
assertEquals(void 0, f1.apply(this, new Array(2)), "5c");
assertEquals(void 0, f1.apply(this, new Array(4242)), "5d");
assertEquals(42, f1.apply(this, new Array(42, 43)), "5e");
assertEquals("foo", f1.apply(this, new Array("foo", "bar", "baz", "bo")), "5f");
assertEquals(void 0, f1.apply(null), "6a");
assertEquals(void 0, f1.apply(null, new Array(1)), "6b");
assertEquals(void 0, f1.apply(null, new Array(2)), "6c");
assertEquals(void 0, f1.apply(null, new Array(4242)), "6d");
assertEquals(42, f1.apply(null, new Array(42, 43)), "6e");
assertEquals("foo", f1.apply(null, new Array("foo", "bar", "baz", "bo")), "6f");
assertEquals(void 0, f1.apply(void 0), "7a");
assertEquals(void 0, f1.apply(void 0, new Array(1)), "7b");
assertEquals(void 0, f1.apply(void 0, new Array(2)), "7c");
assertEquals(void 0, f1.apply(void 0, new Array(4242)), "7d");
assertEquals(42, f1.apply(void 0, new Array(42, 43)), "7e");
assertEquals("foo", f1.apply(void 0, new Array("foo", "bar", "ba", "b")), "7f");
var arr = new Array(42, "foo", "fish", "horse");
function j(a, b, c, d, e, f, g, h, i, j, k, l) {
return "" + a + b + c + d + e + f + g + h + i + j + k + l;
}
var expect = "42foofishhorse";
for (var i = 0; i < 8; i++)
expect += "undefined";
assertEquals(expect, j.apply(undefined, arr), "apply to undefined");
assertThrows("f0.apply(this, 1);");
assertThrows("f0.apply(this, 1, 2);");
assertThrows("f0.apply(this, 1, new Array(2));");
function f() {
var doo = "";
for (var i = 0; i < arguments.length; i++) {
doo += arguments[i];
}
return doo;
}
assertEquals("42foofishhorse", f.apply(this, arr), "apply to this");
function s() {
var doo = this;
for (var i = 0; i < arguments.length; i++) {
doo += arguments[i];
}
return doo;
}
assertEquals("bar42foofishhorse", s.apply("bar", arr), "apply to string");
function al() {
print(this);
assertEquals(Object(345), this);
return arguments.length + arguments[arguments.length - 1];
}
for (var j = 1; j < 0x400000; j <<= 1) {
try {
var a = %NormalizeElements([]);
a.length = j;
a[j - 1] = 42;
assertEquals(42 + j, al.apply(345, a));
} catch (e) {
assertTrue(e.toString().indexOf("Maximum call stack size exceeded") != -1);
for (; j < 0x400000; j <<= 1) {
var caught = false;
try {
a = %NormalizeElements([]);
a.length = j;
a[j - 1] = 42;
al.apply(345, a);
assertUnreachable("Apply of array with length " + a.length +
" should have thrown");
} catch (e) {
assertTrue(e.toString().indexOf("Maximum call stack size exceeded") != -1);
caught = true;
}
assertTrue(caught, "exception not caught");
}
break;
}
}
// Check packed double arrays
var arr = [0.0];
for (var i = 1; i < 4; i++) {
arr.push(i * 0.1);
}
assertEquals(0.0, Math.min.apply(Math, arr));
assertEquals(0.30000000000000004, Math.max.apply(Math, arr));
// Check holey double arrays
var arr = Array(4);
for (var i = 0; i < 4; i++) {
arr[i] = i * 0.1;
}
assertEquals(0.0, Math.min.apply(Math, arr));
assertEquals(0.30000000000000004, Math.max.apply(Math, arr));
// Check that holes are set properly
arr[5] = 0.5;
assertEquals(NaN, Math.min.apply(Math, arr));
assertEquals(NaN, Math.max.apply(Math, arr));
var primes = new Array(0);
function isPrime(possible_prime) {
for (var d = 0; d < primes.length; d++) {
var p = primes[d];
if (possible_prime % p == 0)
return false;
if (p * p > possible_prime)
return true;
}
return true;
}
for (var i = 2; i < 10000; i++) {
if (isPrime(i)) {
primes.push(i);
}
}
assertEquals(1229, primes.length);
var same_primes = Array.prototype.constructor.apply(Array, primes);
for (var i = 0; i < primes.length; i++)
assertEquals(primes[i], same_primes[i], "prime" + primes[i]);
assertEquals(primes.length, same_primes.length, "prime-length");
Array.prototype["1"] = "sep";
var holey = new Array(3);
holey[0] = "mor";
holey[2] = "er";
assertEquals("morseper", String.prototype.concat.apply("", holey),
"moreseper0");
assertEquals("morseper", String.prototype.concat.apply("", holey, 1),
"moreseper1");
assertEquals("morseper", String.prototype.concat.apply("", holey, 1, 2),
"moreseper2");
assertEquals("morseper", String.prototype.concat.apply("", holey, 1, 2, 3),
"morseper3");
assertEquals("morseper", String.prototype.concat.apply("", holey, 1, 2, 3, 4),
"morseper4");
primes[0] = "";
primes[1] = holey;
assertThrows("String.prototype.concat.apply.apply('foo', primes)");
assertEquals("morseper",
String.prototype.concat.apply.apply(String.prototype.concat, primes),
"moreseper-prime");
delete(Array.prototype["1"]);
// Check correct handling of non-array argument lists.
assertSame(this, f0.apply(this, {}), "non-array-1");
assertSame(this, f0.apply(this, { length:1 }), "non-array-2");
assertEquals(void 0, f1.apply(this, { length:1 }), "non-array-3");
assertEquals(void 0, f1.apply(this, { 0:"foo" }), "non-array-4");
assertEquals("foo", f1.apply(this, { length:1, 0:"foo" }), "non-array-5");

View File

@ -0,0 +1,133 @@
// Copyright 2011 the V8 project authors. All rights reserved.
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following
// disclaimer in the documentation and/or other materials provided
// with the distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
(function() {
function f(x) {
var arguments = [ 1, 2, 3 ];
return x;
}
assertEquals(7, f(7));
})();
(function() {
function f(x) {
arguments[0] = 991;
var arguments = [ 1, 2, 3 ];
return x;
}
assertEquals(991, f(7));
})();
(function() {
function f(x) {
arguments[0] = 991;
for (var i = 0; i < 10; i++) {
if (i == 5) {
var arguments = [ 1, 2, 3 ];
}
}
return x;
}
assertEquals(991, f(7));
})();
(function() {
function f(x, s) {
eval(s);
return x;
}
assertEquals(7, f(7, "var arguments = [ 1, 2, 3 ];"));
})();
(function() {
function f(x, s) {
var tmp = arguments[0];
eval(s);
return tmp;
}
assertEquals(7, f(7, "var arguments = [ 1, 2, 3 ];"));
})();
(function() {
function f(x, s) {
var tmp = arguments[0];
eval(s);
return tmp;
}
assertEquals(7, f(7, ""));
})();
(function() {
function f(x, s) {
var tmp = arguments[0];
eval(s);
return x;
}
assertEquals(7, f(7, "var arguments = [ 1, 2, 3 ];"));
})();
(function() {
function f(x, s) {
var tmp = arguments[0];
eval(s);
return x;
}
assertEquals(7, f(7, ""));
})();
(function() {
function f(x) {
function g(y) {
x = y;
}
arguments = {};
g(991);
return x;
}
assertEquals(991, f(7));
})();
(function() {
function f(x) {
function g(y, s) {
eval(s);
}
arguments = {};
g(991, "x = y;");
return x;
}
assertEquals(991, f(7));
})();

View File

@ -0,0 +1,67 @@
// Copyright 2011 the V8 project authors. All rights reserved.
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following
// disclaimer in the documentation and/or other materials provided
// with the distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// Tests to verify proper arguments handling if the arguments
// variable is declared as a parameter or local variable.
function e(a) {
assertEquals(9, a.length);
assertEquals("arguments", a);
};
e("arguments");
function f(arguments) {
assertEquals(9, arguments.length);
assertEquals("arguments", arguments);
};
f("arguments");
function g(x) {
var arguments;
assertEquals("arguments", x);
assertEquals(1, arguments.length);
assertEquals("[object Arguments]", '' + arguments);
};
g("arguments");
function h(x) {
assertEquals("arguments", x);
assertEquals(1, arguments.length);
assertEquals("[object Arguments]", '' + arguments);
var arguments = "foobar";
assertEquals("arguments", x);
assertEquals(6, arguments.length);
assertEquals("foobar", '' + arguments);
};
h("arguments");

View File

@ -0,0 +1,79 @@
// Copyright 2012 the V8 project authors. All rights reserved.
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following
// disclaimer in the documentation and/or other materials provided
// with the distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// Flags: --allow-natives-syntax
(function ApplyArgumentsDeoptInReceiverMapCheck() {
function invoker(h, r) {
return function XXXXX() {
var res = h.apply({ fffffff : r(this) }, arguments);
return res;
};
}
var y = invoker(m, selfOf);
%PrepareFunctionForOptimization(y);
function selfOf(c) {
var sssss = c.self_;
return sssss;
}
function m() {
return this.fffffff;
}
y.apply({ self_ : 3 });
y.apply({ self_ : 3 });
y.apply({ self_ : 3 });
%OptimizeFunctionOnNextCall(y);
assertEquals(y.apply({ self_ : 3, uuu : 4 }), 3);
})();
(function ApplyArgumentsDeoptInReceiverExplicit() {
function f() { return this + 21; }
function deopt() {
%DeoptimizeFunction(XXXXX);
return 21;
}
function XXXXX() {
return f.apply(deopt(), arguments);
};
%PrepareFunctionForOptimization(XXXXX);
XXXXX();
XXXXX();
XXXXX();
%OptimizeFunctionOnNextCall(XXXXX);
assertEquals(42, XXXXX());
})();

134
deps/v8/test/mjsunit/arguments-apply.js vendored Normal file
View File

@ -0,0 +1,134 @@
// Copyright 2009 the V8 project authors. All rights reserved.
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following
// disclaimer in the documentation and/or other materials provided
// with the distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
function ReturnArguments() {
return arguments;
}
function ReturnReceiver() {
return this;
}
function Global() {
return ReturnArguments.apply(this, arguments);
}
assertEquals(0, Global().length);
assertEquals(1, Global(1).length);
assertEquals(2, Global(2)[0]);
assertEquals(2, Global(3, 4).length);
assertEquals(3, Global(3, 4)[0]);
assertEquals(4, Global(3, 4)[1]);
function Local() {
var object = { f: ReturnArguments };
return object.f.apply(this, arguments);
}
assertEquals(0, Local().length);
assertEquals(1, Local(1).length);
assertEquals(2, Local(2)[0]);
assertEquals(2, Local(3, 4).length);
assertEquals(3, Local(3, 4)[0]);
assertEquals(4, Local(3, 4)[1]);
function ShadowArguments() {
var arguments = [3, 4];
return ReturnArguments.apply(this, arguments);
}
assertEquals(2, ShadowArguments().length);
assertEquals(3, ShadowArguments()[0]);
assertEquals(4, ShadowArguments()[1]);
function NonObjectReceiver(receiver) {
return ReturnReceiver.apply(receiver, arguments);
}
assertEquals(Object(42), NonObjectReceiver(42));
assertEquals("object", typeof NonObjectReceiver(42));
assertInstanceof(NonObjectReceiver(42), Number);
assertSame(this, NonObjectReceiver(null));
assertSame(this, NonObjectReceiver(void 0));
function FunctionReceiver() {
return ReturnReceiver.apply(Object, arguments);
}
assertTrue(Object === FunctionReceiver());
function ShadowApply() {
function f() { return 42; }
f.apply = function() { return 87; }
return f.apply(this, arguments);
}
assertEquals(87, ShadowApply());
assertEquals(87, ShadowApply(1));
assertEquals(87, ShadowApply(1, 2));
function CallNonFunction() {
var object = { apply: Function.prototype.apply };
return object.apply(this, arguments);
}
assertThrows(CallNonFunction, TypeError);
// Make sure that the stack after the apply optimization is
// in a valid state.
function SimpleStackCheck() {
var sentinel = 42;
var result = ReturnArguments.apply(this, arguments);
assertTrue(result != null);
assertEquals(42, sentinel);
}
SimpleStackCheck();
function ShadowArgumentsWithConstant() {
var arguments = null;
return ReturnArguments.apply(this, arguments);
}
assertEquals(0, ShadowArgumentsWithConstant().length);
assertEquals(0, ShadowArgumentsWithConstant(1).length);
assertEquals(0, ShadowArgumentsWithConstant(1, 2).length);
// Make sure we can deal with unfolding lots of arguments on the
// stack even in the presence of the apply optimizations.
var array = new Array(2048);
assertEquals(2048, Global.apply(this, array).length);

View File

@ -0,0 +1,41 @@
// Copyright 2008 the V8 project authors. All rights reserved.
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following
// disclaimer in the documentation and/or other materials provided
// with the distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
function sum(a, b, c) {
var result = 0;
for (var i = 0; i < arguments.length; i++) {
result += arguments[i];
}
return result;
}
// Try invoking call before sum has been compiled lazily.
assertEquals(6, sum.call(this, 1, 2, 3), "lazy call");
assertEquals(6, sum(1, 2, 3), "normal");
assertEquals(6, sum.call(this, 1, 2, 3), "call");
assertEquals(6, sum.apply(this, [1, 2, 3]), "apply");

201
deps/v8/test/mjsunit/arguments-deopt.js vendored Normal file
View File

@ -0,0 +1,201 @@
// Copyright 2017 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Flags: --allow-natives-syntax
(function MaterializeStrictArguments() {
"use strict"
function f(x, y) {
return x + y;
}
function test1() {
%DeoptimizeNow();
return f.apply(null, arguments);
}
%PrepareFunctionForOptimization(test1);
assertEquals(test1(1, 2), 3);
assertEquals(test1(1, 2, 3), 3);
%OptimizeFunctionOnNextCall(test1);
assertEquals(test1(1, 2), 3);
%PrepareFunctionForOptimization(test1);
%OptimizeFunctionOnNextCall(test1);
assertEquals(test1(1, 2, 3), 3);
})();
(function MaterializeSloppyArguments() {
function f(x, y) {
return x + y;
}
function test2() {
%DeoptimizeNow();
return f.apply(null, arguments);
}
%PrepareFunctionForOptimization(test2);
assertEquals(test2(1, 2), 3);
assertEquals(test2(1, 2, 3), 3);
%OptimizeFunctionOnNextCall(test2);
assertEquals(test2(1, 2), 3);
%PrepareFunctionForOptimization(test2);
%OptimizeFunctionOnNextCall(test2);
assertEquals(test2(1, 2, 3), 3);
})();
(function MaterializeStrictOverwrittenArguments() {
"use strict"
function f(x, y) {
return x + y;
}
function test3(a, b) {
a = 4;
%DeoptimizeNow();
return f.apply(null, arguments);
}
%PrepareFunctionForOptimization(test3);
assertEquals(test3(1, 2), 3);
assertEquals(test3(1, 2, 3), 3);
%OptimizeFunctionOnNextCall(test3);
assertEquals(test3(11, 12), 23);
%PrepareFunctionForOptimization(test3);
%OptimizeFunctionOnNextCall(test3);
assertEquals(test3(11, 12, 13), 23);
})();
(function MaterializeSloppyOverwrittenArguments() {
function f(x, y) {
return x + y;
}
function test4(a, b) {
a = 4;
%DeoptimizeNow();
return f.apply(null, arguments);
}
test4(1, 2);
test4(3, 4, 5);
%PrepareFunctionForOptimization(test4);
assertEquals(test4(1, 2), 6);
assertEquals(test4(1, 2, 3), 6);
%OptimizeFunctionOnNextCall(test4);
assertEquals(test4(1, 2), 6);
%PrepareFunctionForOptimization(test4);
%OptimizeFunctionOnNextCall(test4);
assertEquals(test4(1, 2, 3), 6);
})();
(function ArgumentsAccessStrict () {
"use strict"
function sum1(a,b,c) {
var sum = 0;
var rest = arguments;
for (var i = 0; i < rest.length; ++i) {
var j = i;
if (rest.length % 15 == 0 && i == 10) j += 10000;
sum += rest[j] || i+1;
}
return sum;
};
%PrepareFunctionForOptimization(sum1);
var args = []
for (var i = 1; i < 30; ++i) {
args.push(i);
if (i%10 == 0) %OptimizeFunctionOnNextCall(sum1);
assertEquals(i*(i+1)/2, sum1(...args));
if (i%10 == 0) %PrepareFunctionForOptimization(sum1);
}
})();
(function ArgumentsAccessSloppy () {
function sum2(a,b,c) {
var sum = 0;
for (var i = 0; i < arguments.length; ++i) {
var j = i;
if (arguments.length % 15 == 0 && i == 10) j += 10000;
sum += arguments[j] || i+1;
}
return sum;
};
%PrepareFunctionForOptimization(sum2);
var args = []
for (var i = 1; i < 30; ++i) {
args.push(i);
if (i%10 == 0) %OptimizeFunctionOnNextCall(sum2);
assertEquals(i*(i+1)/2, sum2(...args));
if (i%10 == 0) %PrepareFunctionForOptimization(sum2);
}
})();
(function RestAccess0 () {
function sum3(...rest) {
var sum = 0;
for (var i = 0; i < rest.length; ++i) {
var j = i;
if (rest.length % 15 == 0 && i == 10) j += 10000;
sum += rest[j] || i+1;
}
return sum;
};
%PrepareFunctionForOptimization(sum3);
var args = []
for (var i = 1; i < 30; ++i) {
args.push(i);
if (i%10 == 0) %OptimizeFunctionOnNextCall(sum3);
assertEquals(i*(i+1)/2, sum3(...args));
if (i%10 == 0) %PrepareFunctionForOptimization(sum3);
}
})();
(function RestAccess1 () {
function sum4(a,...rest) {
var sum = 0;
for (var i = 0; i < rest.length; ++i) {
var j = i;
if (rest.length % 15 == 0 && i == 10) j += 10000;
sum += rest[j] || i+2;
}
return sum;
};
%PrepareFunctionForOptimization(sum4);
var args = []
for (var i = 1; i < 30; ++i) {
args.push(i);
if (i%10 == 0) %OptimizeFunctionOnNextCall(sum4);
assertEquals(i*(i+1)/2-1, sum4(...args));
if (i%10 == 0) %PrepareFunctionForOptimization(sum4);
}
})();
(function ReadArguments () {
function read() {
if (arguments.length % 10 == 5) %DeoptimizeNow();
return arguments[arguments.length-1];
};
%PrepareFunctionForOptimization(read);
var args = []
for (var i = 1; i < 30; ++i) {
args.push(i);
if (i%10 == 0) %OptimizeFunctionOnNextCall(read);
assertEquals(i, read(...args));
if (i%10 == 0) %PrepareFunctionForOptimization(read);
}
})();

52
deps/v8/test/mjsunit/arguments-enum.js vendored Normal file
View File

@ -0,0 +1,52 @@
// Copyright 2008 the V8 project authors. All rights reserved.
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following
// disclaimer in the documentation and/or other materials provided
// with the distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
function countArguments() {
var count = 0;
for (var prop in arguments)
count++;
return count;
}
function setArgumentCount() {
arguments[10] = 5;
arguments.x = 4;
var count = 0;
for (var prop in arguments)
count++;
return count;
}
assertEquals(0, countArguments());
assertEquals(1, countArguments(1));
assertEquals(2, countArguments(1, 2));
assertEquals(5, countArguments(1, 2, 3, 4, 5));
assertEquals(2, setArgumentCount());
assertEquals(3, setArgumentCount(1));
assertEquals(4, setArgumentCount(1, 2));
assertEquals(7, setArgumentCount(1, 2, 3, 4, 5));

View File

@ -0,0 +1,59 @@
// Copyright 2011 the V8 project authors. All rights reserved.
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following
// disclaimer in the documentation and/or other materials provided
// with the distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
function foo(x) {
var a = arguments;
function bar(i) {
assertEquals(i, ++a[0]);
assertEquals(i, x);
};
bar(1);
bar(2);
bar(3);
return bar;
}
var baz = foo(0);
baz(4);
baz(5);
baz(6);
// Test writing a non-smi.
function foo2(x) {
var a = arguments;
function bar2(i) {
assertEquals(i, ++a[0]);
assertEquals(i, x);
};
bar2(1.5);
bar2(2.5);
bar2(3.5);
return bar2;
}
var baz2 = foo2(0.5);
baz2(4.5);
baz2(5.5);
baz2(6.5);

View File

@ -0,0 +1,55 @@
// Copyright 2008 the V8 project authors. All rights reserved.
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following
// disclaimer in the documentation and/or other materials provided
// with the distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
function f1() {
g(f1);
}
function f2(x) {
var a = arguments;
x++;
g(f2);
}
function f3(x) {
var a = arguments;
(function() { x++ })();
g(f3);
}
function g(f) {
assertEquals("object", typeof f.arguments);
assertFalse(f.arguments === f.arguments);
assertEquals(3, f.arguments.length);
assertEquals(1, f.arguments[0]);
assertEquals(2, f.arguments[1]);
assertEquals(3, f.arguments[2]);
}
f1(1,2,3);
f2(1,2,3);
f3(1,2,3);

47
deps/v8/test/mjsunit/arguments-lazy.js vendored Normal file
View File

@ -0,0 +1,47 @@
// Copyright 2009 the V8 project authors. All rights reserved.
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following
// disclaimer in the documentation and/or other materials provided
// with the distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// Make sure we don't allocate the arguments object over and
// over again.
function SharedLazyArguments() {
return arguments === arguments;
}
assertTrue(SharedLazyArguments());
// Make sure that accessing arguments doesn't clobber any
// local variables called arguments.
function ArgumentsOverride(x) {
var arguments = 42;
x = x ? x : 0;
return x + arguments;
}
assertEquals(42, ArgumentsOverride());
assertEquals(43, ArgumentsOverride(1));
assertEquals(44, ArgumentsOverride(2,3));

View File

@ -0,0 +1,84 @@
// Copyright 2010 the V8 project authors. All rights reserved.
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following
// disclaimer in the documentation and/or other materials provided
// with the distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// Tests loading of arguments across eval calls.
// Test loading across an eval call that does not shadow variables.
function testNoShadowing(x, h) {
function f() {
eval('1');
assertEquals(1, x);
assertEquals(2, h());
function g() {
assertEquals(1, x);
assertEquals(2, h());
}
g();
}
f();
}
testNoShadowing(1, function() { return 2; });
// Test loading across eval calls that do not shadow variables.
function testNoShadowing2(x, h) {
eval('1');
function f() {
eval('1');
assertEquals(1, x);
assertEquals(2, h());
function g() {
assertEquals(1, x);
assertEquals(2, h());
}
g();
}
f();
}
testNoShadowing2(1, function() { return 2; });
// Test loading across an eval call that shadows variables.
function testShadowing(x, h) {
function f() {
assertEquals(1, x);
assertEquals(2, h());
eval('var x = 3; var h = function() { return 4; };');
assertEquals(3, x);
assertEquals(4, h());
function g() {
assertEquals(3, x);
assertEquals(4, h());
}
g();
}
f();
assertEquals(1, x);
assertEquals(2, h());
}
testShadowing(1, function() { return 2; });

View File

@ -0,0 +1,164 @@
// Copyright 2009 the V8 project authors. All rights reserved.
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following
// disclaimer in the documentation and/or other materials provided
// with the distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// Testing basic functionality of the arguments object.
// Introduced to ensure that the fast compiler does the right thing.
// The arguments object itself.
assertEquals(42, function(){ return arguments;}(42)[0],
"return arguments value");
assertEquals(42, function(){ return arguments;}(42)[0],
"arguments in plain value context");
assertEquals(42, function(){ arguments;return 42}(37),
"arguments in effect context");
assertEquals(42, function(){ if(arguments)return 42;}(),
"arguments in a boolean context");
assertEquals(42, function(){ return arguments || true;}(42)[0],
"arguments in a short-circuit boolean context - or");
assertEquals(true, function(){ return arguments && [true];}(42)[0],
"arguments in a short-circuit boolean context - and");
assertEquals(42, function(){ arguments = 42; return 42;}(),
"arguments assignment");
// Properties of the arguments object.
assertEquals(42, function(){ return arguments[0]; }(42),
"args[0] value returned");
assertEquals(42, function(){ arguments[0]; return 42}(),
"args[0] value ignored");
assertEquals(42, function(){ if (arguments[0]) return 42; }(37),
"args[0] to boolean");
assertEquals(42, function(){ return arguments[0] || "no"; }(42),
"args[0] short-circuit boolean or true");
assertEquals(42, function(){ return arguments[0] || 42; }(0),
"args[0] short-circuit boolean or false");
assertEquals(37, function(){ return arguments[0] && 37; }(42),
"args[0] short-circuit boolean and true");
assertEquals(0, function(){ return arguments[0] && 42; }(0),
"args[0] short-circuit boolean and false");
assertEquals(42, function(){ arguments[0] = 42; return arguments[0]; }(37),
"args[0] assignment");
// Link between arguments and parameters.
assertEquals(42, function(a) { arguments[0] = 42; return a; }(37),
"assign args[0]->a");
assertEquals(42, function(a) { a = 42; return arguments[0]; }(37),
"assign a->args[0]");
assertEquals(54, function(a, b) { arguments[1] = 54; return b; }(42, 37),
"assign args[1]->b:b");
assertEquals(54, function(a, b) { b = 54; return arguments[1]; }(42, 47),
"assign b->args[1]:b");
assertEquals(42, function(a, b) { arguments[1] = 54; return a; }(42, 37),
"assign args[1]->b:a");
assertEquals(42, function(a, b) { b = 54; return arguments[0]; }(42, 47),
"assign b->args[1]:a");
// Capture parameters in nested contexts.
assertEquals(33,
function(a,b) {
return a + arguments[0] +
function(b){ return a + b + arguments[0]; }(b); }(7,6),
"captured parameters");
assertEquals(42, function(a) {
arguments[0] = 42;
return function(b){ return a; }();
}(37),
"capture value returned");
assertEquals(42,
function(a) {
arguments[0] = 26;
return function(b){ a; return 42; }();
}(37),
"capture value ignored");
assertEquals(42,
function(a) {
arguments[0] = 26;
return function(b){ if (a) return 42; }();
}(37),
"capture to boolean");
assertEquals(42,
function(a) {
arguments[0] = 42;
return function(b){ return a || "no"; }();
}(37),
"capture short-circuit boolean or true");
assertEquals(0,
function(a) {
arguments[0] = 0;
return function(b){ return a && 42; }();
}(37),
"capture short-circuit boolean and false");
// Deeply nested.
assertEquals(42,
function(a,b) {
return arguments[2] +
function(){
return b +
function() {
return a;
}();
}();
}(7,14,21),
"deep nested capture");
// Assignment to captured parameters.
assertEquals(42, function(a,b) {
arguments[1] = 11;
return a + function(){ a = b; return a; }() + a;
}(20, 37), "captured assignment");
// Inside non-function scopes.
assertEquals(42,
function(a) {
arguments[0] = 20;
with ({ b : 22 }) { return a + b; }
}(37),
"a in with");
assertEquals(42,
function(a) {
with ({ b : 22 }) { return arguments[0] + b; }
}(20),
"args in with");
assertEquals(42,
function(a) {
arguments[0] = 20;
with ({ b : 22 }) {
return function() { return a; }() + b; }
}(37),
"captured a in with");
assertEquals(42,
function(a) {
arguments[0] = 12;
with ({ b : 22 }) {
return function f() {
try { throw 8 } catch(e) { return e + a };
}() + b;
}
}(37),
"in a catch in a named function captured a in with ");
// Escaping arguments.
function weirdargs(a,b,c) { if (!a) return arguments;
return [b[2],c]; }
var args1 = weirdargs(false, null, 40);
var res = weirdargs(true, args1, 15);
assertEquals(40, res[0], "return old args element");
assertEquals(15, res[1], "return own args element");

379
deps/v8/test/mjsunit/arguments.js vendored Normal file
View File

@ -0,0 +1,379 @@
// Copyright 2011 the V8 project authors. All rights reserved.
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following
// disclaimer in the documentation and/or other materials provided
// with the distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// Flags: --allow-natives-syntax
function argc0() {
return arguments.length;
}
function argc1(i) {
return arguments.length;
}
function argc2(i, j) {
return arguments.length;
}
assertEquals(0, argc0());
assertEquals(1, argc0(1));
assertEquals(2, argc0(1, 2));
assertEquals(3, argc0(1, 2, 3));
assertEquals(0, argc1());
assertEquals(1, argc1(1));
assertEquals(2, argc1(1, 2));
assertEquals(3, argc1(1, 2, 3));
assertEquals(0, argc2());
assertEquals(1, argc2(1));
assertEquals(2, argc2(1, 2));
assertEquals(3, argc2(1, 2, 3));
var index;
function argv0() {
return arguments[index];
}
function argv1(i) {
return arguments[index];
}
function argv2(i, j) {
return arguments[index];
}
index = 0;
assertEquals(7, argv0(7));
assertEquals(7, argv0(7, 8));
assertEquals(7, argv0(7, 8, 9));
assertEquals(7, argv1(7));
assertEquals(7, argv1(7, 8));
assertEquals(7, argv1(7, 8, 9));
assertEquals(7, argv2(7));
assertEquals(7, argv2(7, 8));
assertEquals(7, argv2(7, 8, 9));
index = 1;
assertEquals(8, argv0(7, 8));
assertEquals(8, argv0(7, 8));
assertEquals(8, argv1(7, 8, 9));
assertEquals(8, argv1(7, 8, 9));
assertEquals(8, argv2(7, 8, 9));
assertEquals(8, argv2(7, 8, 9));
index = 2;
assertEquals(9, argv0(7, 8, 9));
assertEquals(9, argv1(7, 8, 9));
assertEquals(9, argv2(7, 8, 9));
// Test that calling a lazily compiled function with
// an unexpected number of arguments works.
function f(a) { return arguments.length; };
assertEquals(3, f(1, 2, 3));
function f1(x, y) {
function g(a) {
a[0] = "three";
return a.length;
}
var l = g(arguments);
y = 5;
assertEquals(2, l);
assertEquals("three", x);
assertEquals(5, y);
}
f1(3, "five");
function f2() {
if (arguments[0] > 0) {
return arguments.callee(arguments[0] - 1) + arguments[0];
}
return 0;
}
assertEquals(55, f2(10));
function f3() {
assertEquals(0, arguments.length);
}
f3();
function f4() {
var arguments = 0;
assertEquals(void 0, arguments.length);
}
f4();
function f5(x, y, z) {
function g(a) {
x = "two";
y = "three";
a[1] = "drei";
a[2] = "fuenf";
};
g(arguments);
assertEquals("two", x);
assertEquals("drei", y);
assertEquals("fuenf", z);
}
f5(2, 3, 5);
function f6(x, y) {
x = "x";
arguments[1] = "y";
return [arguments.length, arguments[0], y, arguments[2]];
}
assertArrayEquals([0, void 0, void 0, void 0], f6());
assertArrayEquals([1, "x", void 0, void 0], f6(1));
assertArrayEquals([2, "x", "y", void 0], f6(9, 17));
assertArrayEquals([3, "x", "y", 7], f6(3, 5, 7));
assertArrayEquals([4, "x", "y", "c"], f6("a", "b", "c", "d"));
function list_args(a) {
assertEquals("function", typeof a.callee);
var result = [];
result.push(a.length);
for (i = 0; i < a.length; i++) result.push(a[i]);
return result;
}
function f7(x, y) {
function g(p) {
x = p;
}
g(y);
return list_args(arguments);
}
assertArrayEquals([0], f7());
assertArrayEquals([1, void 0], f7(3));
assertArrayEquals([2, 5, 5], f7(3, 5));
assertArrayEquals([3, 5, 5, 7], f7(3, 5, 7));
// Check out of bounds behavior.
function arg_get(x) { return arguments[x]; }
function arg_del(x) { return delete arguments[x]; }
function arg_set(x) { return (arguments[x] = 117); }
assertEquals(undefined, arg_get(0xFFFFFFFF));
assertEquals(true, arg_del(0xFFFFFFFF));
assertEquals(117, arg_set(0xFFFFFFFF));
(function() {
function f(a) { return arguments; }
var a = f(1,2,3);
// Turn arguments into slow.
assertTrue(%HasSloppyArgumentsElements(a));
a[10000] = 1;
assertTrue(%HasSloppyArgumentsElements(a));
// Make it fast again by adding values.
for (var i = 0; i < 1000; i++) {
a[i] = 1.5;
}
assertTrue(%HasSloppyArgumentsElements(a));
})();
(function testDeleteArguments() {
function f() { return arguments };
var args = f(1, 2);
assertEquals(1, args[0]);
assertEquals(2, args[1]);
assertEquals(2, args.length);
delete args[0];
assertEquals(undefined, args[0]);
assertEquals(2, args[1]);
assertEquals(2, args.length);
delete args[1];
assertEquals(undefined, args[0]);
assertEquals(undefined, args[1]);
assertEquals(2, args.length);
})();
(function testDeleteFastSloppyArguments() {
function f(a) { return arguments };
var args = f(1, 2);
assertEquals(1, args[0]);
assertEquals(2, args[1]);
assertEquals(2, args.length);
delete args[0];
assertEquals(undefined, args[0]);
assertEquals(2, args[1]);
assertEquals(2, args.length);
delete args[1];
assertEquals(undefined, args[0]);
assertEquals(undefined, args[1]);
assertEquals(2, args.length);
})();
(function testDeleteSlowSloppyArguments() {
var key = 10000;
function f(a) {
arguments[key] = key;
return arguments
};
var args = f(1, 2);
%HeapObjectVerify(args);
assertEquals(1, args[0]);
assertEquals(2, args[1]);
assertEquals(key, args[key]);
assertEquals(2, args.length);
delete args[0];
%HeapObjectVerify(args);
assertEquals(undefined, args[0]);
assertEquals(2, args[1]);
assertEquals(key, args[key]);
assertEquals(2, args.length);
delete args[1];
%HeapObjectVerify(args);
assertEquals(undefined, args[0]);
assertEquals(undefined, args[1]);
assertEquals(key, args[key]);
assertEquals(2, args.length);
delete args[key];
%HeapObjectVerify(args);
assertEquals(undefined, args[0]);
assertEquals(undefined, args[1]);
assertEquals(undefined, args[key]);
assertEquals(2, args.length);
})();
(function testDeleteSlowSloppyArguments2() {
function f(a) {
return arguments
};
var args = f(1, 2);
%HeapObjectVerify(args);
assertEquals(1, args[0]);
assertEquals(2, args[1]);
assertEquals(2, args.length);
delete args[1];
%HeapObjectVerify(args);
assertEquals(1, args[0]);
assertEquals(undefined, args[1]);
assertEquals(undefined, args[2]);
assertEquals(2, args.length);
delete args[0];
%HeapObjectVerify(args);
assertEquals(undefined, args[0]);
assertEquals(undefined, args[1]);
assertEquals(undefined, args[2]);
assertEquals(2, args.length);
})();
(function testSloppyArgumentProperties() {
function f(a, b) { return arguments }
let args = f(1, 2, 3, 4);
%HeapObjectVerify(args);
assertEquals(4, args.length);
args.foo = "foo";
%HeapObjectVerify(args);
assertEquals("foo", args.foo);
assertEquals(4, args.length);
delete args.foo;
%HeapObjectVerify(args);
assertEquals(undefined, args.foo);
assertEquals(4, args.length);
})();
(function testSloppyArgumentsLengthMapChange() {
function f(a) { return arguments };
let args1 = f(1);
let args2 = f(1,2);
assertTrue(%HaveSameMap(args1, args2));
args2.length = 12;
assertTrue(%HaveSameMap(args1, args2));
args2.length = "aa"
assertTrue(%HaveSameMap(args1, args2));
let args3 = f(1);
let args4 = f(1,2);
// Creating holes causes map transitions.
assertTrue(%HaveSameMap(args1, args3));
assertTrue(%HaveSameMap(args1, args4));
delete args3[0];
assertFalse(%HaveSameMap(args1, args3));
delete args4[1];
assertFalse(%HaveSameMap(args1, args4));
})();
(function testSloppyArgumentsLengthMapChange() {
function f(a) { return arguments };
let args1 = f(1);
let args2 = f(1,2);
assertTrue(%HaveSameMap(args1, args2));
// Changing the length type doesn't causes a map transition.
args2.length = 12;
assertTrue(%HaveSameMap(args1, args2));
args2.length = 12.0;
assertTrue(%HaveSameMap(args1, args2));
args2.length = "aa"
assertTrue(%HaveSameMap(args1, args2));
})();
(function testArgumentsVerification() {
(function f2(a,a) {
%HeapObjectVerify(arguments);
})(1,2);
function f7(a,a,a,a,a,a,a) {
%HeapObjectVerify(arguments);
};
f7(1,2,3,4,5,6);
f7(1,2,3,4,5,6,7);
f7(1,2,3,4,5,6,7,8);
})();
(function testArgumentsHole() {
function f(a) {
arguments[3] = 1;
return arguments[2];
};
assertEquals(undefined, f(1));
assertEquals(undefined, f(1));
assertEquals(undefined, f(1));
})();

View File

@ -0,0 +1,282 @@
// Copyright 2011 the V8 project authors. All rights reserved.
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following
// disclaimer in the documentation and/or other materials provided
// with the distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// Flags: --allow-natives-syntax --expose-gc --no-always-turbofan --turbofan
var a = new Int32Array(1024);
// Test that we do not assert if the accessed index has not an int32 rep.
var v = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
function test_do_not_assert_on_non_int32(vector, base) {
var r = 0;
var a1 = base + 1;
var a2 = base + 2;
var a3 = base + 3;
var a4 = base + 4;
if (a1 == 2) {
r += vector[a1];
r += vector[a4];
r += vector[a2];
r += vector[a3];
}
return r;
}
%PrepareFunctionForOptimization(test_do_not_assert_on_non_int32);
test_do_not_assert_on_non_int32(v,1);
test_do_not_assert_on_non_int32(v,1);
test_do_not_assert_on_non_int32(v,"a");
test_do_not_assert_on_non_int32(v,"a");
%OptimizeFunctionOnNextCall(test_do_not_assert_on_non_int32);
test_do_not_assert_on_non_int32(v,0);
function test_base(a, base, condition) {
a[base + 1] = 1;
a[base + 4] = 2;
a[base + 3] = 3;
a[base + 2] = 4;
a[base + 4] = base + 4;
if (condition) {
a[base + 1] = 1;
a[base + 2] = 2;
a[base + 2] = 3;
a[base + 2] = 4;
a[base + 4] = base + 4;
} else {
a[base + 6] = 1;
a[base + 4] = 2;
a[base + 3] = 3;
a[base + 2] = 4;
a[base + 4] = base - 4;
}
}
function check_test_base(a, base, condition) {
if (condition) {
assertEquals(1, a[base + 1]);
assertEquals(4, a[base + 2]);
assertEquals(base + 4, a[base + 4]);
} else {
assertEquals(1, a[base + 6]);
assertEquals(3, a[base + 3]);
assertEquals(4, a[base + 2]);
assertEquals(base - 4, a[base + 4]);
}
}
%PrepareFunctionForOptimization(test_base);
test_base(a, 1, true);
test_base(a, 2, true);
test_base(a, 1, false);
test_base(a, 2, false);
%OptimizeFunctionOnNextCall(test_base);
test_base(a, 3, true);
check_test_base(a, 3, true);
test_base(a, 3, false);
check_test_base(a, 3, false);
assertOptimized(test_base);
function test_base_for_dictionary_map(a, base, condition) {
a[base + 1] = 1;
a[base + 4] = 2;
a[base + 3] = 3;
a[base + 2] = 4;
a[base + 4] = base + 4;
if (condition) {
a[base + 1] = 1;
a[base + 2] = 2;
a[base + 2] = 3;
a[base + 2] = 4;
a[base + 4] = base + 4;
} else {
a[base + 6] = 1;
a[base + 4] = 2;
a[base + 3] = 3;
a[base + 2] = 4;
a[base + 4] = base - 4;
}
}
// Test that we deopt on failed bounds checks.
var dictionary_map_array = new Int32Array(128);
test_base_for_dictionary_map(dictionary_map_array, 5, true);
%PrepareFunctionForOptimization(test_base_for_dictionary_map);
test_base_for_dictionary_map(dictionary_map_array, 6, true);
test_base_for_dictionary_map(dictionary_map_array, 5, false);
test_base_for_dictionary_map(dictionary_map_array, 6, false);
%OptimizeFunctionOnNextCall(test_base_for_dictionary_map);
test_base_for_dictionary_map(dictionary_map_array, -2, true);
assertUnoptimized(test_base_for_dictionary_map);
function test_base_for_oob(a, base, condition) {
a[base + 1] = 1;
a[base + 4] = 2;
a[base + 3] = 3;
a[base + 2] = 4;
a[base + 4] = base + 4;
if (condition) {
a[base + 1] = 1;
a[base + 2] = 2;
a[base + 2] = 3;
a[base + 2] = 4;
a[base + 4] = base + 4;
} else {
a[base + 6] = 1;
a[base + 4] = 2;
a[base + 3] = 3;
a[base + 2] = 4;
a[base + 4] = base - 4;
}
}
%PrepareFunctionForOptimization(test_base_for_oob);
test_base_for_oob(a, 5, true);
test_base_for_oob(a, 6, true);
test_base_for_oob(a, 5, false);
test_base_for_oob(a, 6, false);
%OptimizeFunctionOnNextCall(test_base_for_oob);
test_base_for_oob(a, 2048, true);
assertUnoptimized(test_base_for_oob);
function test_minus(base,cond) {
a[base - 1] = 1;
a[base - 2] = 2;
a[base + 4] = 3;
a[base] = 4;
a[base + 4] = base + 4;
if (cond) {
a[base - 4] = 1;
a[base + 5] = 2;
a[base + 3] = 3;
a[base + 2] = 4;
a[base + 4] = base + 4;
} else {
a[base + 6] = 1;
a[base + 4] = 2;
a[base + 3] = 3;
a[base + 2] = 4;
a[base + 4] = base - 4;
}
}
function check_test_minus(base,cond) {
if (cond) {
assertEquals(2, a[base + 5]);
assertEquals(3, a[base + 3]);
assertEquals(4, a[base + 2]);
assertEquals(base + 4, a[base + 4]);
} else {
assertEquals(1, a[base + 6]);
assertEquals(3, a[base + 3]);
assertEquals(4, a[base + 2]);
assertEquals(base - 4, a[base + 4]);
}
}
%PrepareFunctionForOptimization(test_minus);
test_minus(5,true);
test_minus(6,true);
%OptimizeFunctionOnNextCall(test_minus);
test_minus(7,true);
check_test_minus(7,true);
test_minus(7,false);
check_test_minus(7,false);
// Specific test on negative offsets.
var short_a = new Array(100);
for (var i = 0; i < short_a.length; i++) short_a[i] = 0;
function short_test(a, i) {
a[i + 9] = 0;
a[i - 10] = 0;
}
%PrepareFunctionForOptimization(short_test);
short_test(short_a, 50);
short_test(short_a, 50);
%OptimizeFunctionOnNextCall(short_test);
short_a.length = 10;
short_test(short_a, 0);
// TODO(v8:11457) Currently, we cannot inline stores if there is a dictionary
// mode prototype on the prototype chain. Therefore, if
// v8_dict_property_const_tracking is enabled, the optimized code only contains
// a call to the IC handler and doesn't get deopted.
assertEquals(%IsDictPropertyConstTrackingEnabled(), isOptimized(short_test));
// A test for when we would modify a phi index.
var data_phi = [0, 1, 2, 3, 4, 5, 6, 7, 8];
function test_phi(a, base, check) {
var index;
if (check) {
index = base + 1;
} else {
index = base + 2;
}
var result = a[index];
result += a[index + 1];
result += a[index - 1];
return result;
}
%PrepareFunctionForOptimization(test_phi);
var result_phi = 0;
result_phi = test_phi(data_phi, 3, true);
assertEquals(12, result_phi);
result_phi = test_phi(data_phi, 3, true);
assertEquals(12, result_phi);
%OptimizeFunctionOnNextCall(test_phi);
result_phi = test_phi(data_phi, 3, true);
assertEquals(12, result_phi);
// A test for recursive decomposition
var data_composition_long = [0, 1, 2, 3, 4, 5, 6, 7, 8];
var data_composition_short = [0, 1, 2, 3, 4];
function test_composition(a, base0, check) {
var base1 = ((base0 + 2));
var base2 = ((base1 + 8) >> 2);
var base3 = ((base2 + 6) >> 1);
var base4 = ((base3 + 8) >> 1);
var result = 0;
result += a[base0];
result += a[base1];
result += a[base2];
result += a[base3];
result += a[base4];
return result;
}
%PrepareFunctionForOptimization(test_composition);
var result_composition = 0;
result_composition = test_composition(data_composition_long, 2);
assertEquals(19, result_composition);
result_composition = test_composition(data_composition_long, 2);
assertEquals(19, result_composition);
%OptimizeFunctionOnNextCall(test_composition);
result_composition = test_composition(data_composition_short, 2);
assertEquals(NaN, result_composition);
gc();

View File

@ -0,0 +1,78 @@
// Copyright 2022 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
// Flags: --allow-natives-syntax
function TestDetachSucceeds(originalKey, detachKey) {
const ab = new ArrayBuffer(100);
%ArrayBufferSetDetachKey(ab, originalKey);
%ArrayBufferDetach(ab, detachKey);
assertEquals(0, ab.byteLength); // Detached.
}
function TestDetachFails(originalKey, detachKey) {
const ab = new ArrayBuffer(100);
%ArrayBufferSetDetachKey(ab, originalKey);
assertThrows(() => { %ArrayBufferDetach(ab, detachKey); }, TypeError);
assertEquals(100, ab.byteLength); // Not detached.
}
(function DetachWithKey() {
TestDetachSucceeds("foo", "foo");
const part1 = "fo";
const part2 = "o";
TestDetachSucceeds("foo", part1 + part2);
TestDetachSucceeds(1337, 1337);
TestDetachSucceeds(null, null);
const obj = {a: 1};
TestDetachSucceeds(obj, obj);
TestDetachFails("foo", "bar");
TestDetachFails("foo", undefined);
TestDetachFails(1337, 1338);
TestDetachFails(1337, undefined);
TestDetachFails(null, 0);
TestDetachFails(null, undefined);
TestDetachFails({a: 1}, {a: 1});
})();
(function DetachTwice() {
const ab = new ArrayBuffer(100);
%ArrayBufferSetDetachKey(ab, "foo");
%ArrayBufferDetach(ab, "foo");
assertEquals(0, ab.byteLength);
// If the detach key is wrong, an error is thrown even if the buffer was
// already detached.
assertThrows(() => { %ArrayBufferDetach(ab, "bar"); });
})();
(function DetachWithoutKey() {
// This test cannot be implemented via TestDetachFails, since the
// non-existence of the detach key parameter is not the same thing as it being
// undefined.
const ab = new ArrayBuffer(100);
%ArrayBufferSetDetachKey(ab, "foo");
assertThrows(() => { %ArrayBufferDetach(ab); }, TypeError);
assertEquals(100, ab.byteLength); // Not detached.
})();
(function DetachKeyProvidedEvenThoughWeDontNeedOne() {
// This test cannot be implemented via TestDetachFails, since the
// non-existence of the detach key parameter is not the same thing as it being
// undefined.
const ab1 = new ArrayBuffer(100); // No detach key.
assertThrows(() => { %ArrayBufferDetach(ab1, 'unnecessary'); }, TypeError);
assertEquals(100, ab1.byteLength); // Not detached.
%ArrayBufferDetach(ab1, undefined); // Passing undefined is fine.
assertEquals(0, ab1.byteLength); // Detached.
const ab2 = new ArrayBuffer(100); // No detach key.
%ArrayBufferDetach(ab2); // Passing no detach key is fine.
assertEquals(0, ab2.byteLength); // Detached.
})();

View File

@ -0,0 +1,90 @@
// Copyright 2024 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: --mock-arraybuffer-allocator
// Flags: --mock-arraybuffer-allocator-limit=65536
// Flags: --allow-natives-syntax
TestArrayBufferTooLarge();
%PrepareFunctionForOptimization(TestArrayBufferTooLarge);
TestArrayBufferTooLarge();
%OptimizeFunctionOnNextCall(TestArrayBufferTooLarge);
TestArrayBufferTooLarge();
function TestArrayBufferTooLarge() {
const LIMIT = 65536;
// Not too big.
new ArrayBuffer(LIMIT);
// Too big.
assertThrows(() => new ArrayBuffer(LIMIT + 1), RangeError);
// Not too big.
new Int8Array(LIMIT);
// Too big.
assertThrows(() => new Int8Array(LIMIT + 1), RangeError);
// Not too big.
new Int16Array(LIMIT / 2);
// Too big.
assertThrows(() => new Int16Array(LIMIT / 2 + 1), RangeError);
// Not too big.
new Int32Array(LIMIT / 4);
// Too big.
assertThrows(() => new Int32Array(LIMIT / 4 + 1), RangeError);
// Not too big.
new Float64Array(LIMIT / 8);
// Too big.
assertThrows(() => new Float64Array(LIMIT / 8 + 1), RangeError);
// Not too big, based on an iterable input.
let array = new Array(LIMIT);
for (i = 0; i < array.length; i++) array[i] = i & 0xff;
new Int8Array(array);
// Too big, based on an iterable input.
let big = new Array(LIMIT + 1);
for (i = 0; i < big.length; i++) big[i] = i & 0xff;
assertThrows(() => new Int8Array(big), RangeError);
assertThrowsWithMessage("Invalid typed array length", () => {
const int8_array = new Int8Array(LIMIT + 1);
});
const int8_array = new Int8Array(LIMIT);
assertThrowsWithMessage("Array buffer allocation failed", () => {
// Outer one is still alive so we can't allocate another.
// 64 is the default of v8_typed_array_max_size_in_heap - below this
// level the mock array buffer allocator is not asked.
int8_slice = new Int8Array(65);
});
assertThrowsWithMessage("Array buffer allocation failed", () => {
// Outer one is still alive so we can't allocate another with slice.
int8_slice = int8_array.slice(0, 65);
});
}
function assertThrowsWithMessage(expected_message, fn) {
var threw = true;
try {
fn();
threw = false;
} catch (e) {
assertTrue(e instanceof RangeError)
if (!e.message.includes(expected_message)) {
print("Error '" + e.message + "' doesn't include expected '" + expected_message + "'");
}
assertTrue(e.message.includes(expected_message));
}
assertTrue(threw);
}

268
deps/v8/test/mjsunit/array-concat.js vendored Normal file
View File

@ -0,0 +1,268 @@
// Copyright 2008 the V8 project authors. All rights reserved.
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following
// disclaimer in the documentation and/or other materials provided
// with the distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
/**
* @fileoverview Test concat on small and large arrays
*/
(function testStringWrapperConcat() {
var concat = Array.prototype.concat;
var str = new String('abcd');
assertEquals([1,2,3,new String('abcd')], [1, 2, 3].concat(str));
assertEquals([new String("abcd")], concat.call(str));
var array = [1, 2, 3];
array.__proto__ = str;
array.length = 4;
assertEquals([1,2,3,'d'], concat.call(array));
})()
var poses;
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;
var largeLength = 500000;
Object.defineProperty(arr1, 0, {get: function() {
arr2[largeLength] = "X";
return undefined;
}, configurable: true})
var r3 = [].concat(arr1, arr2); // [undefined,2,1,3,"X"]
var expected = [undefined,2,1,3];
var initialLen = expected.length;
expected[largeLength + 2] = "X";
var numElementsToCheck = 10;
// Checking entire massive array is too slow, so check:
// - the length,
assertEquals(expected.length, r3.length);
var slicesToCheck = [
// - the first few elements,
{start: 0, end: initialLen},
// - arbitrary number of elements past the first few elements,
{start: initialLen, end: initialLen + numElementsToCheck},
// - arbitrary number of elements in the middle of the array
{start: largeLength / 2, end: largeLength / 2 + numElementsToCheck},
// - last few elements
{start: largeLength, end: largeLength + 3}];
for (const {start, end} of slicesToCheck) {
assertEquals(expected.slice(start, end), r3.slice(start, end));
}
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);

View File

@ -0,0 +1,35 @@
// Copyright 2012 the V8 project authors. All rights reserved.
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following
// disclaimer in the documentation and/or other materials provided
// with the distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// Flags: --allow-natives-syntax
var a = new Array(0, 1, 2);
assertTrue(%HasSmiElements(a));
var b = new Array(0.5, 1.2, 2.3);
assertTrue(%HasDoubleElements(b));
var c = new Array(0.5, 1.2, new Object());
assertTrue(%HasObjectElements(c));

View File

@ -0,0 +1,176 @@
// Copyright 2012 the V8 project authors. All rights reserved.
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following
// disclaimer in the documentation and/or other materials provided
// with the distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// Flags: --allow-natives-syntax --expose-gc --no-always-turbofan --turbofan
// Test element kind of objects.
var elements_kind = {
fast_smi_only : 'fast smi only elements',
fast : 'fast elements',
fast_double : 'fast double elements',
dictionary : 'dictionary elements',
external_byte : 'external byte elements',
external_unsigned_byte : 'external unsigned byte elements',
external_short : 'external short elements',
external_unsigned_short : 'external unsigned short elements',
external_int : 'external int elements',
external_unsigned_int : 'external unsigned int elements',
external_float : 'external float elements',
external_double : 'external double elements',
external_pixel : 'external pixel elements'
}
function getKind(obj) {
if (%HasSmiElements(obj)) return elements_kind.fast_smi_only;
if (%HasObjectElements(obj)) return elements_kind.fast;
if (%HasDoubleElements(obj)) return elements_kind.fast_double;
if (%HasDictionaryElements(obj)) return elements_kind.dictionary;
}
function isHoley(obj) {
if (%HasHoleyElements(obj)) return true;
return false;
}
function assertKind(expected, obj, name_opt) {
assertEquals(expected, getKind(obj), name_opt);
}
// Test: ensure that crankshafted array constructor sites are deopted
// if another function is used.
(function() {
function bar0(t) {
return new t();
}
%PrepareFunctionForOptimization(bar0);
a = bar0(Array);
a[0] = 3.5;
b = bar0(Array);
assertKind(elements_kind.fast_double, b);
%OptimizeFunctionOnNextCall(bar0);
b = bar0(Array);
assertKind(elements_kind.fast_double, b);
assertOptimized(bar0);
// bar0 should deopt
b = bar0(Object);
assertUnoptimized(bar0);
%PrepareFunctionForOptimization(bar0);
// When it's re-optimized, we should call through the full stub
bar0(Array);
%OptimizeFunctionOnNextCall(bar0);
b = bar0(Array);
// We also lost our ability to record kind feedback, as the site
// is megamorphic now.
assertKind(elements_kind.fast_smi_only, b);
assertOptimized(bar0);
b[0] = 3.5;
c = bar0(Array);
assertKind(elements_kind.fast_smi_only, c);
})();
// Test: When a method with array constructor is crankshafted, the type
// feedback for elements kind is baked in. Verify that transitions don't
// change it anymore
(function() {
function bar() {
return new Array();
}
%PrepareFunctionForOptimization(bar);
a = bar();
bar();
%OptimizeFunctionOnNextCall(bar);
b = bar();
assertOptimized(bar);
b[0] = 3.5;
c = bar();
assertKind(elements_kind.fast_smi_only, c);
assertOptimized(bar);
})();
// Test: create arrays in two contexts, verifying that the correct
// map for Array in that context will be used.
(function() {
function bar() { return new Array(); }
%PrepareFunctionForOptimization(bar);
bar();
bar();
%OptimizeFunctionOnNextCall(bar);
a = bar();
assertTrue(a instanceof Array);
var contextB = Realm.create();
Realm.eval(contextB,
"function bar2() { return new Array(); }; %PrepareFunctionForOptimization(bar2)");
Realm.eval(contextB, "bar2(); bar2();");
Realm.eval(contextB, "%OptimizeFunctionOnNextCall(bar2);");
Realm.eval(contextB, "bar2();");
assertFalse(Realm.eval(contextB, "bar2();") instanceof Array);
assertTrue(Realm.eval(contextB, "bar2() instanceof Array"));
})();
// Test: create array with packed feedback, then optimize function, which
// should deal with arguments that create holey arrays.
(function() {
function bar(len) { return new Array(len); }
%PrepareFunctionForOptimization(bar);
bar(0);
bar(0);
%OptimizeFunctionOnNextCall(bar);
a = bar(0);
assertOptimized(bar);
assertTrue(isHoley(a));
a = bar(1); // ouch!
assertOptimized(bar);
assertTrue(isHoley(a));
a = bar(100);
assertTrue(isHoley(a));
a = bar(0);
assertOptimized(bar);
assertTrue(isHoley(a));
})();
// Test: Make sure that crankshaft continues with feedback for large arrays.
(function() {
function bar(len) { return new Array(len); }
%PrepareFunctionForOptimization(bar);
var size = 100001;
// Perform a gc, because we are allocating a very large array and if a gc
// happens during the allocation we could lose our memento.
gc();
bar(size)[0] = 'string';
var res = bar(size);
assertKind(elements_kind.fast, bar(size));
%OptimizeFunctionOnNextCall(bar);
assertKind(elements_kind.fast, bar(size));
// But there is a limit, based on the size of the old generation, currently
// 22937600, but double it to prevent the test being too brittle.
var large_size = 22937600 * 2;
assertKind(elements_kind.dictionary, bar(large_size));
})();

View File

@ -0,0 +1,115 @@
// Copyright 2008 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 loop_count = 5
for (var i = 0; i < loop_count; i++) {
var a = new Array();
var b = Array();
assertEquals(0, a.length);
assertEquals(0, b.length);
for (var k = 0; k < 10; k++) {
assertEquals('undefined', typeof a[k]);
assertEquals('undefined', typeof b[k]);
}
}
for (var i = 0; i < loop_count; i++) {
for (var j = 0; j < 100; j++) {
var a = new Array(j);
var b = Array(j);
assertEquals(j, a.length);
assertEquals(j, b.length);
for (var k = 0; k < j; k++) {
assertEquals('undefined', typeof a[k]);
assertEquals('undefined', typeof b[k]);
}
}
}
for (var i = 0; i < loop_count; i++) {
a = new Array(0, 1);
assertArrayEquals([0, 1], a);
a = new Array(0, 1, 2);
assertArrayEquals([0, 1, 2], a);
a = new Array(0, 1, 2, 3);
assertArrayEquals([0, 1, 2, 3], a);
a = new Array(0, 1, 2, 3, 4);
assertArrayEquals([0, 1, 2, 3, 4], a);
a = new Array(0, 1, 2, 3, 4, 5);
assertArrayEquals([0, 1, 2, 3, 4, 5], a);
a = new Array(0, 1, 2, 3, 4, 5, 6);
assertArrayEquals([0, 1, 2, 3, 4, 5, 6], a);
a = new Array(0, 1, 2, 3, 4, 5, 6, 7);
assertArrayEquals([0, 1, 2, 3, 4, 5, 6, 7], a);
a = new Array(0, 1, 2, 3, 4, 5, 6, 7, 8);
assertArrayEquals([0, 1, 2, 3, 4, 5, 6, 7, 8], a);
a = new Array(0, 1, 2, 3, 4, 5, 6, 7, 8, 9);
assertArrayEquals([0, 1, 2, 3, 4, 5, 6, 7, 8, 9], a);
}
function innerArrayLiteral(n) {
var a = new Array(n);
for (var i = 0; i < n; i++) {
a[i] = i * 2 + 7;
}
return a.join();
}
function testConstruction(len, elements_str) {
var a = eval('[' + elements_str + ']');
var b = eval('new Array(' + elements_str + ')')
var c = eval('Array(' + elements_str + ')')
assertEquals(len, a.length);
assertArrayEquals(a, b);
assertArrayEquals(a, c);
}
for (var i = 0; i < loop_count; i++) {
const N = 2000;
const literal = innerArrayLiteral(N);
let str = literal;
// JSObject::kInitialMaxFastElementArray is approximately 10000.
for (var j = N; j <= 12000; j += N) {
testConstruction(j, str);
str += ", " + literal;
}
}
for (var i = 0; i < loop_count; i++) {
assertArrayEquals(['xxx'], new Array('xxx'));
assertArrayEquals(['xxx'], Array('xxx'));
assertArrayEquals([true], new Array(true));
assertArrayEquals([false], Array(false));
assertArrayEquals([{a:1}], new Array({a:1}));
assertArrayEquals([{b:2}], Array({b:2}));
}
assertThrows('new Array(3.14)');
assertThrows('Array(2.72)');
// Make sure that throws occur in the context of the Array function.
var b = Realm.create();
var bArray = Realm.eval(b, "Array");
var bError = Realm.eval(b, "RangeError");
function verifier(array, error) {
try {
new array(3.14);
} catch(e) {
return e.__proto__ === error.__proto__;
}
assertTrue(false); // should never get here.
}
assertTrue(verifier(Array, RangeError()));
assertTrue(verifier(bArray, bError()));
assertFalse(verifier(Array, bError()));
assertFalse(verifier(bArray, RangeError()));

View File

@ -0,0 +1,191 @@
// Copyright 2010 the V8 project authors. All rights reserved.
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following
// disclaimer in the documentation and/or other materials provided
// with the distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
////////////////////////////////////////////////////////////////////////
// Tests below verify that elements set on Array.prototype's proto propagate
// for various Array.prototype functions (like unshift, shift, etc.)
// If add any new tests here, consider adding them to all other files:
// array-elements-from-array-prototype.js
// array-elements-from-array-prototype-chain.js
// array-elements-from-object-prototype.js
// those ideally should be identical modulo host of elements and
// the way elements introduced.
//
// Note: they are put into a separate file as we need maximally clean
// VM setup---some optimizations might be already turned off in
// 'dirty' VM.
////////////////////////////////////////////////////////////////////////
var at3 = '@3'
var at7 = '@7'
Array.prototype.__proto__ = {3: at3};
Array.prototype.__proto__.__proto__ = {7: at7};
var a = new Array(13)
assertEquals(at3, a[3])
assertFalse(a.hasOwnProperty(3))
assertEquals(at7, a[7])
assertFalse(a.hasOwnProperty(7))
assertEquals(undefined, a.shift(), 'hole should be returned as undefined')
// Side-effects: Array.prototype[3] percolates into a[2] and Array.prototype[7[
// into a[6], still visible at the corresponding indices.
assertEquals(at3, a[2])
assertTrue(a.hasOwnProperty(2))
assertEquals(at3, a[3])
assertFalse(a.hasOwnProperty(3))
assertEquals(at7, a[6])
assertTrue(a.hasOwnProperty(6))
assertEquals(at7, a[7])
assertFalse(a.hasOwnProperty(7))
a.unshift('foo', 'bar')
// Side-effects: Array.prototype[3] now percolates into a[5] and Array.prototype[7]
// into a[9].
assertEquals(at3, a[3])
assertFalse(a.hasOwnProperty(3))
assertEquals(at3, a[4])
assertTrue(a.hasOwnProperty(4))
assertEquals(at3, a[5])
assertTrue(a.hasOwnProperty(5))
assertEquals(undefined, a[6])
assertFalse(a.hasOwnProperty(6))
assertEquals(at7, a[7])
assertFalse(a.hasOwnProperty(7))
assertEquals(at7, a[8])
assertTrue(a.hasOwnProperty(8))
assertEquals(at7, a[9])
assertTrue(a.hasOwnProperty(9))
var sliced = a.slice(3, 10)
// Slice must keep intact a and reify holes at indices 0--2 and 4--6.
assertEquals(at3, a[3])
assertFalse(a.hasOwnProperty(3))
assertEquals(at3, a[4])
assertTrue(a.hasOwnProperty(4))
assertEquals(at3, a[5])
assertTrue(a.hasOwnProperty(5))
assertEquals(undefined, a[6])
assertFalse(a.hasOwnProperty(6))
assertEquals(at7, a[7])
assertFalse(a.hasOwnProperty(7))
assertEquals(at7, a[8])
assertTrue(a.hasOwnProperty(8))
assertEquals(at7, a[9])
assertTrue(a.hasOwnProperty(9))
assertEquals(at3, sliced[0])
assertTrue(sliced.hasOwnProperty(0))
assertEquals(at3, sliced[1])
assertTrue(sliced.hasOwnProperty(1))
assertEquals(at3, sliced[2])
assertTrue(sliced.hasOwnProperty(2))
// Note: sliced[3] comes directly from Array.prototype[3]
assertEquals(at3, sliced[3]);
assertFalse(sliced.hasOwnProperty(3))
assertEquals(at7, sliced[4])
assertTrue(sliced.hasOwnProperty(4))
assertEquals(at7, sliced[5])
assertTrue(sliced.hasOwnProperty(5))
assertEquals(at7, sliced[6])
assertTrue(sliced.hasOwnProperty(6))
// Splice is too complicated the operation, start afresh.
// Shrking array.
var a0 = [0, 1, , , 4, 5, , , , 9]
var result = a0.splice(4, 1)
// Side-effects: everything before 4 is kept intact:
assertEquals(0, a0[0])
assertTrue(a0.hasOwnProperty(0))
assertEquals(1, a0[1])
assertTrue(a0.hasOwnProperty(1))
assertEquals(undefined, a0[2])
assertFalse(a0.hasOwnProperty(2))
assertEquals(at3, a0[3])
assertFalse(a0.hasOwnProperty(3))
// 4 and above shifted left by one reifying at7 into a0[6] and keeping
// a hole at a0[7]
assertEquals(5, a0[4])
assertTrue(a0.hasOwnProperty(4))
assertEquals(undefined, a0[5])
assertFalse(a0.hasOwnProperty(5))
assertEquals(at7, a0[6])
assertTrue(a0.hasOwnProperty(6))
assertEquals(at7, a0[7])
assertFalse(a0.hasOwnProperty(7))
assertEquals(9, a0[8])
assertTrue(a0.hasOwnProperty(8))
// Growing array.
var a1 = [0, 1, , , 4, 5, , , , 9]
var result = a1.splice(4, 0, undefined)
// Side-effects: everything before 4 is kept intact:
assertEquals(0, a1[0])
assertTrue(a1.hasOwnProperty(0))
assertEquals(1, a1[1])
assertTrue(a1.hasOwnProperty(1))
assertEquals(undefined, a1[2])
assertFalse(a1.hasOwnProperty(2))
assertEquals(at3, a1[3])
assertFalse(a1.hasOwnProperty(3))
// Now owned undefined resides at 4 and rest is shifted right by one
// reifying at7 into a0[8] and keeping a hole at a0[7].
assertEquals(undefined, a1[4])
assertTrue(a1.hasOwnProperty(4))
assertEquals(4, a1[5])
assertTrue(a1.hasOwnProperty(5))
assertEquals(5, a1[6])
assertTrue(a1.hasOwnProperty(6))
assertEquals(at7, a1[7])
assertFalse(a1.hasOwnProperty(7))
assertEquals(at7, a1[8])
assertTrue(a1.hasOwnProperty(8))
assertEquals(undefined, a1[9])
assertFalse(a1.hasOwnProperty(9))
assertEquals(9, a1[10])
assertTrue(a1.hasOwnProperty(10))

View File

@ -0,0 +1,191 @@
// Copyright 2010 the V8 project authors. All rights reserved.
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following
// disclaimer in the documentation and/or other materials provided
// with the distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
////////////////////////////////////////////////////////////////////////
// Tests below verify that elements set on Array.prototype propagate
// for various Array.prototype functions (like unshift, shift, etc.)
// If add any new tests here, consider adding them to all other files:
// array-elements-from-array-prototype.js
// array-elements-from-array-prototype-chain.js
// array-elements-from-object-prototype.js
// those ideally should be identical modulo host of elements and
// the way elements introduced.
//
// Note: they are put into a separate file as we need maximally clean
// VM setup---some optimizations might be already turned off in
// 'dirty' VM.
////////////////////////////////////////////////////////////////////////
var at3 = '@3'
var at7 = '@7'
Array.prototype[3] = at3
Array.prototype[7] = at7
var a = new Array(13)
assertEquals(at3, a[3])
assertFalse(a.hasOwnProperty(3))
assertEquals(at7, a[7])
assertFalse(a.hasOwnProperty(7))
assertEquals(undefined, a.shift(), 'hole should be returned as undefined')
// Side-effects: Array.prototype[3] percolates into a[2] and Array.prototype[7[
// into a[6], still visible at the corresponding indices.
assertEquals(at3, a[2])
assertTrue(a.hasOwnProperty(2))
assertEquals(at3, a[3])
assertFalse(a.hasOwnProperty(3))
assertEquals(at7, a[6])
assertTrue(a.hasOwnProperty(6))
assertEquals(at7, a[7])
assertFalse(a.hasOwnProperty(7))
a.unshift('foo', 'bar')
// Side-effects: Array.prototype[3] now percolates into a[5] and Array.prototype[7]
// into a[9].
assertEquals(at3, a[3])
assertFalse(a.hasOwnProperty(3))
assertEquals(at3, a[4])
assertTrue(a.hasOwnProperty(4))
assertEquals(at3, a[5])
assertTrue(a.hasOwnProperty(5))
assertEquals(undefined, a[6])
assertFalse(a.hasOwnProperty(6))
assertEquals(at7, a[7])
assertFalse(a.hasOwnProperty(7))
assertEquals(at7, a[8])
assertTrue(a.hasOwnProperty(8))
assertEquals(at7, a[9])
assertTrue(a.hasOwnProperty(9))
var sliced = a.slice(3, 10)
// Slice must keep intact a and reify holes at indices 0--2 and 4--6.
assertEquals(at3, a[3])
assertFalse(a.hasOwnProperty(3))
assertEquals(at3, a[4])
assertTrue(a.hasOwnProperty(4))
assertEquals(at3, a[5])
assertTrue(a.hasOwnProperty(5))
assertEquals(undefined, a[6])
assertFalse(a.hasOwnProperty(6))
assertEquals(at7, a[7])
assertFalse(a.hasOwnProperty(7))
assertEquals(at7, a[8])
assertTrue(a.hasOwnProperty(8))
assertEquals(at7, a[9])
assertTrue(a.hasOwnProperty(9))
assertEquals(at3, sliced[0])
assertTrue(sliced.hasOwnProperty(0))
assertEquals(at3, sliced[1])
assertTrue(sliced.hasOwnProperty(1))
assertEquals(at3, sliced[2])
assertTrue(sliced.hasOwnProperty(2))
// Note: sliced[3] comes directly from Array.prototype[3]
assertEquals(at3, sliced[3]);
assertFalse(sliced.hasOwnProperty(3))
assertEquals(at7, sliced[4])
assertTrue(sliced.hasOwnProperty(4))
assertEquals(at7, sliced[5])
assertTrue(sliced.hasOwnProperty(5))
assertEquals(at7, sliced[6])
assertTrue(sliced.hasOwnProperty(6))
// Splice is too complicated the operation, start afresh.
// Shrking array.
var a0 = [0, 1, , , 4, 5, , , , 9]
var result = a0.splice(4, 1)
// Side-effects: everything before 4 is kept intact:
assertEquals(0, a0[0])
assertTrue(a0.hasOwnProperty(0))
assertEquals(1, a0[1])
assertTrue(a0.hasOwnProperty(1))
assertEquals(undefined, a0[2])
assertFalse(a0.hasOwnProperty(2))
assertEquals(at3, a0[3])
assertFalse(a0.hasOwnProperty(3))
// 4 and above shifted left by one reifying at7 into a0[6] and keeping
// a hole at a0[7]
assertEquals(5, a0[4])
assertTrue(a0.hasOwnProperty(4))
assertEquals(undefined, a0[5])
assertFalse(a0.hasOwnProperty(5))
assertEquals(at7, a0[6])
assertTrue(a0.hasOwnProperty(6))
assertEquals(at7, a0[7])
assertFalse(a0.hasOwnProperty(7))
assertEquals(9, a0[8])
assertTrue(a0.hasOwnProperty(8))
// Growing array.
var a1 = [0, 1, , , 4, 5, , , , 9]
var result = a1.splice(4, 0, undefined)
// Side-effects: everything before 4 is kept intact:
assertEquals(0, a1[0])
assertTrue(a1.hasOwnProperty(0))
assertEquals(1, a1[1])
assertTrue(a1.hasOwnProperty(1))
assertEquals(undefined, a1[2])
assertFalse(a1.hasOwnProperty(2))
assertEquals(at3, a1[3])
assertFalse(a1.hasOwnProperty(3))
// Now owned undefined resides at 4 and rest is shifted right by one
// reifying at7 into a0[8] and keeping a hole at a0[7].
assertEquals(undefined, a1[4])
assertTrue(a1.hasOwnProperty(4))
assertEquals(4, a1[5])
assertTrue(a1.hasOwnProperty(5))
assertEquals(5, a1[6])
assertTrue(a1.hasOwnProperty(6))
assertEquals(at7, a1[7])
assertFalse(a1.hasOwnProperty(7))
assertEquals(at7, a1[8])
assertTrue(a1.hasOwnProperty(8))
assertEquals(undefined, a1[9])
assertFalse(a1.hasOwnProperty(9))
assertEquals(9, a1[10])
assertTrue(a1.hasOwnProperty(10))

View File

@ -0,0 +1,191 @@
// Copyright 2010 the V8 project authors. All rights reserved.
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following
// disclaimer in the documentation and/or other materials provided
// with the distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
////////////////////////////////////////////////////////////////////////
// Tests below verify that elements set on Object.prototype propagate
// for various Array.prototype functions (like unshift, shift, etc.)
// If add any new tests here, consider adding them to all other files:
// array-elements-from-array-prototype.js
// array-elements-from-array-prototype-chain.js
// array-elements-from-object-prototype.js
// those ideally should be identical modulo host of elements and
// the way elements introduced.
//
// Note: they are put into a separate file as we need maximally clean
// VM setup---some optimizations might be already turned off in
// 'dirty' VM.
////////////////////////////////////////////////////////////////////////
var at3 = '@3'
var at7 = '@7'
Object.prototype[3] = at3
Object.prototype[7] = at7
var a = new Array(13)
assertEquals(at3, a[3])
assertFalse(a.hasOwnProperty(3))
assertEquals(at7, a[7])
assertFalse(a.hasOwnProperty(7))
assertEquals(undefined, a.shift(), 'hole should be returned as undefined')
// Side-effects: Array.prototype[3] percolates into a[2] and Array.prototype[7[
// into a[6], still visible at the corresponding indices.
assertEquals(at3, a[2])
assertTrue(a.hasOwnProperty(2))
assertEquals(at3, a[3])
assertFalse(a.hasOwnProperty(3))
assertEquals(at7, a[6])
assertTrue(a.hasOwnProperty(6))
assertEquals(at7, a[7])
assertFalse(a.hasOwnProperty(7))
a.unshift('foo', 'bar')
// Side-effects: Array.prototype[3] now percolates into a[5] and Array.prototype[7]
// into a[9].
assertEquals(at3, a[3])
assertFalse(a.hasOwnProperty(3))
assertEquals(at3, a[4])
assertTrue(a.hasOwnProperty(4))
assertEquals(at3, a[5])
assertTrue(a.hasOwnProperty(5))
assertEquals(undefined, a[6])
assertFalse(a.hasOwnProperty(6))
assertEquals(at7, a[7])
assertFalse(a.hasOwnProperty(7))
assertEquals(at7, a[8])
assertTrue(a.hasOwnProperty(8))
assertEquals(at7, a[9])
assertTrue(a.hasOwnProperty(9))
var sliced = a.slice(3, 10)
// Slice must keep intact a and reify holes at indices 0--2 and 4--6.
assertEquals(at3, a[3])
assertFalse(a.hasOwnProperty(3))
assertEquals(at3, a[4])
assertTrue(a.hasOwnProperty(4))
assertEquals(at3, a[5])
assertTrue(a.hasOwnProperty(5))
assertEquals(undefined, a[6])
assertFalse(a.hasOwnProperty(6))
assertEquals(at7, a[7])
assertFalse(a.hasOwnProperty(7))
assertEquals(at7, a[8])
assertTrue(a.hasOwnProperty(8))
assertEquals(at7, a[9])
assertTrue(a.hasOwnProperty(9))
assertEquals(at3, sliced[0])
assertTrue(sliced.hasOwnProperty(0))
assertEquals(at3, sliced[1])
assertTrue(sliced.hasOwnProperty(1))
assertEquals(at3, sliced[2])
assertTrue(sliced.hasOwnProperty(2))
// Note: sliced[3] comes directly from Array.prototype[3]
assertEquals(at3, sliced[3]);
assertFalse(sliced.hasOwnProperty(3))
assertEquals(at7, sliced[4])
assertTrue(sliced.hasOwnProperty(4))
assertEquals(at7, sliced[5])
assertTrue(sliced.hasOwnProperty(5))
assertEquals(at7, sliced[6])
assertTrue(sliced.hasOwnProperty(6))
// Splice is too complicated the operation, start afresh.
// Shrking array.
var a0 = [0, 1, , , 4, 5, , , , 9]
var result = a0.splice(4, 1)
// Side-effects: everything before 4 is kept intact:
assertEquals(0, a0[0])
assertTrue(a0.hasOwnProperty(0))
assertEquals(1, a0[1])
assertTrue(a0.hasOwnProperty(1))
assertEquals(undefined, a0[2])
assertFalse(a0.hasOwnProperty(2))
assertEquals(at3, a0[3])
assertFalse(a0.hasOwnProperty(3))
// 4 and above shifted left by one reifying at7 into a0[6] and keeping
// a hole at a0[7]
assertEquals(5, a0[4])
assertTrue(a0.hasOwnProperty(4))
assertEquals(undefined, a0[5])
assertFalse(a0.hasOwnProperty(5))
assertEquals(at7, a0[6])
assertTrue(a0.hasOwnProperty(6))
assertEquals(at7, a0[7])
assertFalse(a0.hasOwnProperty(7))
assertEquals(9, a0[8])
assertTrue(a0.hasOwnProperty(8))
// Growing array.
var a1 = [0, 1, , , 4, 5, , , , 9]
var result = a1.splice(4, 0, undefined)
// Side-effects: everything before 4 is kept intact:
assertEquals(0, a1[0])
assertTrue(a1.hasOwnProperty(0))
assertEquals(1, a1[1])
assertTrue(a1.hasOwnProperty(1))
assertEquals(undefined, a1[2])
assertFalse(a1.hasOwnProperty(2))
assertEquals(at3, a1[3])
assertFalse(a1.hasOwnProperty(3))
// Now owned undefined resides at 4 and rest is shifted right by one
// reifying at7 into a0[8] and keeping a hole at a0[7].
assertEquals(undefined, a1[4])
assertTrue(a1.hasOwnProperty(4))
assertEquals(4, a1[5])
assertTrue(a1.hasOwnProperty(5))
assertEquals(5, a1[6])
assertTrue(a1.hasOwnProperty(6))
assertEquals(at7, a1[7])
assertFalse(a1.hasOwnProperty(7))
assertEquals(at7, a1[8])
assertTrue(a1.hasOwnProperty(8))
assertEquals(undefined, a1[9])
assertFalse(a1.hasOwnProperty(9))
assertEquals(9, a1[10])
assertTrue(a1.hasOwnProperty(10))

50
deps/v8/test/mjsunit/array-feedback.js vendored Normal file
View File

@ -0,0 +1,50 @@
// Copyright 2012 the V8 project authors. All rights reserved.
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following
// disclaimer in the documentation and/or other materials provided
// with the distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// Flags: --allow-natives-syntax --expose-gc --turbofan --no-always-turbofan
// Verify that cross context calls work
(function (){
var realmA = Realm.current();
var realmB = Realm.create();
assertEquals(0, realmA);
assertEquals(1, realmB);
function instanceof_check(type) {
assertTrue(type() instanceof type);
assertTrue(type(5) instanceof type);
assertTrue(type(1,2,3) instanceof type);
}
var realmBArray = Realm.eval(realmB, "Array");
instanceof_check(Array);
instanceof_check(Array);
instanceof_check(Array);
instanceof_check(realmBArray);
instanceof_check(realmBArray);
instanceof_check(realmBArray);
})();

17
deps/v8/test/mjsunit/array-foreach.js vendored Normal file
View File

@ -0,0 +1,17 @@
// 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 a = [20, 21, 22, 23];
a.__proto__ = [10, 11, 12, 13];
var values = [];
var indices = [];
function callback(value, index, object) {
object.length = 2;
values.push(value);
indices.push(index);
}
a.forEach(callback);
assertEquals([20, 21, 12, 13], values);
assertEquals([0, 1, 2, 3], indices);

View File

@ -0,0 +1,11 @@
// Copyright 2018 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
const n = 130000;
{
let x = new Set();
for (let i = 0; i < n; ++i) x.add(i);
let a = Array.from(x);
}

View File

@ -0,0 +1,370 @@
// Copyright 2008 the V8 project authors. All rights reserved.
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following
// disclaimer in the documentation and/or other materials provided
// with the distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
/**
* @fileoverview Test splice, shift, unshift, slice and join on small
* and large arrays. Some of these methods are specified such that they
* should work on other objects too, so we test that too.
*/
var LARGE = 40000;
var VERYLARGE = 40000;
var fourhundredth = LARGE/400;
function PseudoArray() {
};
for (var use_real_arrays = 0; use_real_arrays <= 1; use_real_arrays++) {
var poses = [0, 140, 20000];
var the_prototype;
var new_function;
var push_function;
var concat_function;
var slice_function;
var splice_function;
var splice_function_2;
var unshift_function;
var unshift_function_2;
var shift_function;
if (use_real_arrays) {
new_function = function(length) {
return new Array(length);
};
the_prototype = Array.prototype;
push_function = function(array, elt) {
return array.push(elt);
};
concat_function = function(array, other) {
return array.concat(other);
};
slice_function = function(array, start, len) {
return array.slice(start, len);
};
splice_function = function(array, start, len) {
return array.splice(start, len);
};
splice_function_2 = function(array, start, len, elt) {
return array.splice(start, len, elt);
};
unshift_function = function(array, elt) {
return array.unshift(elt);
};
unshift_function_2 = function(array, elt1, elt2) {
return array.unshift(elt1, elt2);
};
shift_function = function(array) {
return array.shift();
};
} else {
// Don't run largest size on non-arrays or we'll be here for ever.
poses.pop();
new_function = function(length) {
var obj = new PseudoArray();
obj.length = length;
return obj;
};
the_prototype = PseudoArray.prototype;
push_function = function(array, elt) {
array[array.length] = elt;
array.length++;
};
concat_function = function(array, other) {
return Array.prototype.concat.call(array, other);
};
slice_function = function(array, start, len) {
return Array.prototype.slice.call(array, start, len);
};
splice_function = function(array, start, len) {
return Array.prototype.splice.call(array, start, len);
};
splice_function_2 = function(array, start, len, elt) {
return Array.prototype.splice.call(array, start, len, elt);
};
unshift_function = function(array, elt) {
return Array.prototype.unshift.call(array, elt);
};
unshift_function_2 = function(array, elt1, elt2) {
return Array.prototype.unshift.call(array, elt1, elt2);
};
shift_function = function(array) {
return Array.prototype.shift.call(array);
};
}
for (var pos_pos = 0; pos_pos < poses.length; pos_pos++) {
var pos = poses[pos_pos];
if (pos > 100) {
var a = new_function(pos);
assertEquals(pos, a.length);
push_function(a, 'foo');
assertEquals(pos + 1, a.length);
var b = ['bar'];
// Delete a huge number of holes.
var c = splice_function(a, 10, pos - 20);
assertEquals(pos - 20, c.length);
assertEquals(21, a.length);
}
// Add a numeric property to the prototype of the array class. This
// allows us to test some borderline stuff relative to the standard.
the_prototype["" + (pos + 1)] = 'baz';
if (use_real_arrays) {
// It seems quite clear from ECMAScript spec 15.4.4.5. Just call Get on
// every integer in the range.
// IE, Safari get this right.
// FF, Opera get this wrong.
var a = ['zero', ,'two'];
if (pos == 0) {
assertEquals("zero,baz,two", a.join(","));
}
// Concat only applies to real arrays, unlike most of the other methods.
var a = new_function(pos);
push_function(a, "con");
assertEquals("con", a[pos]);
assertEquals(pos + 1, a.length);
var b = new_function(0);
push_function(b, "cat");
assertEquals("cat", b[0]);
var ab = concat_function(a, b);
assertEquals("con", ab[pos]);
assertEquals(pos + 2, ab.length);
assertEquals("cat", ab[pos + 1]);
var ba = concat_function(b, a);
assertEquals("con", ba[pos + 1]);
assertEquals(pos + 2, ba.length);
assertEquals("cat", ba[0]);
// Join with '' as separator.
var join = a.join('');
assertEquals("con", join);
join = b.join('');
assertEquals("cat", join);
join = ab.join('');
assertEquals("concat", join);
join = ba.join('');
assertEquals("catcon", join);
}
a = new_function(pos);
push_function(a, 'zero');
push_function(a, void 0);
push_function(a, 'two');
// Splice works differently from join.
// IE, Safari get this wrong.
// FF, Opera get this right.
// 15.4.4.12 line 24 says the object itself has to have the property...
var zero = splice_function(a, pos, 1);
assertEquals("undefined", typeof(a[pos]));
assertEquals("two", a[pos+1], "pos1:" + pos);
assertEquals(pos + 2, a.length, "a length");
assertEquals(1, zero.length, "zero length");
assertEquals("zero", zero[0]);
// 15.4.4.12 line 41 says the object itself has to have the property...
a = new_function(pos);
push_function(a, 'zero');
push_function(a, void 0);
push_function(a, 'two');
var nothing = splice_function_2(a, pos, 0, 'minus1');
assertEquals("minus1", a[pos]);
assertEquals("zero", a[pos+1]);
assertEquals("undefined", typeof(a[pos+2]), "toot!");
assertEquals("two", a[pos+3], "pos3");
assertEquals(pos + 4, a.length);
assertEquals(1, zero.length);
assertEquals("zero", zero[0]);
// 15.4.4.12 line 10 says the object itself has to have the property...
a = new_function(pos);
push_function(a, 'zero');
push_function(a, void 0);
push_function(a, 'two');
var one = splice_function(a, pos + 1, 1);
assertEquals("", one.join(","));
assertEquals(pos + 2, a.length);
assertEquals("zero", a[pos]);
assertEquals("two", a[pos+1]);
// Set things back to the way they were.
the_prototype[pos + 1] = undefined;
// Unshift.
var a = new_function(pos);
push_function(a, "foo");
assertEquals("foo", a[pos]);
assertEquals(pos + 1, a.length);
unshift_function(a, "bar");
assertEquals("foo", a[pos+1]);
assertEquals(pos + 2, a.length);
assertEquals("bar", a[0]);
unshift_function_2(a, "baz", "boo");
assertEquals("foo", a[pos+3]);
assertEquals(pos + 4, a.length);
assertEquals("baz", a[0]);
assertEquals("boo", a[1]);
assertEquals("bar", a[2]);
// Shift.
// Skip VERYLARGE arrays, as we removed sparse support for shift.
// Slice is also skipped, since it relies on the "shift" test to be run.
if (pos < VERYLARGE) {
var baz = shift_function(a);
assertEquals("baz", baz);
assertEquals("boo", a[0]);
assertEquals(pos + 3, a.length);
assertEquals("foo", a[pos + 2]);
// Slice.
var bar = slice_function(a, 1, 0); // don't throw an exception please.
bar = slice_function(a, 1, 2);
assertEquals("bar", bar[0]);
assertEquals(1, bar.length);
assertEquals("bar", a[1]);
}
}
}
// Lets see if performance is reasonable.
var a = new Array(LARGE + 10);
for (var i = 0; i < a.length; i += 1000) {
a[i] = i;
}
// Take something near the end of the array.
for (var i = 0; i < 10; i++) {
var top = a.splice(LARGE, 5);
assertEquals(5, top.length);
assertEquals(LARGE, top[0]);
assertEquals("undefined", typeof(top[1]));
assertEquals(LARGE + 5, a.length);
a.splice(LARGE, 0, LARGE);
a.length = LARGE + 10;
}
var a = new Array(LARGE + 10);
for (var i = 0; i < a.length; i += fourhundredth) {
a[i] = i;
}
// Take something near the middle of the array.
for (var i = 0; i < 10; i++) {
var top = a.splice(LARGE >> 1, 5);
assertEquals(5, top.length);
assertEquals(LARGE >> 1, top[0]);
assertEquals("undefined", typeof(top[1]));
assertEquals(LARGE + 5, a.length);
a.splice(LARGE >> 1, 0, LARGE >> 1, void 0, void 0, void 0, void 0);
}
// Test http://b/issue?id=1202711
arr = [0];
arr.length = 2;
Array.prototype[1] = 1;
assertEquals(1, arr.pop());
assertEquals(0, arr.pop());
Array.prototype[1] = undefined;
// Test http://code.google.com/p/chromium/issues/detail?id=21860
Array.prototype.push.apply([], [1].splice(0, -(-1 % 5)));
// Check that the Array functions work also properly on non-Arrays
var receiver;
receiver = 'a string';
assertThrows(function(){
Array.prototype.push.call(receiver);
});
receiver = 0;
assertEquals(undefined, receiver.length);
assertEquals(0, Array.prototype.push.call(receiver));
assertEquals(1, Array.prototype.push.call(receiver, 'first'));
assertEquals(undefined, receiver.length);
receiver = {};
assertEquals(undefined, receiver.length);
assertEquals(0, Array.prototype.push.call(receiver));
assertEquals(0, Array.prototype.push.call(receiver));
assertEquals(0, receiver.length);
assertEquals(1, Array.prototype.push.call(receiver, 'first'));
assertEquals(1, receiver.length);
assertEquals('first', receiver[0]);
assertEquals(2, Array.prototype.push.call(receiver, 'second'));
assertEquals(2, receiver.length);
assertEquals('first', receiver[0]);
assertEquals('second', receiver[1]);
receiver = {'length': 10};
assertEquals(10, Array.prototype.push.call(receiver));
assertEquals(10, receiver.length);
assertEquals(11, Array.prototype.push.call(receiver, 'first'));
assertEquals(11, receiver.length);
assertEquals('first', receiver[10]);
assertEquals(13, Array.prototype.push.call(receiver, 'second', 'third'));
assertEquals(13, receiver.length);
assertEquals('first', receiver[10]);
assertEquals('second', receiver[11]);
assertEquals('third', receiver[12]);
receiver = {
get length() { return 10; },
set length(l) {}
};
assertEquals(10, Array.prototype.push.call(receiver));
assertEquals(10, receiver.length);
assertEquals(11, Array.prototype.push.call(receiver, 'first'));
assertEquals(10, receiver.length);
assertEquals('first', receiver[10]);
assertEquals(12, Array.prototype.push.call(receiver, 'second', 'third'));
assertEquals(10, receiver.length);
assertEquals('second', receiver[10]);
assertEquals('third', receiver[11]);
// readonly length
receiver = {
get length() { return 10; },
};
assertThrows(function(){
Array.prototype.push.call(receiver);
});
receiver = {
set length(l) {}
};
assertEquals(0, Array.prototype.push.call(receiver));
assertEquals(undefined, receiver.length);
assertEquals(1, Array.prototype.push.call(receiver, 'first'));
assertEquals(undefined, receiver.length);
assertEquals(2, Array.prototype.push.call(receiver, 'third', 'second'));
assertEquals(undefined, receiver.length);

View File

@ -0,0 +1,159 @@
// Copyright 2008 the V8 project authors. All rights reserved.
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following
// disclaimer in the documentation and/or other materials provided
// with the distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// This file contains a number of tests of array functions and their
// interaction with properties in the prototype chain.
//
// The behavior of SpiderMonkey is slightly different for arrays (see
// below). Our behavior is consistent and matches the bahavior of
// KJS.
var proto = { length:3, 0:'zero', 1:'one', 2:'two' }
function constructor() {};
constructor.prototype = proto;
// Set elements on the array prototype.
Array.prototype[0] = 'zero';
Array.prototype[1] = 'one';
Array.prototype[2] = 'two';
// ----------------------------------------------------------------------
// Helper functions.
// ----------------------------------------------------------------------
function assertHasOwnProperties(object, limit) {
for (var i = 0; i < limit; i++) {
assertTrue(object.hasOwnProperty(i));
}
}
// ----------------------------------------------------------------------
// shift.
// ----------------------------------------------------------------------
function runTest1() {
var nonArray = new constructor();
var array = ['zero', , 'two'];
// Shift away the zero.
assertEquals('zero', array.shift());
assertEquals('zero', Array.prototype.shift.call(nonArray));
// Check that the local object has properties 0 and 1 with the right
// values.
assertEquals(2, array.length);
assertEquals(2, nonArray.length);
assertHasOwnProperties(array, 2);
assertHasOwnProperties(nonArray, 2);
// Note: Spidermonkey is inconsistent here. It treats arrays
// differently from non-arrays. It only consults the prototype for
// non-arrays. Therefore, array[0] is undefined in Spidermonkey and
// 'one' in V8 and KJS.
assertEquals('one', array[0]);
assertEquals('one', nonArray[0]);
assertEquals('two', array[1]);
assertEquals('two', nonArray[1]);
// Get index 2 from the prototype.
assertEquals('two', array[2]);
assertEquals('two', nonArray[2]);
}
runTest1();
// ----------------------------------------------------------------------
// unshift.
// ----------------------------------------------------------------------
runTest2 = function() {
var nonArray = new constructor();
var array = ['zero', , 'two'];
// Unshift a new 'zero'.
assertEquals(4, array.unshift('zero'));
assertEquals(4, Array.prototype.unshift.call(nonArray, 'zero'));
// Check that the local object has properties 0 through 3 with the
// right values.
assertEquals(4, array.length);
assertEquals(4, nonArray.length);
assertHasOwnProperties(array, 4);
assertHasOwnProperties(nonArray, 4);
assertEquals('zero', array[0]);
assertEquals('zero', nonArray[0]);
assertEquals('zero', array[1]);
assertEquals('zero', nonArray[1]);
// Again Spidermonkey is inconsistent. array[2] is undefined
// instead of 'one'.
assertEquals('one', array[2]);
assertEquals('one', nonArray[2]);
assertEquals('two', array[3]);
assertEquals('two', nonArray[3]);
}
runTest2();
// ----------------------------------------------------------------------
// splice
// ----------------------------------------------------------------------
runTest3 = function() {
var nonArray = new constructor();
var array = ['zero', , 'two'];
// Delete the first element by splicing in nothing.
assertArrayEquals(['zero'], array.splice(0, 1));
assertArrayEquals(['zero'], Array.prototype.splice.call(nonArray, 0, 1));
// Check that the local object has properties 0 and 1 with the right
// values.
assertEquals(2, array.length);
assertEquals(2, nonArray.length);
assertHasOwnProperties(array, 2);
assertHasOwnProperties(nonArray, 2);
// Again Spidermonkey is inconsistent. array[0] is undefined
// instead of 'one'.
assertEquals('one', array[0]);
assertEquals('one', nonArray[0]);
assertEquals('two', array[1]);
assertEquals('two', nonArray[1]);
// Get index 2 from the prototype.
assertEquals('two', array[2]);
assertEquals('two', nonArray[2]);
};
runTest3();
// ----------------------------------------------------------------------
// slice
// ----------------------------------------------------------------------
runTest4 = function() {
var nonArray = new constructor();
var array = ['zero', , 'two'];
// Again Spidermonkey is inconsistent. (array.slice(0, 3))[1] is
// undefined instead of 'one'.
assertArrayEquals(['zero', 'one', 'two'], array.slice(0, 3));
assertArrayEquals(['zero', 'one', 'two'], Array.prototype.slice.call(nonArray, 0, 3));
};
runTest4();

View File

@ -0,0 +1,151 @@
// Copyright 2022 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.
// Large array of packed Smi, and Smi search_element
(() => {
let a = [];
for (let i = 0; i < 200; i++) {
a[i] = i;
}
function testArrayIncludes(idx) {
return a.includes(idx);
}
// Without fromIndex
for (let i = 0; i < 200; i++) {
assertEquals(true, testArrayIncludes(i));
}
// With fromIndex
for (let i = 0, from_index = 0; i+from_index < 200; i += 2, from_index++) {
assertEquals(true, testArrayIncludes(i, from_index));
}
})();
// Large array of holey Smi, and Smi search_element
(() => {
let a = [];
// Skipping every other item when initializing
for (let i = 0; i < 200; i+=2) {
a[i] = i;
}
function testArrayIncludes(idx) {
return a.includes(idx);
}
// Without fromIndex
for (let i = 0; i < 200; i++) {
if (i % 2 == 0) {
assertEquals(true, testArrayIncludes(i));
} else {
assertEquals(false, testArrayIncludes(i));
}
}
// With fromIndex
for (let i = 0, from_index = 0; i + from_index < 200; i += 2, from_index++) {
if (i % 2 == 0) {
assertEquals(true, testArrayIncludes(i, from_index));
} else {
assertEquals(false, testArrayIncludes(i, from_index));
}
}
})();
// Large array of packed Doubles, and Double search_element
(() => {
let a = [];
for (let i = 0; i < 200; i++) {
a[i] = i + 0.5;
}
function testArrayIncludes(idx) {
return a.includes(idx);
}
// Without fromIndex
for (let i = 0; i < 200; i++) {
assertEquals(true, testArrayIncludes(i + 0.5));
}
// With fromIndex
for (let i = 0, from_index = 0; i+from_index < 200; i += 2, from_index++) {
assertEquals(true, testArrayIncludes(i+0.5, from_index));
}
})();
// Large array of holey Doubles, and Double search_element
(() => {
let a = [];
// Skipping every other item when initializing
for (let i = 0; i < 200; i+=2) {
a[i] = i + 0.5;
}
function testArrayIncludes(idx) {
return a.includes(idx);
}
// Without fromIndex
for (let i = 0; i < 200; i++) {
if (i % 2 == 0) {
assertEquals(true, testArrayIncludes(i + 0.5));
} else {
assertEquals(false, testArrayIncludes(i + 0.5));
}
}
// With fromIndex
for (let i = 0, from_index = 0; i + from_index < 200; i += 2, from_index++) {
if (i % 2 == 0) {
assertEquals(true, testArrayIncludes(i+0.5, from_index));
} else {
assertEquals(false, testArrayIncludes(i+0.5, from_index));
}
}
})();
// Large array of packed objects, and object search_element
(() => {
let a = [];
let b = [];
for (let i = 0; i < 200; i++) {
a[i] = { v: i };
b[i] = a[i];
}
function testArrayIncludes(idx) {
return a.includes(idx);
}
// Without fromIndex
for (let i = 0; i < 200; i++) {
assertEquals(true, testArrayIncludes(b[i]));
}
// With fromIndex
for (let i = 0, from_index = 0; i+from_index < 200; i += 2, from_index++) {
assertEquals(true, testArrayIncludes(b[i], from_index));
}
})();
// Large array of holey objects, and object search_element
(() => {
let a = [];
let b = [];
// Skipping every other item when initializing
for (let i = 0; i < 200; i++) {
b[i] = { v: i };
if (i % 2 == 0) {
a[i] = b[i];
}
}
function testArrayIncludes(idx) {
return a.includes(idx);
}
// Without fromIndex
for (let i = 0; i < 200; i++) {
if (i % 2 == 0) {
assertEquals(true, testArrayIncludes(b[i]));
} else {
assertEquals(false, testArrayIncludes(b[i]));
}
}
// With fromIndex
for (let i = 0, from_index = 0; i + from_index < 200; i += 2, from_index++) {
if (i % 2 == 0) {
assertEquals(true, testArrayIncludes(b[i], from_index));
} else {
assertEquals(false, testArrayIncludes(b[i], from_index));
}
}
})();

View File

@ -0,0 +1,634 @@
// 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 --expose-gc
// Ensure `Array.prototype.indexOf` functions correctly for numerous elements
// kinds, and various exotic receiver types,
var kIterCount = 1;
var kTests = {
Array: {
PACKED_ELEMENTS() {
var r = /foo/;
var s = new String("bar");
var p = new Proxy({}, {});
var o = {};
var array = [r, s, p];
assertTrue(%HasObjectElements(array));
assertFalse(%HasHoleyElements(array));
for (var i = 0; i < kIterCount; ++i) {
assertEquals(array.indexOf(p), 2);
assertEquals(array.indexOf(o), -1);
}
},
HOLEY_ELEMENTS() {
var r = /foo/;
var p = new Proxy({}, {});
var o = {};
var array = [r, , p];
assertTrue(%HasObjectElements(array));
assertTrue(%HasHoleyElements(array));
for (var i = 0; i < kIterCount; ++i) {
assertEquals(array.indexOf(p), 2);
assertEquals(array.indexOf(o), -1);
}
},
PACKED_SMI_ELEMENTS() {
var array = [0, 88, 9999, 1, -5, 7];
assertTrue(%HasSmiElements(array));
assertFalse(%HasHoleyElements(array));
for (var i = 0; i < kIterCount; ++i) {
assertEquals(array.indexOf(9999), 2);
assertEquals(array.indexOf(-5), 4);
assertEquals(array.indexOf(-5.00001), -1);
assertEquals(array.indexOf(undefined), -1);
assertEquals(array.indexOf(NaN), -1);
}
},
HOLEY_SMI_ELEMENTS() {
var array = [49, , , 72, , , 67, -48];
assertTrue(%HasSmiElements(array));
assertTrue(%HasHoleyElements(array));
for (var i = 0; i < kIterCount; ++i) {
assertEquals(array.indexOf(72), 3);
assertEquals(array.indexOf(-48), 7);
assertEquals(array.indexOf(72, 4), -1);
assertEquals(array.indexOf(undefined), -1);
assertEquals(array.indexOf(undefined, -2), -1);
assertEquals(array.indexOf(NaN), -1);
}
},
PACKED_DOUBLE_ELEMENTS() {
var array = [7.00000001, -13000.89412, 73451.4124,
5824.48, 6.0000495, 48.3488, 44.0, 76.35, NaN, 78.4];
assertTrue(%HasDoubleElements(array));
assertFalse(%HasHoleyElements(array));
for (var i = 0; i < kIterCount; ++i) {
assertEquals(array.indexOf(7.00000001), 0);
assertEquals(array.indexOf(7.00000001, 2), -1);
assertEquals(array.indexOf(NaN), -1);
assertEquals(array.indexOf(NaN, -1), -1);
assertEquals(array.indexOf(-13000.89412), 1);
assertEquals(array.indexOf(-13000.89412, -2), -1);
assertEquals(array.indexOf(undefined), -1);
}
},
HOLEY_DOUBLE_ELEMENTS() {
var array = [7.00000001, -13000.89412, ,
5824.48, , 48.3488, , NaN, , 78.4];
assertTrue(%HasDoubleElements(array));
assertTrue(%HasHoleyElements(array));
for (var i = 0; i < kIterCount; ++i) {
assertEquals(array.indexOf(7.00000001), 0);
assertEquals(array.indexOf(7.00000001, 2), -1);
assertEquals(array.indexOf(NaN), -1);
assertEquals(array.indexOf(NaN, -2), -1);
assertEquals(array.indexOf(-13000.89412), 1);
assertEquals(array.indexOf(-13000.89412, -2), -1);
assertEquals(array.indexOf(undefined, -2), -1);
assertEquals(array.indexOf(undefined, -1), -1);
}
},
DICTIONARY_ELEMENTS() {
var array = [];
Object.defineProperty(array, 4, { get() { gc(); return NaN; } });
Object.defineProperty(array, 7, { value: Function });
assertTrue(%HasDictionaryElements(array));
for (var i = 0; i < kIterCount; ++i) {
assertEquals(array.indexOf(NaN), -1);
assertEquals(array.indexOf(NaN, -3), -1);
assertEquals(array.indexOf(Function), 7);
assertEquals(array.indexOf(undefined), -1);
assertEquals(array.indexOf(undefined, 7), -1);
}
},
},
Object: {
PACKED_ELEMENTS() {
var r = /foo/;
var s = new String("bar");
var p = new Proxy({}, {});
var o = {};
var object = { 0: r, 1: s, 2: p, length: 3 };
assertTrue(%HasObjectElements(object));
// TODO(caitp): JSObjects always seem to start with HOLEY_ELEMENTS
// assertFalse(%HasHoleyElements(object));
for (var i = 0; i < kIterCount; ++i) {
assertEquals(Array.prototype.indexOf.call(object, p), 2);
assertEquals(Array.prototype.indexOf.call(object, o), -1);
}
},
HOLEY_ELEMENTS() {
var r = /foo/;
var p = new Proxy({}, {});
var o = {};
var object = { 0: r, 2: p, length: 3 };
assertTrue(%HasObjectElements(object));
assertTrue(%HasHoleyElements(object));
for (var i = 0; i < kIterCount; ++i) {
assertEquals(Array.prototype.indexOf.call(object, p), 2);
assertEquals(Array.prototype.indexOf.call(object, o), -1);
}
},
PACKED_SMI_ELEMENTS() {
var object = { 0: 0, 1: 88, 2: 9999, 3: 1, 4: -5, 5: 7, length: 6 };
// TODO(caitp): JSObjects always seem to start with HOLEY_ELEMENTS
// assertTrue(%HasSmiElements(object));
// assertFalse(%HasHoleyElements(object));
for (var i = 0; i < kIterCount; ++i) {
assertEquals(Array.prototype.indexOf.call(object, 9999), 2);
assertEquals(Array.prototype.indexOf.call(object, -5), 4);
assertEquals(Array.prototype.indexOf.call(object, -5.00001), -1);
assertEquals(Array.prototype.indexOf.call(object, undefined), -1);
assertEquals(Array.prototype.indexOf.call(object, NaN), -1);
}
},
HOLEY_SMI_ELEMENTS() {
var object = { 0: 49, 3: 72, 6: 67, 7: -48, length: 8 };
// TODO(caitp): JSObjects always seem to start with HOLEY_ELEMENTS
// assertTrue(%HasSmiElements(object));
// assertTrue(%HasHoleyElements(object));
for (var i = 0; i < kIterCount; ++i) {
assertEquals(Array.prototype.indexOf.call(object, 72), 3);
assertEquals(Array.prototype.indexOf.call(object, -48), 7);
assertEquals(Array.prototype.indexOf.call(object, 72, 4), -1);
assertEquals(Array.prototype.indexOf.call(object, undefined), -1);
assertEquals(Array.prototype.indexOf.call(object, undefined, -2), -1);
assertEquals(Array.prototype.indexOf.call(object, NaN), -1);
}
},
PACKED_DOUBLE_ELEMENTS() {
var object = { 0: 7.00000001, 1: -13000.89412, 2: 73451.4124,
3: 5824.48, 4: 6.0000495, 5: 48.3488, 6: 44.0, 7: 76.35,
8: NaN, 9: 78.4, length: 10 };
// TODO(caitp): JSObjects always seem to start with HOLEY_ELEMENTS
// assertTrue(%HasDoubleElements(object));
// assertFalse(%HasHoleyElements(object));
for (var i = 0; i < kIterCount; ++i) {
assertEquals(Array.prototype.indexOf.call(object, 7.00000001), 0);
assertEquals(Array.prototype.indexOf.call(object, 7.00000001, 2), -1);
assertEquals(Array.prototype.indexOf.call(object, NaN), -1);
assertEquals(Array.prototype.indexOf.call(object, NaN, -1), -1);
assertEquals(Array.prototype.indexOf.call(object, -13000.89412), 1);
assertEquals(Array.prototype.indexOf.call(object, -13000.89412, -2), -1);
assertEquals(Array.prototype.indexOf.call(object, undefined), -1);
}
},
HOLEY_DOUBLE_ELEMENTS() {
var object = { 0: 7.00000001, 1: -13000.89412, 3: 5824.48, 5: 48.3488,
7: NaN, 9: 78.4, length: 10 };
// TODO(caitp): JSObjects always seem to start with HOLEY_ELEMENTS
// assertTrue(%HasDoubleElements(object));
// assertTrue(%HasHoleyElements(object));
for (var i = 0; i < kIterCount; ++i) {
assertEquals(Array.prototype.indexOf.call(object, 7.00000001), 0);
assertEquals(Array.prototype.indexOf.call(object, 7.00000001, 2), -1);
assertEquals(Array.prototype.indexOf.call(object, NaN), -1);
assertEquals(Array.prototype.indexOf.call(object, NaN, -2), -1);
assertEquals(Array.prototype.indexOf.call(object, -13000.89412), 1);
assertEquals(Array.prototype.indexOf.call(object, -13000.89412, -2), -1);
assertEquals(Array.prototype.indexOf.call(object, undefined, -2), -1);
assertEquals(Array.prototype.indexOf.call(object, undefined, -1), -1);
}
},
DICTIONARY_ELEMENTS() {
var object = { length: 8 };
Object.defineProperty(object, 4, { get() { gc(); return NaN; } });
Object.defineProperty(object, 7, { value: Function });
assertTrue(%HasDictionaryElements(object));
for (var i = 0; i < kIterCount; ++i) {
assertEquals(Array.prototype.indexOf.call(object, NaN), -1);
assertEquals(Array.prototype.indexOf.call(object, NaN, -3), -1);
assertEquals(Array.prototype.indexOf.call(object, Function), 7);
assertEquals(Array.prototype.indexOf.call(object, undefined), -1);
assertEquals(Array.prototype.indexOf.call(object, undefined, 7), -1);
}
(function prototypeModifiedDuringAccessor() {
function O() {
return {
__proto__: {},
get 0() {
gc();
this.__proto__.__proto__ = {
get 1() {
gc();
this[2] = "c";
return "b";
}
};
return "a";
},
length: 3
};
}
// Switch to slow path when first accessor modifies the prototype
assertEquals(Array.prototype.indexOf.call(O(), "a"), 0);
assertEquals(Array.prototype.indexOf.call(O(), "b"), 1);
assertEquals(Array.prototype.indexOf.call(O(), "c"), 2);
// Avoid switching to slow path due to avoiding the accessor
assertEquals(Array.prototype.indexOf.call(O(), "c", 2), -1);
assertEquals(Array.prototype.indexOf.call(O(), "b", 1), -1);
assertEquals(Array.prototype.indexOf.call(O(), undefined, 1), 1);
});
},
},
String: {
FAST_STRING_ELEMENTS() {
for (var i = 0; i < kIterCount; ++i) {
assertEquals(Array.prototype.indexOf.call("froyo", "y"), 3);
assertEquals(Array.prototype.indexOf.call("froyo", "y", -1), -1);
assertEquals(Array.prototype.indexOf.call("froyo", "y", -2), 3);
assertEquals(Array.prototype.indexOf.call("froyo", NaN), -1);
assertEquals(Array.prototype.indexOf.call("froyo", undefined), -1);
}
},
SLOW_STRING_ELEMENTS() {
var string = new String("froyo");
// Never accessible from A.p.indexOf as 'length' is not configurable
Object.defineProperty(string, 34, { value: NaN });
Object.defineProperty(string, 12, { get() { return "nope" } });
for (var i = 0; i < kIterCount; ++i) {
assertEquals(Array.prototype.indexOf.call("froyo", "y"), 3);
assertEquals(Array.prototype.indexOf.call("froyo", "y", -1), -1);
assertEquals(Array.prototype.indexOf.call("froyo", "y", -2), 3);
assertEquals(Array.prototype.indexOf.call(string, NaN), -1);
assertEquals(Array.prototype.indexOf.call(string, undefined), -1);
assertEquals(Array.prototype.indexOf.call(string, "nope"), -1);
}
},
},
Arguments: {
FAST_SLOPPY_ARGUMENTS_ELEMENTS() {
var args = (function(a, b) { return arguments; })("foo", NaN, "bar");
assertTrue(%HasSloppyArgumentsElements(args));
for (var i = 0; i < kIterCount; ++i) {
assertEquals(Array.prototype.indexOf.call(args, undefined), -1);
assertEquals(Array.prototype.indexOf.call(args, NaN), -1);
assertEquals(Array.prototype.indexOf.call(args, NaN, -1), -1);
assertEquals(Array.prototype.indexOf.call(args, "bar", -1), 2);
}
},
SLOW_SLOPPY_ARGUMENTS_ELEMENTS() {
var args = (function(a, a) { return arguments; })("foo", NaN, "bar");
Object.defineProperty(args, 3, { get() { gc(); return "silver"; } });
Object.defineProperty(args, "length", { value: 4 });
assertTrue(%HasSloppyArgumentsElements(args));
for (var i = 0; i < kIterCount; ++i) {
assertEquals(Array.prototype.indexOf.call(args, undefined), -1);
assertEquals(Array.prototype.indexOf.call(args, NaN), -1);
assertEquals(Array.prototype.indexOf.call(args, NaN, -2), -1);
assertEquals(Array.prototype.indexOf.call(args, "bar", -2), 2);
assertEquals(Array.prototype.indexOf.call(args, "silver", -1), 3);
}
}
},
TypedArray: {
Int8Array() {
var array = new Int8Array([-129, 128,
NaN /* 0 */, +0 /* 0 */, -0 /* 0 */,
+Infinity /* 0 */, -Infinity /* 0 */,
255 /* -1 */, 127 /* 127 */, -255 /* 1 */]);
assertEquals(Array.prototype.indexOf.call(array, -129), -1);
assertEquals(Array.prototype.indexOf.call(array, 128), -1);
assertEquals(Array.prototype.indexOf.call(array, 0, 2), 2);
assertEquals(Array.prototype.indexOf.call(array, 0, 3), 3);
assertEquals(Array.prototype.indexOf.call(array, 0, 4), 4);
assertEquals(Array.prototype.indexOf.call(array, 0, 5), 5);
assertEquals(Array.prototype.indexOf.call(array, 0, 6), 6);
assertEquals(Array.prototype.indexOf.call(array, 0, 7), -1);
assertEquals(Array.prototype.indexOf.call(array, -1, 7), 7);
assertEquals(Array.prototype.indexOf.call(array, -1, 8), -1);
assertEquals(Array.prototype.indexOf.call(array, 127, 8), 8);
assertEquals(Array.prototype.indexOf.call(array, 127, 9), -1);
assertEquals(Array.prototype.indexOf.call(array, 1, 9), 9);
},
Detached_Int8Array() {
var array = new Int8Array(10);
%ArrayBufferDetach(array.buffer);
assertEquals(Array.prototype.indexOf.call(array, 0), -1);
assertEquals(Array.prototype.indexOf.call(array, 0, 10), -1);
},
Uint8Array() {
var array = new Uint8Array([-1, 256,
NaN /* 0 */, +0 /* 0 */, -0 /* 0 */,
+Infinity /* 0 */, -Infinity /* 0 */,
255 /* 255 */, 257 /* 1 */, -128 /* 128 */,
-2 /* 254 */]);
assertEquals(Array.prototype.indexOf.call(array, -1), -1);
assertEquals(Array.prototype.indexOf.call(array, 256), -1);
assertEquals(Array.prototype.indexOf.call(array, 0, 2), 2);
assertEquals(Array.prototype.indexOf.call(array, 0, 3), 3);
assertEquals(Array.prototype.indexOf.call(array, 0, 4), 4);
assertEquals(Array.prototype.indexOf.call(array, 0, 5), 5);
assertEquals(Array.prototype.indexOf.call(array, 0, 6), 6);
assertEquals(Array.prototype.indexOf.call(array, 0, 7), -1);
assertEquals(Array.prototype.indexOf.call(array, 255, 7), 7);
assertEquals(Array.prototype.indexOf.call(array, 255, 8), -1);
assertEquals(Array.prototype.indexOf.call(array, 1, 8), 8);
assertEquals(Array.prototype.indexOf.call(array, 1, 9), -1);
assertEquals(Array.prototype.indexOf.call(array, 128, 9), 9);
assertEquals(Array.prototype.indexOf.call(array, 128, 10), -1);
assertEquals(Array.prototype.indexOf.call(array, 254, 10), 10);
},
Detached_Uint8Array() {
var array = new Uint8Array(10);
%ArrayBufferDetach(array.buffer);
assertEquals(Array.prototype.indexOf.call(array, 0), -1);
assertEquals(Array.prototype.indexOf.call(array, 0, 10), -1);
},
Uint8ClampedArray() {
var array = new Uint8ClampedArray([-1 /* 0 */, NaN /* 0 */, 256 /* 255 */,
127.6 /* 128 */, 127.4 /* 127 */,
121.5 /* 122 */, 124.5 /* 124 */]);
assertEquals(Array.prototype.indexOf.call(array, -1), -1);
assertEquals(Array.prototype.indexOf.call(array, 256), -1);
assertEquals(Array.prototype.indexOf.call(array, 0), 0);
assertEquals(Array.prototype.indexOf.call(array, 0, 1), 1);
assertEquals(Array.prototype.indexOf.call(array, 255, 2), 2);
assertEquals(Array.prototype.indexOf.call(array, 128, 3), 3);
assertEquals(Array.prototype.indexOf.call(array, 128, 4), -1);
assertEquals(Array.prototype.indexOf.call(array, 127, 4), 4);
assertEquals(Array.prototype.indexOf.call(array, 127, 5), -1);
assertEquals(Array.prototype.indexOf.call(array, 122, 5), 5);
assertEquals(Array.prototype.indexOf.call(array, 122, 6), -1);
assertEquals(Array.prototype.indexOf.call(array, 124, 6), 6);
},
Detached_Uint8ClampedArray() {
var array = new Uint8ClampedArray(10);
%ArrayBufferDetach(array.buffer);
assertEquals(Array.prototype.indexOf.call(array, 0), -1);
assertEquals(Array.prototype.indexOf.call(array, 0, 10), -1);
},
Int16Array() {
var array = new Int16Array([-32769, 32768,
NaN /* 0 */, Infinity /* 0 */,
-Infinity /* 0 */, -0 /* 0 */, +0 /* 0 */,
0x7FFFF /* -1 */, 30000 /* 30000 */,
300000 /* -27680 */]);
assertEquals(Array.prototype.indexOf.call(array, -32769), -1);
assertEquals(Array.prototype.indexOf.call(array, 32768), -1);
assertEquals(Array.prototype.indexOf.call(array, 0, 2), 2);
assertEquals(Array.prototype.indexOf.call(array, 0, 3), 3);
assertEquals(Array.prototype.indexOf.call(array, 0, 4), 4);
assertEquals(Array.prototype.indexOf.call(array, 0, 5), 5);
assertEquals(Array.prototype.indexOf.call(array, 0, 6), 6);
assertEquals(Array.prototype.indexOf.call(array, 0, 7), -1);
assertEquals(Array.prototype.indexOf.call(array, -1, 7), 7);
assertEquals(Array.prototype.indexOf.call(array, -1, 8), -1);
assertEquals(Array.prototype.indexOf.call(array, 30000, 8), 8);
assertEquals(Array.prototype.indexOf.call(array, 30000, 9), -1);
assertEquals(Array.prototype.indexOf.call(array, -27680, 9), 9);
},
Detached_Int16Array() {
var array = new Int16Array(10);
%ArrayBufferDetach(array.buffer);
assertEquals(Array.prototype.indexOf.call(array, 0), -1);
assertEquals(Array.prototype.indexOf.call(array, 0, 10), -1);
},
Uint16Array() {
var array = new Uint16Array([-1, 65536,
NaN /* 0 */, Infinity /* 0 */,
-Infinity /* 0 */, -0 /* 0 */, +0 /* 0 */,
0x7FFFF /* 65535 */, 300000 /* 37856 */,
3000000 /* 50880 */]);
assertEquals(Array.prototype.indexOf.call(array, -1), -1);
assertEquals(Array.prototype.indexOf.call(array, 65536), -1);
assertEquals(Array.prototype.indexOf.call(array, 0, 2), 2);
assertEquals(Array.prototype.indexOf.call(array, 0, 3), 3);
assertEquals(Array.prototype.indexOf.call(array, 0, 4), 4);
assertEquals(Array.prototype.indexOf.call(array, 0, 5), 5);
assertEquals(Array.prototype.indexOf.call(array, 0, 6), 6);
assertEquals(Array.prototype.indexOf.call(array, 0, 7), -1);
assertEquals(Array.prototype.indexOf.call(array, 65535, 7), 7);
assertEquals(Array.prototype.indexOf.call(array, 65535, 8), -1);
assertEquals(Array.prototype.indexOf.call(array, 37856, 8), 8);
assertEquals(Array.prototype.indexOf.call(array, 37856, 9), -1);
assertEquals(Array.prototype.indexOf.call(array, 50880, 9), 9);
},
Detached_Uint16Array() {
var array = new Uint16Array(10);
%ArrayBufferDetach(array.buffer);
assertEquals(Array.prototype.indexOf.call(array, 0), -1);
assertEquals(Array.prototype.indexOf.call(array, 0, 10), -1);
},
Int32Array() {
var array = new Int32Array([-2147483649, 2147483648,
NaN /* 0 */, Infinity /* 0 */,
-Infinity /* 0 */, -0 /* 0 */, +0 /* 0 */,
0x7FFFFFFFF /* -1 */, 4294968064 /* 768 */,
4294959447 /* -7849 */]);
assertEquals(Array.prototype.indexOf.call(array, -2147483649), -1);
assertEquals(Array.prototype.indexOf.call(array, 2147483648), -1);
assertEquals(Array.prototype.indexOf.call(array, 0.0, 2), 2);
assertEquals(Array.prototype.indexOf.call(array, 0.0, 3), 3);
assertEquals(Array.prototype.indexOf.call(array, 0, 4), 4);
assertEquals(Array.prototype.indexOf.call(array, 0, 5), 5);
assertEquals(Array.prototype.indexOf.call(array, 0.0, 6), 6);
assertEquals(Array.prototype.indexOf.call(array, 0.0, 7), -1);
assertEquals(Array.prototype.indexOf.call(array, -1, 7), 7);
assertEquals(Array.prototype.indexOf.call(array, -1, 8), -1);
assertEquals(Array.prototype.indexOf.call(array, 768, 8), 8);
assertEquals(Array.prototype.indexOf.call(array, 768, 9), -1);
assertEquals(Array.prototype.indexOf.call(array, -7849, 9), 9);
},
Detached_Int32Array() {
var array = new Int32Array(10);
%ArrayBufferDetach(array.buffer);
assertEquals(Array.prototype.indexOf.call(array, 0), -1);
assertEquals(Array.prototype.indexOf.call(array, 0, 10), -1);
},
Uint32Array() {
var array = new Uint32Array([-1, 4294967296,
NaN /* 0 */, Infinity /* 0 */,
-Infinity /* 0 */, -0 /* 0 */, +0 /* 0 */,
0x7FFFFFFFF /* 4294967295 */,
4294968064 /* 768 */,
4295079447 /* 112151 */]);
assertEquals(Array.prototype.indexOf.call(array, -1), -1);
assertEquals(Array.prototype.indexOf.call(array, 4294967296), -1);
assertEquals(Array.prototype.indexOf.call(array, 0.0, 2), 2);
assertEquals(Array.prototype.indexOf.call(array, 0.0, 3), 3);
assertEquals(Array.prototype.indexOf.call(array, 0, 4), 4);
assertEquals(Array.prototype.indexOf.call(array, 0, 5), 5);
assertEquals(Array.prototype.indexOf.call(array, 0.0, 6), 6);
assertEquals(Array.prototype.indexOf.call(array, 0.0, 7), -1);
assertEquals(Array.prototype.indexOf.call(array, 4294967295, 7), 7);
assertEquals(Array.prototype.indexOf.call(array, 4294967295, 8), -1);
assertEquals(Array.prototype.indexOf.call(array, 768, 8), 8);
assertEquals(Array.prototype.indexOf.call(array, 768, 9), -1);
assertEquals(Array.prototype.indexOf.call(array, 112151, 9), 9);
},
Detached_Uint32Array() {
var array = new Uint32Array(10);
%ArrayBufferDetach(array.buffer);
assertEquals(Array.prototype.indexOf.call(array, 0), -1);
assertEquals(Array.prototype.indexOf.call(array, 0, 10), -1);
},
Float32Array() {
var array = new Float32Array([-1, 4294967296,
NaN, Infinity /* 0 */,
-Infinity /* 0 */, -0 /* 0 */, +0 /* 0 */,
0x7FFFFFFFF /* 34359738368.0 */,
-4294968064 /* -4294968320.0 */,
4295079447 /* 4295079424.0 */]);
assertEquals(Array.prototype.indexOf.call(array, -1.0), 0);
assertEquals(Array.prototype.indexOf.call(array, 4294967296), 1);
assertEquals(Array.prototype.indexOf.call(array, NaN, 2), -1);
assertEquals(Array.prototype.indexOf.call(array, Infinity, 3), 3);
assertEquals(Array.prototype.indexOf.call(array, -Infinity, 4), 4);
assertEquals(Array.prototype.indexOf.call(array, 0, 5), 5);
assertEquals(Array.prototype.indexOf.call(array, 0, 6), 6);
assertEquals(Array.prototype.indexOf.call(array, 0.0, 7), -1);
assertEquals(Array.prototype.indexOf.call(array, 34359738368.0, 7), 7);
assertEquals(Array.prototype.indexOf.call(array, 34359738368.0, 8), -1);
assertEquals(Array.prototype.indexOf.call(array, -4294968320.0, 8), 8);
assertEquals(Array.prototype.indexOf.call(array, -4294968320.0, 9), -1);
assertEquals(Array.prototype.indexOf.call(array, 4295079424.0, 9), 9);
},
Detached_Float32Array() {
var array = new Float32Array(10);
%ArrayBufferDetach(array.buffer);
assertEquals(Array.prototype.indexOf.call(array, 0), -1);
assertEquals(Array.prototype.indexOf.call(array, 0, 10), -1);
},
Float64Array() {
var array = new Float64Array([-1, 4294967296,
NaN, Infinity /* 0 */,
-Infinity /* 0 */, -0 /* 0 */, +0 /* 0 */,
0x7FFFFFFFF /* 34359738367.0 */,
-4294968064 /* -4294968064.0 */,
4295079447 /* 4295079447.0 */]);
assertEquals(Array.prototype.indexOf.call(array, -1.0), 0);
assertEquals(Array.prototype.indexOf.call(array, 4294967296), 1);
assertEquals(Array.prototype.indexOf.call(array, NaN, 2), -1);
assertEquals(Array.prototype.indexOf.call(array, Infinity, 3), 3);
assertEquals(Array.prototype.indexOf.call(array, -Infinity, 4), 4);
assertEquals(Array.prototype.indexOf.call(array, 0, 5), 5);
assertEquals(Array.prototype.indexOf.call(array, 0, 6), 6);
assertEquals(Array.prototype.indexOf.call(array, 0.0, 7), -1);
assertEquals(Array.prototype.indexOf.call(array, 34359738367.0, 7), 7);
assertEquals(Array.prototype.indexOf.call(array, 34359738367.0, 8), -1);
assertEquals(Array.prototype.indexOf.call(array, -4294968064.0, 8), 8);
assertEquals(Array.prototype.indexOf.call(array, -4294968064.0, 9), -1);
assertEquals(Array.prototype.indexOf.call(array, 4295079447.0, 9), 9);
},
Detached_Float64Array() {
var array = new Float32Array(10);
%ArrayBufferDetach(array.buffer);
assertEquals(Array.prototype.indexOf.call(array, 0), -1);
assertEquals(Array.prototype.indexOf.call(array, 0, 10), -1);
},
}
};
function runSuites(suites) {
Object.keys(suites).forEach(suite => runSuite(suites[suite]));
function runSuite(suite) {
Object.keys(suite).forEach(test => suite[test]());
}
}
runSuites(kTests);

187
deps/v8/test/mjsunit/array-indexing.js vendored Normal file
View File

@ -0,0 +1,187 @@
// Copyright 2008 the V8 project authors. All rights reserved.
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following
// disclaimer in the documentation and/or other materials provided
// with the distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
var array = [1,2,3,1,2,3,1,2,3,1,2,3];
var undef_array = [0,,2,undefined,4,,6,undefined,8,,10];
// Sparse arrays with length 42000.
var sparse_array = [];
sparse_array[100] = 3;
sparse_array[200] = undefined;
sparse_array[300] = 4;
sparse_array[400] = 5;
sparse_array[500] = 6;
sparse_array[600] = 5;
sparse_array[700] = 4;
sparse_array[800] = undefined;
sparse_array[900] = 3
sparse_array[41999] = "filler";
var dense_object = { 0: 42, 1: 37, length: 2 };
var sparse_object = { 0: 42, 100000: 37, length: 200000 };
var funky_object = { 10:42, 100000: 42, 100001: 37, length: 50000 };
var infinite_object = { 10: 42, 100000: 37, length: Infinity };
// ----------------------------------------------------------------------
// Array.prototype.indexOf.
// ----------------------------------------------------------------------
// Negative cases.
assertEquals(-1, [].indexOf(1));
assertEquals(-1, array.indexOf(4));
assertEquals(-1, array.indexOf(3, array.length));
assertEquals(2, array.indexOf(3));
// Negative index out of range.
assertEquals(0, array.indexOf(1, -17));
// Negative index in rage.
assertEquals(3, array.indexOf(1, -11));
// Index in range.
assertEquals(3, array.indexOf(1, 1));
assertEquals(3, array.indexOf(1, 3));
assertEquals(6, array.indexOf(1, 4));
// Find undefined, not holes.
assertEquals(3, undef_array.indexOf(undefined));
assertEquals(3, undef_array.indexOf(undefined, 3));
assertEquals(7, undef_array.indexOf(undefined, 4));
assertEquals(7, undef_array.indexOf(undefined, 7));
assertEquals(-1, undef_array.indexOf(undefined, 8));
assertEquals(3, undef_array.indexOf(undefined, -11));
assertEquals(3, undef_array.indexOf(undefined, -8));
assertEquals(7, undef_array.indexOf(undefined, -7));
assertEquals(7, undef_array.indexOf(undefined, -4));
assertEquals(-1, undef_array.indexOf(undefined, -3));
// Find in sparse array.
assertEquals(100, sparse_array.indexOf(3));
assertEquals(900, sparse_array.indexOf(3, 101));
assertEquals(-1, sparse_array.indexOf(3, 901));
assertEquals(100, sparse_array.indexOf(3, -42000));
assertEquals(900, sparse_array.indexOf(3, 101 - 42000));
assertEquals(-1, sparse_array.indexOf(3, 901 - 42000));
assertEquals(300, sparse_array.indexOf(4));
assertEquals(700, sparse_array.indexOf(4, 301));
assertEquals(-1, sparse_array.indexOf(4, 701));
assertEquals(300, sparse_array.indexOf(4, -42000));
assertEquals(700, sparse_array.indexOf(4, 301 - 42000));
assertEquals(-1, sparse_array.indexOf(4, 701 - 42000));
assertEquals(200, sparse_array.indexOf(undefined));
assertEquals(800, sparse_array.indexOf(undefined, 201));
assertEquals(-1, sparse_array.indexOf(undefined, 801));
assertEquals(200, sparse_array.indexOf(undefined, -42000));
assertEquals(800, sparse_array.indexOf(undefined, 201 - 42000));
assertEquals(-1, sparse_array.indexOf(undefined, 801 - 42000));
// Find in non-arrays.
assertEquals(0, Array.prototype.indexOf.call(dense_object, 42));
assertEquals(1, Array.prototype.indexOf.call(dense_object, 37));
assertEquals(-1, Array.prototype.indexOf.call(dense_object, 87));
assertEquals(0, Array.prototype.indexOf.call(sparse_object, 42));
assertEquals(100000, Array.prototype.indexOf.call(sparse_object, 37));
assertEquals(-1, Array.prototype.indexOf.call(sparse_object, 87));
assertEquals(10, Array.prototype.indexOf.call(funky_object, 42));
assertEquals(-1, Array.prototype.indexOf.call(funky_object, 42, 15));
assertEquals(-1, Array.prototype.indexOf.call(funky_object, 37));
assertEquals(10, Array.prototype.indexOf.call(infinite_object, 42));
// ----------------------------------------------------------------------
// Array.prototype.lastIndexOf.
// ----------------------------------------------------------------------
// Negative cases.
assertEquals(-1, [].lastIndexOf(1));
assertEquals(-1, array.lastIndexOf(1, -17));
assertEquals(9, array.lastIndexOf(1));
// Index out of range.
assertEquals(9, array.lastIndexOf(1, array.length));
// Index in range.
assertEquals(0, array.lastIndexOf(1, 2));
assertEquals(3, array.lastIndexOf(1, 4));
assertEquals(3, array.lastIndexOf(1, 3));
// Negative index in range.
assertEquals(0, array.lastIndexOf(1, -11));
// Find undefined, not holes.
assertEquals(7, undef_array.lastIndexOf(undefined));
assertEquals(-1, undef_array.lastIndexOf(undefined, 2));
assertEquals(3, undef_array.lastIndexOf(undefined, 3));
assertEquals(3, undef_array.lastIndexOf(undefined, 6));
assertEquals(7, undef_array.lastIndexOf(undefined, 7));
assertEquals(7, undef_array.lastIndexOf(undefined, -1));
assertEquals(-1, undef_array.lastIndexOf(undefined, -9));
assertEquals(3, undef_array.lastIndexOf(undefined, -8));
assertEquals(3, undef_array.lastIndexOf(undefined, -5));
assertEquals(7, undef_array.lastIndexOf(undefined, -4));
// Find in sparse array.
assertEquals(900, sparse_array.lastIndexOf(3));
assertEquals(100, sparse_array.lastIndexOf(3, 899));
assertEquals(-1, sparse_array.lastIndexOf(3, 99));
assertEquals(900, sparse_array.lastIndexOf(3, -1));
assertEquals(100, sparse_array.lastIndexOf(3, 899 - 42000));
assertEquals(-1, sparse_array.lastIndexOf(3, 99 - 42000));
assertEquals(700, sparse_array.lastIndexOf(4));
assertEquals(300, sparse_array.lastIndexOf(4, 699));
assertEquals(-1, sparse_array.lastIndexOf(4, 299));
assertEquals(700, sparse_array.lastIndexOf(4, -1));
assertEquals(300, sparse_array.lastIndexOf(4, 699 - 42000));
assertEquals(-1, sparse_array.lastIndexOf(4, 299 - 42000));
assertEquals(800, sparse_array.lastIndexOf(undefined));
assertEquals(200, sparse_array.lastIndexOf(undefined, 799));
assertEquals(-1, sparse_array.lastIndexOf(undefined, 199));
assertEquals(800, sparse_array.lastIndexOf(undefined, -1));
assertEquals(200, sparse_array.lastIndexOf(undefined, 799 - 42000));
assertEquals(-1, sparse_array.lastIndexOf(undefined, 199 - 42000));
assertEquals(0, Array.prototype.lastIndexOf.call(dense_object, 42));
assertEquals(1, Array.prototype.lastIndexOf.call(dense_object, 37));
assertEquals(0, Array.prototype.lastIndexOf.call(sparse_object, 42));
assertEquals(100000, Array.prototype.lastIndexOf.call(sparse_object, 37));
//Find in non-arrays.
assertEquals(0, Array.prototype.lastIndexOf.call(dense_object, 42));
assertEquals(1, Array.prototype.lastIndexOf.call(dense_object, 37));
assertEquals(-1, Array.prototype.lastIndexOf.call(dense_object, 87));
assertEquals(0, Array.prototype.lastIndexOf.call(sparse_object, 42));
assertEquals(100000, Array.prototype.lastIndexOf.call(sparse_object, 37));
assertEquals(-1, Array.prototype.lastIndexOf.call(sparse_object, 87));
assertEquals(10, Array.prototype.lastIndexOf.call(funky_object, 42, 15));
assertEquals(10, Array.prototype.lastIndexOf.call(funky_object, 42));
assertEquals(-1, Array.prototype.lastIndexOf.call(funky_object, 37));
// This call would take too long because it would search backwards from 2**53-1
// assertEquals(-1, Array.prototype.lastIndexOf.call(infinite_object, 42));

View File

@ -0,0 +1,202 @@
// Copyright 2022 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.
// Large array of packed Smi, and Smi search_element
(() => {
let a = [];
for (let i = 0; i < 200; i++) {
a[i] = i;
}
function testArrayIndexOf(idx) {
return a.indexOf(idx);
}
// Without fromIndex
for (let i = 0; i < 200; i++) {
assertEquals(i, testArrayIndexOf(i));
}
// With fromIndex
for (let i = 0, from_index = 0; i+from_index < 200; i += 2, from_index++) {
assertEquals(i, testArrayIndexOf(i, from_index));
}
})();
// Large array of holey Smi, and Smi search_element
(() => {
let a = [];
// Skipping every other item when initializing
for (let i = 0; i < 200; i+=2) {
a[i] = i;
}
function testArrayIndexOf(idx) {
return a.indexOf(idx);
}
// Without fromIndex
for (let i = 0; i < 200; i++) {
if (i % 2 == 0) {
assertEquals(i, testArrayIndexOf(i));
} else {
assertEquals(-1, testArrayIndexOf(i));
}
}
// With fromIndex
for (let i = 0, from_index = 0; i + from_index < 200; i += 2, from_index++) {
if (i % 2 == 0) {
assertEquals(i, testArrayIndexOf(i, from_index));
} else {
assertEquals(-1, testArrayIndexOf(i, from_index));
}
}
})();
// Large array of packed Doubles, and Double search_element
(() => {
let a = [];
for (let i = 0; i < 200; i++) {
a[i] = i + 0.5;
}
function testArrayIndexOf(idx) {
return a.indexOf(idx);
}
// Without fromIndex
for (let i = 0; i < 200; i++) {
assertEquals(i, testArrayIndexOf(i + 0.5));
}
// With fromIndex
for (let i = 0, from_index = 0; i+from_index < 200; i += 2, from_index++) {
assertEquals(i, testArrayIndexOf(i+0.5, from_index));
}
})();
// Large array of holey Doubles, and Double search_element
(() => {
let a = [];
// Skipping every other item when initializing
for (let i = 0; i < 200; i+=2) {
a[i] = i + 0.5;
}
function testArrayIndexOf(idx) {
return a.indexOf(idx);
}
// Without fromIndex
for (let i = 0; i < 200; i++) {
if (i % 2 == 0) {
assertEquals(i, testArrayIndexOf(i + 0.5));
} else {
assertEquals(-1, testArrayIndexOf(i + 0.5));
}
}
// With fromIndex
for (let i = 0, from_index = 0; i + from_index < 200; i += 2, from_index++) {
if (i % 2 == 0) {
assertEquals(i, testArrayIndexOf(i+0.5, from_index));
} else {
assertEquals(-1, testArrayIndexOf(i+0.5, from_index));
}
}
})();
// Large array of packed objects, and object search_element
(() => {
let a = [];
let b = [];
for (let i = 0; i < 200; i++) {
a[i] = { v: i };
b[i] = a[i];
}
function testArrayIndexOf(idx) {
return a.indexOf(idx);
}
// Without fromIndex
for (let i = 0; i < 200; i++) {
assertEquals(i, testArrayIndexOf(b[i]));
}
// With fromIndex
for (let i = 0, from_index = 0; i+from_index < 200; i += 2, from_index++) {
assertEquals(i, testArrayIndexOf(b[i], from_index));
}
})();
// Large array of holey objects, and object search_element
(() => {
let a = [];
let b = [];
// Skipping every other item when initializing
for (let i = 0; i < 200; i++) {
b[i] = { v: i };
if (i % 2 == 0) {
a[i] = b[i];
}
}
function testArrayIndexOf(idx) {
return a.indexOf(idx);
}
// Without fromIndex
for (let i = 0; i < 200; i++) {
if (i % 2 == 0) {
assertEquals(i, testArrayIndexOf(b[i]));
} else {
assertEquals(-1, testArrayIndexOf(b[i]));
}
}
// With fromIndex
for (let i = 0, from_index = 0; i + from_index < 200; i += 2, from_index++) {
if (i % 2 == 0) {
assertEquals(i, testArrayIndexOf(b[i], from_index));
} else {
assertEquals(-1, testArrayIndexOf(b[i], from_index));
}
}
})();
// This test checks that when the item that IndexOf searches is present multiple
// time, the correct index is returned (in particular, when a single SIMD vector
// had multiple matches). For instance, if we do:
//
// [1, 2, 1, 3].indexOf(1)
//
// Then it should return 0 rather than 2.
(() => {
// The patterns that this function will check, where for instance patternABAB
// means that we'd like to build a vector containing {A, B, A, B}.
let patterns = {
patternABAB : (a, b, c, d) => [a, b, a, b, c, d, c, d],
patternAABB : (a, b, c, d) => [a, a, b, b, c, c, d, d],
patternABBA : (a, b, c, d) => [a, b, b, a, c, d, d, c],
patternABAA : (a, b, c, d) => [a, b, a, a, c, d, c, c],
patternAABA : (a, b, c, d) => [a, a, b, a, c, c, d, c],
patternAAAB : (a, b, c, d) => [a, a, a, b, c, c, c, d],
patternBAAA : (a, b, c, d) => [b, a, a, a, d, c, c, c]
};
// Starting |a| with a bunch of 0s, which might be handled by the scalar loop
// that the SIMD code does to reach 16/32-byte alignment.
let a = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
let next_int = 1;
for (const [_, pattern] of Object.entries(patterns)) {
// It's a bit tricky to ensure that 2 items will be in the same SIMD batch
// because we can't control the alignment of the array from JS, and the
// SIMD code will start by skipping the first items to have the memory
// aligned on 16/32 bytes. So, we put each pattern 8 times in a row in |a|,
// but each time with an additional item, to make sure that each of those 8
// repeated pattern have a different alignment.
for (let i = 0; i < 8; i++) {
a = a.concat(pattern(next_int, next_int + 1, next_int + 2, next_int + 3));
a.push(next_int + 4); // By adding a 9th item, we make sure that the
// alignment of the next batch is not the same as
// the current one.
next_int += 5;
}
}
let b = a.slice();
b[10000] = 42; // Switch b to dictionary mode so that the SIMD code won't be
// used for it. We can then use `b.indexOf` as reference.
for (let x of b) {
if (x == undefined) break;
assertEquals(b.indexOf(x), a.indexOf(x));
}
})();

26
deps/v8/test/mjsunit/array-isarray.js vendored Normal file
View File

@ -0,0 +1,26 @@
// 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.
assertTrue(Array.isArray([]));
assertFalse(Array.isArray({}));
assertFalse(Array.isArray(null));
assertFalse(Array.isArray(0));
assertFalse(Array.isArray(0.1));
assertFalse(Array.isArray(""));
assertFalse(Array.isArray(undefined));
assertTrue(Array.isArray(new Proxy([], {})));
assertFalse(Array.isArray(new Proxy({}, {})));
assertTrue(Array.isArray(new Proxy(new Proxy([], {}), {})));
assertFalse(Array.isArray(new Proxy(new Proxy({}, {}), {})));
(function TestIsArrayStackOverflow() {
var proxy = new Proxy([], {});
for(var i=0; i<200*1024; i++) {
proxy = new Proxy(proxy, {});
}
assertThrows(()=>Array.isArray(proxy), RangeError);
})();

425
deps/v8/test/mjsunit/array-iteration.js vendored Normal file
View File

@ -0,0 +1,425 @@
// Copyright 2008 the V8 project authors. All rights reserved.
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following
// disclaimer in the documentation and/or other materials provided
// with the distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// Tests for non-standard array iteration functions.
//
// See
//
// <http://developer.mozilla.org/en/docs/Core_JavaScript_1.5_Reference:Global_Objects:Array>
//
// for an explanation of each of the functions.
//
// Array.prototype.filter
//
(function() {
// Simple use.
var a = [0,1];
assertArrayEquals([0], a.filter(function(n) { return n == 0; }));
assertArrayEquals([0,1], a);
// Use specified object as this object when calling the function.
var o = { value: 42 }
a = [1,42,3,42,4];
assertArrayEquals([42,42],
a.filter(function(n) { return this.value == n }, o))
// Modify original array.
a = [1,42,3,42,4];
assertArrayEquals([42,42],
a.filter(function(n, index, array) {
array[index] = 43; return 42 == n;
}));
assertArrayEquals([43,43,43,43,43], a);
// Only loop through initial part of array eventhough elements are
// added.
a = [1,1];
assertArrayEquals([],
a.filter(function(n, index, array) { array.push(n+1); return n == 2; }));
assertArrayEquals([1,1,2,2], a);
// Respect holes.
a = new Array(20);
var count = 0;
a[2] = 2;
a[15] = 2;
a[17] = 4;
var a = a.filter(function(n) { count++; return n == 2; });
assertEquals(3, count);
for (var i in a) assertEquals(2, a[i]);
// Skip over missing properties.
a = {
"0": 0,
"2": 2,
length: 3
};
var received = [];
assertArrayEquals([2],
Array.prototype.filter.call(a, function(n) {
received.push(n);
return n == 2;
}));
assertArrayEquals([0, 2], received);
// Modify array prototype
a = [0, , 2];
received = [];
assertArrayEquals([2],
Array.prototype.filter.call(a, function(n) {
a.__proto__ = null;
received.push(n);
return n == 2;
}));
assertArrayEquals([0, 2], received);
// Create a new object in each function call when receiver is a
// primitive value. See ECMA-262, Annex C.
a = [];
[1, 2].filter(function() { a.push(this) }, "");
assertTrue(a[0] !== a[1]);
// Do not create a new object otherwise.
a = [];
[1, 2].filter(function() { a.push(this) }, {});
assertEquals(a[0], a[1]);
// In strict mode primitive values should not be coerced to an object.
a = [];
[1, 2].filter(function() { 'use strict'; a.push(this); }, "");
assertEquals("", a[0]);
assertEquals(a[0], a[1]);
})();
//
// Array.prototype.forEach
//
(function() {
// Simple use.
var a = [0,1];
var count = 0;
a.forEach(function(n) { count++; });
assertEquals(2, count);
// Use specified object as this object when calling the function.
var o = { value: 42 }
var result = [];
a.forEach(function(n) { result.push(this.value); }, o);
assertArrayEquals([42,42], result);
// Modify original array.
a = [0,1];
count = 0;
a.forEach(function(n, index, array) { array[index] = n + 1; count++; });
assertEquals(2, count);
assertArrayEquals([1,2], a);
// Only loop through initial part of array eventhough elements are
// added.
a = [1,1];
count = 0;
a.forEach(function(n, index, array) { array.push(n+1); count++; });
assertEquals(2, count);
assertArrayEquals([1,1,2,2], a);
// Respect holes.
a = new Array(20);
count = 0;
a[15] = 2;
a.forEach(function(n) { count++; });
assertEquals(1, count);
// Skip over missing properties.
a = {
"0": 0,
"2": 2,
length: 3
};
var received = [];
Array.prototype.forEach.call(a, function(n) { received.push(n); });
assertArrayEquals([0, 2], received);
// Modify array prototype
a = [0, , 2];
received = [];
Array.prototype.forEach.call(a, function(n) {
a.__proto__ = null;
received.push(n);
return n == 2;
});
assertArrayEquals([0, 2], received);
// Create a new object in each function call when receiver is a
// primitive value. See ECMA-262, Annex C.
a = [];
[1, 2].forEach(function() { a.push(this) }, "");
assertTrue(a[0] !== a[1]);
// Do not create a new object otherwise.
a = [];
[1, 2].forEach(function() { a.push(this) }, {});
assertEquals(a[0], a[1]);
// In strict mode primitive values should not be coerced to an object.
a = [];
[1, 2].forEach(function() { 'use strict'; a.push(this); }, "");
assertEquals("", a[0]);
assertEquals(a[0], a[1]);
})();
//
// Array.prototype.every
//
(function() {
// Simple use.
var a = [0,1];
assertFalse(a.every(function(n) { return n == 0 }));
a = [0,0];
assertTrue(a.every(function(n) { return n == 0 }));
assertTrue([].every(function(n) { return n == 0}));
// Use specified object as this object when calling the function.
var o = { value: 42 }
a = [0];
assertFalse(a.every(function(n) { return this.value == n; }, o));
a = [42];
assertTrue(a.every(function(n) { return this.value == n; }, o));
// Modify original array.
a = [0,1];
assertFalse(
a.every(function(n, index, array) {
array[index] = n + 1; return n == 1;
}));
assertArrayEquals([1,1], a);
// Only loop through initial part of array eventhough elements are
// added.
a = [1,1];
assertTrue(
a.every(function(n, index, array) {
array.push(n + 1); return n == 1;
}));
assertArrayEquals([1,1,2,2], a);
// Respect holes.
a = new Array(20);
var count = 0;
a[2] = 2;
a[15] = 2;
assertTrue(a.every(function(n) { count++; return n == 2; }));
assertEquals(2, count);
// Skip over missing properties.
a = {
"0": 2,
"2": 2,
length: 3
};
var received = [];
assertTrue(
Array.prototype.every.call(a, function(n) {
received.push(n);
return n == 2;
}));
assertArrayEquals([2, 2], received);
// Modify array prototype
a = [2, , 2];
received = [];
assertTrue(
Array.prototype.every.call(a, function(n) {
a.__proto__ = null;
received.push(n);
return n == 2;
}));
assertArrayEquals([2, 2], received);
// Create a new object in each function call when receiver is a
// primitive value. See ECMA-262, Annex C.
a = [];
[1, 2].every(function() { a.push(this); return true; }, "");
assertTrue(a[0] !== a[1]);
// Do not create a new object otherwise.
a = [];
[1, 2].every(function() { a.push(this); return true; }, {});
assertEquals(a[0], a[1]);
// In strict mode primitive values should not be coerced to an object.
a = [];
[1, 2].every(function() { 'use strict'; a.push(this); return true; }, "");
assertEquals("", a[0]);
assertEquals(a[0], a[1]);
})();
//
// Array.prototype.map
//
(function() {
var a = [0,1,2,3,4];
// Simple use.
var result = [1,2,3,4,5];
assertArrayEquals(result, a.map(function(n) { return n + 1; }));
assertEquals(a, a);
// Use specified object as this object when calling the function.
var o = { delta: 42 }
result = [42,43,44,45,46];
assertArrayEquals(result, a.map(function(n) { return this.delta + n; }, o));
// Modify original array.
a = [0,1,2,3,4];
result = [1,2,3,4,5];
assertArrayEquals(result,
a.map(function(n, index, array) {
array[index] = n + 1; return n + 1;
}));
assertArrayEquals(result, a);
// Only loop through initial part of array eventhough elements are
// added.
a = [0,1,2,3,4];
result = [1,2,3,4,5];
assertArrayEquals(result,
a.map(function(n, index, array) { array.push(n); return n + 1; }));
assertArrayEquals([0,1,2,3,4,0,1,2,3,4], a);
// Respect holes.
a = new Array(20);
a[15] = 2;
a = a.map(function(n) { return 2*n; });
for (var i in a) assertEquals(4, a[i]);
// Skip over missing properties.
a = {
"0": 1,
"2": 2,
length: 3
};
var received = [];
assertArrayEquals([2, , 4],
Array.prototype.map.call(a, function(n) {
received.push(n);
return n * 2;
}));
assertArrayEquals([1, 2], received);
// Modify array prototype
a = [1, , 2];
received = [];
assertArrayEquals([2, , 4],
Array.prototype.map.call(a, function(n) {
a.__proto__ = null;
received.push(n);
return n * 2;
}));
assertArrayEquals([1, 2], received);
// Create a new object in each function call when receiver is a
// primitive value. See ECMA-262, Annex C.
a = [];
[1, 2].map(function() { a.push(this) }, "");
assertTrue(a[0] !== a[1]);
// Do not create a new object otherwise.
a = [];
[1, 2].map(function() { a.push(this) }, {});
assertEquals(a[0], a[1]);
// In strict mode primitive values should not be coerced to an object.
a = [];
[1, 2].map(function() { 'use strict'; a.push(this); }, "");
assertEquals("", a[0]);
assertEquals(a[0], a[1]);
})();
//
// Array.prototype.some
//
(function() {
var a = [0,1,2,3,4];
// Simple use.
assertTrue(a.some(function(n) { return n == 3}));
assertFalse(a.some(function(n) { return n == 5}));
// Use specified object as this object when calling the function.
var o = { element: 42 };
a = [1,42,3];
assertTrue(a.some(function(n) { return this.element == n; }, o));
a = [1];
assertFalse(a.some(function(n) { return this.element == n; }, o));
// Modify original array.
a = [0,1,2,3];
assertTrue(
a.some(function(n, index, array) {
array[index] = n + 1; return n == 2; }));
assertArrayEquals([1,2,3,3], a);
// Only loop through initial part when elements are added.
a = [0,1,2];
assertFalse(
a.some(function(n, index, array) { array.push(42); return n == 42; }));
assertArrayEquals([0,1,2,42,42,42], a);
// Respect holes.
a = new Array(20);
var count = 0;
a[2] = 42;
a[10] = 2;
a[15] = 42;
assertTrue(a.some(function(n) { count++; return n == 2; }));
assertEquals(2, count);
// Create a new object in each function call when receiver is a
// primitive value. See ECMA-262, Annex C.
a = [];
[1, 2].some(function() { a.push(this) }, "");
assertTrue(a[0] !== a[1]);
// Do not create a new object otherwise.
a = [];
[1, 2].some(function() { a.push(this) }, {});
assertEquals(a[0], a[1]);
// In strict mode primitive values should not be coerced to an object.
a = [];
[1, 2].some(function() { 'use strict'; a.push(this); }, "");
assertEquals("", a[0]);
assertEquals(a[0], a[1]);
})();

View File

@ -0,0 +1,20 @@
// Copyright 2018 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Flags: --allow-natives-syntax
/* Test behaviors when the prototype has elements */
(function () {
var array = [,];
function next() {
return array[Symbol.iterator]().next();
}
assertEquals(next().value, undefined);
array.__proto__.push(5);
assertEquals(next().value, 5);
})();

View File

@ -0,0 +1,14 @@
// Copyright 2018 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
(function ArrayPrototypeChanged() {
const el = {
toString() {
Array.prototype[1] = '2';
return '1';
}
};
const a = [el, ,3];
assertSame("123", a.join(''));
})();

View File

@ -0,0 +1,152 @@
// Copyright 2018 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Flags: --allow-natives-syntax
const MIN_DICTIONARY_INDEX = 8192;
function ArrayTests() {
(function ToStringThrows() {
function TestError() {}
let callCount = 0;
const toStringThrows = {
toString() {
callCount++;
throw new TestError;
}
};
const a = [toStringThrows];
assertThrows(() => a.join(), TestError);
assertSame(1, callCount);
// Verifies cycle detection still works properly after thrown error.
a[0] = 1;
a[1] = 2;
assertSame('1,2', a.join());
})();
(function ArrayLengthIncreased() {
let callCount = 0;
const a = [
{
toString() {
callCount++;
a.push(2);
return '1';
}
}
];
assertSame('1', a.join());
assertSame(1, callCount);
assertSame('1,2', a.join());
})();
(function ArrayLengthDecreased() {
let callCount = 0;
const a = [
{
toString() {
callCount++;
a.pop();
return '1';
}
},
'2'
];
assertSame('1,', a.join());
assertSame(1, callCount);
assertSame('1', a.join());
})();
(function ElementsKindChangedToHoley() {
let callCount = 0;
const a = [
{
toString() {
callCount++;
a.length = 4;
a[1] = 777;
a[2] = 7.7;
return '1';
}
},
2,
3
];
assertSame('1,777,7.7', a.join());
assertSame(1, callCount);
assertSame('1,777,7.7,', a.join());
})();
(function ElementsKindChangedToHoleyThroughDeletion() {
let callCount = 0;
const a = [
{
toString() {
callCount++;
delete a[1];
a[2] = 7.7;
return '1';
}
},
2,
3
];
assertSame('1,,7.7', a.join());
assertSame(1, callCount);
assertSame('1,,7.7', a.join());
})();
(function NumberDictionaryChanged() {
let callCount = 0;
const a = [];
a[MIN_DICTIONARY_INDEX - 1] = {
toString() {
callCount++;
a[MIN_DICTIONARY_INDEX] = '2';
return '1';
}
};
a[MIN_DICTIONARY_INDEX] = 'NOPE';
assertTrue(%HasDictionaryElements(a));
assertSame('12', a.join(''));
assertSame(1, callCount);
assertSame('12', a.join(''));
})();
(function NumberDictionaryLengthChange() {
let callCount = 0;
const a = [];
a[MIN_DICTIONARY_INDEX - 1] = {
toString() {
callCount++;
a.length = MIN_DICTIONARY_INDEX;
return '1';
}
};
a[MIN_DICTIONARY_INDEX] = '2';
assertTrue(%HasDictionaryElements(a));
assertSame('1', a.join(''));
assertSame(1, callCount);
assertSame('1', a.join(''));
})();
}
(function NonArrayCycleDetection() {
const a = {
length: 3,
toString() { return Array.prototype.join.call(this); }
};
a[0] = '1';
a[1] = a;
a[2] = '3';
assertSame("1,,3", Array.prototype.join.call(a));
});
ArrayTests();
%SetForceSlowPath(true);
ArrayTests();

View File

@ -0,0 +1,108 @@
// Copyright 2018 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Flags: --allow-natives-syntax
(function Throws() {
function TestError() {}
let callCount = 0;
const a = [0, 1];
Object.defineProperty(a, '0', {
configurable: true,
get() {
callCount++;
throw new TestError();
}
});
assertTrue(%HasDictionaryElements(a));
assertThrows(() => a.join(), TestError);
assertSame(1, callCount);
// Verifies cycle detection still works properly after thrown error.
Object.defineProperty(a, '0', {
configurable: true,
get() {
callCount++;
return 777;
}
});
assertSame('777,1', a.join());
assertSame(2, callCount);
})();
(function ArrayLengthIncreased() {
let callCount = 0;
const a = [1];
Object.defineProperty(a, '0', {
configurable: true,
get() {
callCount++;
a.push(2);
return 9;
}
});
assertSame('9', a.join());
assertSame(1, callCount);
// Verifies cycle detection still works properly after continuation.
assertSame('9,2', a.join());
assertSame(2, callCount);
})();
(function ArrayLengthIncreasedWithHole() {
let callCount = 0;
const a = [1, , 2];
Object.defineProperty(a, '1', {
configurable: true,
get() {
callCount++;
a.push(3);
}
});
assertSame('1,,2', a.join());
assertSame(1, callCount);
// Verifies cycle detection still works properly after continuation.
assertSame('1,,2,3', a.join());
assertSame(2, callCount);
})();
(function ArrayLengthDecreased() {
let callCount = 0;
const a = [0, 1];
Object.defineProperty(a, '0', {
configurable: true,
get() {
callCount++;
a.length = 1;
return 9;
}
});
assertSame('9,', a.join());
assertSame(1, callCount);
// Verifies cycle detection still works properly after continuation.
assertSame('9', a.join());
assertSame(2, callCount);
})();
(function ElementsKindChangedToHoley() {
let callCount = 0;
const a = [0, 1];
Object.defineProperty(a, '0', {
configurable: true,
get() {
callCount++;
a.length = 3;
return 9;
}
});
assertSame('9,1', a.join());
assertSame(1, callCount);
// Verifies cycle detection still works properly after continuation.
assertSame('9,1,', a.join());
assertSame(2, callCount);
})();

View File

@ -0,0 +1,63 @@
// Copyright 2018 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Flags: --allow-natives-syntax
(function DictionaryStringRepeatFastPath() {
const a = new Array(%StringMaxLength());
assertTrue(%HasDictionaryElements(a));
const sep = '12';
assertThrows(() => a.join(sep), RangeError);
// Verifies cycle detection still works properly after thrown error.
assertThrows(() => a.join(sep), RangeError);
a.length = 3;
a[0] = 'a';
a[1] = 'b';
a[2] = 'c';
assertSame('a,b,c', a.join());
})();
(function SeparatorOverflow() {
const a = ['a',,,,,'b'];
const sep = ','.repeat(%StringMaxLength());
assertThrows(() => a.join(sep), RangeError);
// Verifies cycle detection still works properly after thrown error.
assertThrows(() => a.join(sep), RangeError);
assertSame('a,,,,,b', a.join());
})();
(function ElementOverflow() {
const el = ','.repeat(%StringMaxLength());
const a = [el, el, el, el, el];
assertThrows(() => a.join(), RangeError);
// Verifies cycle detection still works properly after thrown error.
assertThrows(() => a.join(), RangeError);
a[0] = 'a';
a[1] = 'b';
a[2] = 'c';
a[3] = 'd';
a[4] = 'e';
assertSame('a,b,c,d,e', a.join());
})();
(function ElementSeparatorOverflow() {
const el = ','.repeat(%StringMaxLength());
const a = [el, el, el, el];
assertThrows(() => a.join(el), RangeError);
// Verifies cycle detection still works properly after thrown error.
assertThrows(() => a.join(el), RangeError);
a[0] = 'a';
a[1] = 'b';
a[2] = 'c';
a[3] = 'd';
assertSame('a,b,c,d', a.join());
})();

View File

@ -0,0 +1,16 @@
// Copyright 2018 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
const DEPTH = 128;
function makeNestedArray(depth, value) {
return depth > 0 ? [value, makeNestedArray(depth - 1, value)] : [value];
}
const array = makeNestedArray(DEPTH, 'a');
const expected = 'a' + ',a'.repeat(DEPTH);
assertSame(expected, array.join());
// Verify cycle detection is still working.
assertSame(expected, array.join());

View File

@ -0,0 +1,29 @@
// Copyright 2018 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
(function Throws() {
function TestError() {}
let callCount = 0;
const a = {
0: 1,
1: 2,
get length() {
callCount++;
throw new TestError();
}
};
assertThrows(() => Array.prototype.join.call(a), TestError);
assertSame(1, callCount);
// Verifies cycle detection still works properly after thrown error.
Object.defineProperty(a, 'length', {
get() {
callCount++;
return 2;
}
});
assertSame('1,2', Array.prototype.join.call(a));
assertSame(2, callCount);
})();

View File

@ -0,0 +1,197 @@
// Copyright 2018 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Flags: --allow-natives-syntax
const MIN_DICTIONARY_INDEX = 8192;
(function ToStringThrows() {
function TestError() {}
let callCount = 0;
const a = [1, 2];
assertThrows(() => a.join({
toString() {
callCount++;
throw new TestError;
}
}), TestError);
assertSame(1, callCount);
// Verifies cycle detection still works properly after thrown error.
assertSame('1,2', a.join());
})();
(function RecursiveJoinCall() {
const a = [1,2,3];
let callCount = 0;
const sep = {
toString() {
callCount++;
return a.join('-');
}
};
assertSame('11-2-321-2-33', a.join(sep));
assertSame(1, callCount);
// Verify cycle detection works properly after nested call
assertSame('1,2,3', a.join());
})();
(function ArrayLengthIncreased() {
const a = [1,2,3];
let callCount = 0;
assertSame('1,2,3', a.join({
toString() {
callCount++;
a.push(4);
return ',';
}
}));
assertSame(1, callCount);
assertSame('1,2,3,4', a.join());
})();
(function ArrayLengthDecreased() {
const a = [1,2,3];
let callCount = 0;
assertSame('1,2,', a.join({
toString() {
callCount++;
a.pop();
return ',';
}
}));
assertSame(1, callCount);
assertSame('1,2', a.join());
})();
(function ArrayEmptied() {
const a = [1,2,3];
let callCount = 0;
assertSame(',,', a.join({
toString() {
callCount++;
a.length = 0;
return ',';
}
}));
assertSame(1, callCount);
})();
(function NumberDictionaryEmptied() {
const a = [];
a[0] = 1;
a[MIN_DICTIONARY_INDEX] = 2;
assertTrue(%HasDictionaryElements(a));
let callCount = 0;
assertSame('-'.repeat(MIN_DICTIONARY_INDEX), a.join({
toString() {
callCount++;
a.length = 0;
return '-';
}
}));
assertSame(1, callCount);
})();
(function NumberDictionaryEmptiedEmptySeparator() {
const a = [];
a[0] = 1;
a[MIN_DICTIONARY_INDEX] = 2;
assertTrue(%HasDictionaryElements(a));
let callCount = 0;
assertSame(''.repeat(MIN_DICTIONARY_INDEX), a.join({
toString() {
callCount++;
a.length = 0;
return '';
}
}));
assertSame(1, callCount);
})();
(function ElementsKindSmiToDoubles() {
const a = [1,2,3];
let callCount = 0;
assertTrue(%HasSmiElements(a));
assertSame('1.5,2,3', a.join({
toString() {
callCount++;
a[0] = 1.5;
assertTrue(%HasDoubleElements(a));
return ',';
}
}));
assertSame(1, callCount);
assertSame('1.5,2,3', a.join());
})();
(function ElementsKindDoublesToObjects() {
const a = [1.5, 2.5, 3.5];
let callCount = 0;
assertTrue(%HasDoubleElements(a));
assertSame('one,2.5,3.5', a.join({
toString() {
callCount++;
a[0] = 'one';
assertTrue(%HasObjectElements(a));
return ',';
}
}));
assertSame(1, callCount);
assertSame('one,2.5,3.5', a.join());
})();
(function ArrayIsNoLongerFast() {
const a = [1,2,3];
let callCount = 0;
assertSame('666,2,3', a.join({
toString() {
callCount++;
Object.defineProperty(a, '0', {
get(){ return 666; }
});
return ',';
}
}));
assertSame(1, callCount);
assertSame('666,2,3', a.join());
})();
(function ArrayPrototypeUnset() {
const a = [1,2];
a.length = 3;
let callCount = 0;
assertSame('1,2,4', a.join({
toString() {
callCount++;
a.__proto__ = { '2': 4 };
return ',';
}
}));
assertSame(1, callCount);
a.__proto__ = Array.prototype;
assertSame('1,2,', a.join());
})();
(function ArrayPrototypeIsNoLongerFast() {
const a = [1,2,3];
let callCount = 0;
assertSame('1,2,777', a.join({
toString() {
callCount++;
a.pop();
Object.defineProperty(Array.prototype, '2', {
get(){ return 777; }
});
return ',';
}
}));
assertSame(1, callCount);
assertSame('1,2', a.join());
})();

114
deps/v8/test/mjsunit/array-join.js vendored Normal file
View File

@ -0,0 +1,114 @@
// Copyright 2008 the V8 project authors. All rights reserved.
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following
// disclaimer in the documentation and/or other materials provided
// with the distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
assertSame(',', [null, undefined].join());
assertSame('1.5,2.5', [1.5, 2.5].join());
assertSame(',1.5,', [,1.5,,].join());
var obj = {
toString() {
return 'a';
}
};
assertSame('1,1.5,a,', [1, 1.5, obj, ,].join());
// Test that array join calls toString on subarrays.
var a = [[1,2],3,4,[5,6]];
assertEquals('1,2345,6', a.join(''));
assertEquals('1,2*3*4*5,6', a.join('*'));
assertEquals('1,2**3**4**5,6', a.join('**'));
assertEquals('1,2****3****4****5,6', a.join('****'));
assertEquals('1,2********3********4********5,6', a.join('********'));
assertEquals('1,2**********3**********4**********5,6', a.join('**********'));
// Create a cycle.
a.push(a);
assertEquals('1,2345,6', a.join(''));
assertEquals('1,2*3*4*5,6*', a.join('*'));
assertEquals('1,2**3**4**5,6**', a.join('**'));
assertEquals('1,2****3****4****5,6****', a.join('****'));
assertEquals('1,2********3********4********5,6********', a.join('********'));
assertEquals('1,2**********3**********4**********5,6**********', a.join('**********'));
// Replace array.prototype.toString.
var oldToString = Array.prototype.toString;
Array.prototype.toString = function() { return "array"; };
assertEquals('array34arrayarray', a.join(''));
assertEquals('array*3*4*array*array', a.join('*'));
assertEquals('array**3**4**array**array', a.join('**'));
assertEquals('array****3****4****array****array', a.join('****'));
assertEquals('array********3********4********array********array', a.join('********'));
assertEquals('array**********3**********4**********array**********array', a.join('**********'));
Array.prototype.toString = function() { throw 42; };
assertThrows("a.join('')");
assertThrows("a.join('*')");
assertThrows("a.join('**')");
assertThrows("a.join('****')");
assertThrows("a.join('********')");
assertThrows("a.join('**********')");
Array.prototype.toString = function() { return "array"; };
assertEquals('array34arrayarray', a.join(''));
assertEquals('array*3*4*array*array', a.join('*'));
assertEquals('array**3**4**array**array', a.join('**'));
assertEquals('array****3****4****array****array', a.join('****'));
assertEquals('array********3********4********array********array', a.join('********'));
assertEquals('array**********3**********4**********array**********array', a.join('**********'));
// Restore original toString.
delete Array.prototype.toString;
if (Array.prototype.toString != oldToString) {
Array.prototype.toString = oldToString;
}
var a = new Array(123123);
assertEquals(123122, String(a).length);
assertEquals(123122, a.join(",").length);
assertEquals(246244, a.join("oo").length);
a = new Array(Math.pow(2,32) - 1); // Max length.
assertEquals("", a.join(""));
a = new Array(100001);
for (var i = 0; i < a.length; i++) a[i] = undefined;
a[5] = "ab";
a[90000] = "cd";
assertEquals("abcd", a.join("")); // Must not throw.
// Make sure that each element is accessed exactly once, and in the correct
// order.
{
var log = [];
var p = new Proxy({length: 3, 0: 'a', 1: 'b'}, {
get: function(t, k, r) { log.push(k); return Reflect.get(t, k, r); }
});
assertEquals("a,b,", Array.prototype.join.call(p));
assertEquals(["length", "0", "1", "2"], log);
}

View File

@ -0,0 +1,83 @@
// Copyright 2017 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
assertThrows(() => {
Array.prototype.lastIndexOf.call(null, 42);
}, TypeError);
assertThrows(() => {
Array.prototype.lastIndexOf.call(undefined, 42);
}, TypeError);
/* Tests inspired by test262's
lastIndexOf/calls-only-has-on-prototype-after-length-zeroed.js */
// Stateful fromIndex that tries to empty the array
(function testFromIndex() {
var array = [5, undefined, 7];
var fromIndex = {
valueOf: function() {
array.length = 1;
return 2;
}
};
assertEquals(-1, array.lastIndexOf(undefined, fromIndex));
array = [5, undefined, 7];
assertEquals(0, array.lastIndexOf(5, fromIndex));
})();
// Stateful fromIndex and proxy as Prototype
// Must test for [[HasProperty]] before [[Get]]
var testHasProperty = function(value) {
var array = [5, undefined, 7];
var fromIndex = {
valueOf: function() {
array.length = 0;
return 2;
}
};
// Install a prototype that only has [[HasProperty]], and throws on [[Get]]
Object.setPrototypeOf(array,
new Proxy(Array.prototype, {
has: function(t, pk) { return pk in t; },
get: function () { throw new Error('[[Get]] trap called') },
}));
assertEquals(-1, Array.prototype.lastIndexOf.call(array, value, fromIndex));
}
testHasProperty(5);
testHasProperty(undefined);
// Test call order: [[HasProperty]] before [[Get]]
var testHasPropertyThenGet = function(value) {
var array = [5, , 7];
var log = [];
// Install a prototype with only [[HasProperty]] and [[Get]]
Object.setPrototypeOf(array,
new Proxy(Array.prototype, {
has: function() { log.push("HasProperty"); return true; },
get: function() { log.push("Get"); },
}));
// The 2nd element (index 1) will trigger the calls to the prototype
Array.prototype.lastIndexOf.call(array, value);
assertEquals(["HasProperty", "Get"], log);
}
testHasPropertyThenGet(5);
testHasPropertyThenGet(undefined);
// Test for sparse Arrays
/* This will not enter the fast path for sparse arrays, due to UseSparseVariant
excluding array elements with accessors */
(function() {
var array = new Array(10000);
array[0] = 5; array[9999] = 7;
var count = 0;
Object.defineProperty(array.__proto__, 9998, { get: () => ++count });
Array.prototype.lastIndexOf.call(array, 0);
assertEquals(1,count);
})();

View File

@ -0,0 +1,53 @@
// Copyright 2008 the V8 project authors. All rights reserved.
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following
// disclaimer in the documentation and/or other materials provided
// with the distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// A reduced test case from Acid3 test 95.
// When an object is assigned to an array length field,
// it is converted to a number.
function CheckSetArrayLength(x, expected) {
var a = [];
a.length = x;
assertEquals("number", typeof a.length);
assertEquals(expected, a.length);
}
CheckSetArrayLength(2147483648, 2147483648);
CheckSetArrayLength("2147483648", 2147483648);
CheckSetArrayLength(null, 0);
CheckSetArrayLength(false, 0);
CheckSetArrayLength(true, 1);
CheckSetArrayLength({valueOf : function() { return 42; }}, 42);
CheckSetArrayLength({toString : function() { return '42'; }}, 42);
// Test invalid values
assertThrows("var y = []; y.length = 'abc';");
assertThrows("var y = []; y.length = undefined;");
assertThrows("var y = []; y.length = {};");
assertThrows("var y = []; y.length = -1;");
assertThrows("var y = []; y.length = {valueOf:function() { throw new Error(); }};");

170
deps/v8/test/mjsunit/array-length.js vendored Normal file
View File

@ -0,0 +1,170 @@
// Copyright 2008 the V8 project authors. All rights reserved.
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following
// disclaimer in the documentation and/or other materials provided
// with the distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
var a = [0,1,2,3];
assertEquals(0, a.length = 0);
assertEquals('undefined', typeof a[0]);
assertEquals('undefined', typeof a[1]);
assertEquals('undefined', typeof a[2]);
assertEquals('undefined', typeof a[3]);
var a = [0,1,2,3];
assertEquals(2, a.length = 2);
assertEquals(0, a[0]);
assertEquals(1, a[1]);
assertEquals('undefined', typeof a[2]);
assertEquals('undefined', typeof a[3]);
for(var i = 0; i < 10; i++) {
var array = new Array(i).fill(42);
array.push(42);
array.length = i;
array.length = i+1;
assertEquals('undefined' , typeof array[i]);
}
var a = new Array();
a[0] = 0;
a[1000] = 1000;
a[1000000] = 1000000;
a[2000000] = 2000000;
assertEquals(2000001, a.length);
assertEquals(0, a.length = 0);
assertEquals(0, a.length);
assertEquals('undefined', typeof a[0]);
assertEquals('undefined', typeof a[1000]);
assertEquals('undefined', typeof a[1000000]);
assertEquals('undefined', typeof a[2000000]);
var a = new Array();
a[0] = 0;
a[1000] = 1000;
a[1000000] = 1000000;
a[2000000] = 2000000;
assertEquals(2000001, a.length);
assertEquals(2000, a.length = 2000);
assertEquals(2000, a.length);
assertEquals(0, a[0]);
assertEquals(1000, a[1000]);
assertEquals('undefined', typeof a[1000000]);
assertEquals('undefined', typeof a[2000000]);
var a = new Array();
a[Math.pow(2,31)-1] = 0;
a[Math.pow(2,30)-1] = 0;
assertEquals(Math.pow(2,31), a.length);
var a = new Array();
a[0] = 0;
a[1000] = 1000;
a[Math.pow(2,30)-1] = Math.pow(2,30)-1;
a[Math.pow(2,31)-1] = Math.pow(2,31)-1;
a[Math.pow(2,32)-2] = Math.pow(2,32)-2;
assertEquals(Math.pow(2,30)-1, a[Math.pow(2,30)-1]);
assertEquals(Math.pow(2,31)-1, a[Math.pow(2,31)-1]);
assertEquals(Math.pow(2,32)-2, a[Math.pow(2,32)-2]);
assertEquals(Math.pow(2,32)-1, a.length);
assertEquals(Math.pow(2,30) + 1, a.length = Math.pow(2,30)+1); // not a smi!
assertEquals(Math.pow(2,30)+1, a.length);
assertEquals(0, a[0]);
assertEquals(1000, a[1000]);
assertEquals(Math.pow(2,30)-1, a[Math.pow(2,30)-1]);
assertEquals('undefined', typeof a[Math.pow(2,31)-1]);
assertEquals('undefined', typeof a[Math.pow(2,32)-2], "top");
var a = new Array();
assertEquals(Object(12), a.length = new Number(12));
assertEquals(12, a.length);
Number.prototype.valueOf = function() { return 10; }
var n = new Number(100);
assertEquals(n, a.length = n);
assertEquals(10, a.length);
n.valueOf = function() { return 20; }
assertEquals(n, a.length = n);
assertEquals(20, a.length);
var o = { length: -23 };
Array.prototype.pop.apply(o);
assertEquals(0, o.length);
// Check case of compiled stubs.
var a = [];
for (var i = 0; i < 7; i++) {
assertEquals(3, a.length = 3);
var t = 239;
t = a.length = 7;
assertEquals(7, t);
}
(function () {
"use strict";
var frozen_object = Object.freeze({__proto__:[]});
assertThrows(function () { frozen_object.length = 10 });
})();
(function sloppyReentrantDescriptorChange() {
var b = [];
b.length = {
valueOf() {
Object.defineProperty(b, "length", {writable: false});
return 1;
}
};
assertEquals(0, b.length);
})();
(function strictReentrantDescriptorChange() {
var b = [];
assertThrows(() => {
"use strict";
b.length = {
valueOf() {
Object.defineProperty(b, "length", {writable: false});
return 1;
}
};
}, TypeError);
b.length = { valueOf() { return 0; } };
assertEquals(0, b.length);
})();

View File

@ -0,0 +1,239 @@
// Copyright 2013 the V8 project authors. All rights reserved.
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following
// disclaimer in the documentation and/or other materials provided
// with the distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// Flags: --allow-natives-syntax --expose-gc --turbofan --no-always-turbofan --deopt-every-n-times=0
var elements_kind = {
packed_smi : 'packed smi elements',
packed : 'packed elements',
packed_double : 'packed double elements',
dictionary : 'dictionary elements',
external_byte : 'external byte elements',
external_unsigned_byte : 'external unsigned byte elements',
external_short : 'external short elements',
external_unsigned_short : 'external unsigned short elements',
external_int : 'external int elements',
external_unsigned_int : 'external unsigned int elements',
external_float : 'external float elements',
external_double : 'external double elements',
external_pixel : 'external pixel elements'
}
function getKind(obj) {
if (%HasSmiElements(obj)) return elements_kind.packed_smi;
if (%HasObjectElements(obj)) return elements_kind.packed;
if (%HasDoubleElements(obj)) return elements_kind.packed_double;
if (%HasDictionaryElements(obj)) return elements_kind.dictionary;
}
function isHoley(obj) {
if (%HasHoleyElements(obj)) return true;
return false;
}
function assertKind(expected, obj, name_opt) {
assertEquals(expected, getKind(obj), name_opt);
}
function get_literal(x) {
var literal = [1, 2, x];
return literal;
};
%PrepareFunctionForOptimization(get_literal);
get_literal(3);
// It's important to store a from before we crankshaft get_literal, because
// mementos won't be created from crankshafted code at all.
a = get_literal(3);
%OptimizeFunctionOnNextCall(get_literal);
get_literal(3);
assertOptimized(get_literal);
assertTrue(%HasSmiElements(a));
// a has a memento so the transition caused by the store will affect the
// boilerplate.
a[0] = 3.5;
// We should have transitioned the boilerplate array to double, and
// crankshafted code should de-opt on the unexpected elements kind
b = get_literal(3);
assertTrue(%HasDoubleElements(b));
assertEquals([1, 2, 3], b);
assertUnoptimized(get_literal);
// Optimize again
%PrepareFunctionForOptimization(get_literal);
get_literal(3);
%OptimizeFunctionOnNextCall(get_literal);
b = get_literal(3);
assertTrue(%HasDoubleElements(b));
assertOptimized(get_literal);
// Test: make sure allocation site information is updated through a
// transition from SMI->DOUBLE->PACKED
(function() {
function bar(a, b, c) {
return [a, b, c];
}
a = bar(1, 2, 3);
a[0] = 3.5;
a[1] = 'hi';
b = bar(1, 2, 3);
assertKind(elements_kind.packed, b);
})();
(function changeOptimizedEmptyArrayKind() {
function f() {
return new Array();
};
%PrepareFunctionForOptimization(f);
var a = f();
assertKind('packed smi elements', a);
a = f();
assertKind('packed smi elements', a);
a = f();
a.push(0.5);
assertKind('packed double elements', a);
%OptimizeFunctionOnNextCall(f);
a = f();
assertKind('packed double elements', a);
})();
(function changeOptimizedArrayLiteralKind() {
function f() {
return [1, 2];
};
%PrepareFunctionForOptimization(f);
var a = f();
assertKind('packed smi elements', a);
a = f();
a.push(0.5);
assertKind('packed double elements', a);
a = f();
assertKind('packed double elements', a);
assertFalse(isHoley(a));
a = f();
a.push(undefined);
assertKind('packed elements', a);
assertFalse(isHoley(a));
a = f();
assertKind('packed elements', a);
assertFalse(isHoley(a));
%OptimizeFunctionOnNextCall(f);
a = f();
assertKind('packed elements', a);
assertFalse(isHoley(a));
a = f();
assertKind('packed elements', a);
assertFalse(isHoley(a));
})();
(function changeOptimizedEmptyArrayLiteralKind() {
function f() {
return [];
};
%PrepareFunctionForOptimization(f);
var a = f();
assertKind('packed smi elements', a);
assertFalse(isHoley(a));
a = f();
a.push(0.5);
assertKind('packed double elements', a);
assertFalse(isHoley(a));
a = f();
assertKind('packed double elements', a);
assertFalse(isHoley(a));
%OptimizeFunctionOnNextCall(f);
a = f();
assertKind('packed double elements', a);
assertFalse(isHoley(a));
a = f();
assertKind('packed double elements', a);
assertFalse(isHoley(a));
})();
(function changeEmptyArrayLiteralKind2() {
function f() {
var literal = [];
%HeapObjectVerify(literal);
return literal;
};
%PrepareFunctionForOptimization(f);
var a = f();
assertKind('packed smi elements', a);
assertFalse(isHoley(a));
a = f();
a.push(0.5);
assertKind('packed double elements', a);
assertFalse(isHoley(a));
a = f();
assertKind('packed double elements', a);
assertFalse(isHoley(a));
a = f();
a.push(undefined);
assertKind('packed elements', a);
assertFalse(isHoley(a));
a = f();
assertKind('packed elements', a);
assertFalse(isHoley(a));
a = f();
a[10] = 1;
assertKind('packed elements', a);
assertTrue(isHoley(a));
a = f();
assertKind('packed elements', a);
assertTrue(isHoley(a));
a = f();
a[10000] = 1;
assertKind('dictionary elements', a);
assertFalse(isHoley(a));
a = f();
assertKind('packed elements', a);
assertTrue(isHoley(a));
})();

View File

@ -0,0 +1,209 @@
// Copyright 2012 the V8 project authors. All rights reserved.
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following
// disclaimer in the documentation and/or other materials provided
// with the distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// Flags: --allow-natives-syntax --expose-gc --ignition-osr --no-always-turbofan
// Flags: --turbofan
// IC and Crankshaft support for smi-only elements in dynamic array literals.
function get(foo) { return foo; } // Used to generate dynamic values.
function array_literal_test() {
var a0 = [1, 2, 3];
assertTrue(%HasSmiElements(a0));
var a1 = [get(1), get(2), get(3)];
assertTrue(%HasSmiElements(a1));
var b0 = [1, 2, get("three")];
assertTrue(%HasObjectElements(b0));
var b1 = [get(1), get(2), get("three")];
assertTrue(%HasObjectElements(b1));
var c0 = [1, 2, get(3.5)];
assertTrue(%HasDoubleElements(c0));
assertEquals(3.5, c0[2]);
assertEquals(2, c0[1]);
assertEquals(1, c0[0]);
var c1 = [1, 2, 3.5];
assertTrue(%HasDoubleElements(c1));
assertEquals(3.5, c1[2]);
assertEquals(2, c1[1]);
assertEquals(1, c1[0]);
var c2 = [get(1), get(2), get(3.5)];
assertTrue(%HasDoubleElements(c2));
assertEquals(3.5, c2[2]);
assertEquals(2, c2[1]);
assertEquals(1, c2[0]);
var object = new Object();
var d0 = [1, 2, object];
assertTrue(%HasObjectElements(d0));
assertEquals(object, d0[2]);
assertEquals(2, d0[1]);
assertEquals(1, d0[0]);
var e0 = [1, 2, 3.5];
assertTrue(%HasDoubleElements(e0));
assertEquals(3.5, e0[2]);
assertEquals(2, e0[1]);
assertEquals(1, e0[0]);
var f0 = [1, 2, [1, 2]];
assertTrue(%HasObjectElements(f0));
assertEquals([1,2], f0[2]);
assertEquals(2, f0[1]);
assertEquals(1, f0[0]);
}
%PrepareFunctionForOptimization(array_literal_test);
%PrepareFunctionForOptimization(array_literal_test);
for (var i = 0; i < 3; i++) {
array_literal_test();
}
%OptimizeFunctionOnNextCall(array_literal_test);
array_literal_test();
function test_large_literal() {
function d() {
gc();
return 2.5;
}
function o() {
gc();
return new Object();
}
large =
[ 0, 1, 2, 3, 4, 5, d(), d(), d(), d(), d(), d(), o(), o(), o(), o() ];
assertFalse(%HasDictionaryElements(large));
assertFalse(%HasSmiElements(large));
assertFalse(%HasDoubleElements(large));
assertTrue(%HasObjectElements(large));
assertEquals(large,
[0, 1, 2, 3, 4, 5, 2.5, 2.5, 2.5, 2.5, 2.5, 2.5,
new Object(), new Object(), new Object(), new Object()]);
}
%PrepareFunctionForOptimization(test_large_literal);
%PrepareFunctionForOptimization(test_large_literal);
for (var i = 0; i < 3; i++) {
test_large_literal();
}
%OptimizeFunctionOnNextCall(test_large_literal);
test_large_literal();
function deopt_array(use_literal) {
if (use_literal) {
return [.5, 3, 4];
} else {
return new Array();
}
}
%PrepareFunctionForOptimization(deopt_array);
%PrepareFunctionForOptimization(deopt_array);
deopt_array(false);
deopt_array(false);
deopt_array(false);
%OptimizeFunctionOnNextCall(deopt_array);
var turbofan = willBeTurbofanned(deopt_array);
var array = deopt_array(false);
assertOptimized(deopt_array);
if (turbofan) {
deopt_array(true);
assertOptimized(deopt_array);
array = deopt_array(false);
assertOptimized(deopt_array);
}
// Check that unexpected changes in the objects stored into the boilerplate
// also force a deopt.
function deopt_array_literal_all_smis(a) {
return [0, 1, a];
}
%PrepareFunctionForOptimization(deopt_array_literal_all_smis);
%PrepareFunctionForOptimization(deopt_array_literal_all_smis);
deopt_array_literal_all_smis(2);
deopt_array_literal_all_smis(3);
deopt_array_literal_all_smis(4);
array = deopt_array_literal_all_smis(4);
assertEquals(0, array[0]);
assertEquals(1, array[1]);
assertEquals(4, array[2]);
%OptimizeFunctionOnNextCall(deopt_array_literal_all_smis);
array = deopt_array_literal_all_smis(5);
array = deopt_array_literal_all_smis(6);
assertOptimized(deopt_array_literal_all_smis);
assertEquals(0, array[0]);
assertEquals(1, array[1]);
assertEquals(6, array[2]);
array = deopt_array_literal_all_smis(.5);
assertUnoptimized(deopt_array_literal_all_smis);
assertEquals(0, array[0]);
assertEquals(1, array[1]);
assertEquals(.5, array[2]);
function deopt_array_literal_all_doubles(a) {
return [0.5, 1, a];
}
%PrepareFunctionForOptimization(deopt_array_literal_all_doubles);
%PrepareFunctionForOptimization(deopt_array_literal_all_doubles);
deopt_array_literal_all_doubles(.5);
deopt_array_literal_all_doubles(.5);
deopt_array_literal_all_doubles(.5);
array = deopt_array_literal_all_doubles(0.5);
assertEquals(0.5, array[0]);
assertEquals(1, array[1]);
assertEquals(0.5, array[2]);
%OptimizeFunctionOnNextCall(deopt_array_literal_all_doubles);
array = deopt_array_literal_all_doubles(5);
array = deopt_array_literal_all_doubles(6);
assertOptimized(deopt_array_literal_all_doubles);
assertEquals(0.5, array[0]);
assertEquals(1, array[1]);
assertEquals(6, array[2]);
var foo = new Object();
array = deopt_array_literal_all_doubles(foo);
assertUnoptimized(deopt_array_literal_all_doubles);
assertEquals(0.5, array[0]);
assertEquals(1, array[1]);
assertEquals(foo, array[2]);
(function literals_after_osr() {
var color = [0];
// Trigger OSR.
while ((%GetOptimizationStatus(literals_after_osr) &
V8OptimizationStatus.kTopmostFrameIsTurboFanned) !== 0) {}
return [color[0]];
})();

View File

@ -0,0 +1,172 @@
// Copyright 2014 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Flags: --allow-natives-syntax
function testAdd(mode) {
var a = [];
Object.defineProperty(a, "length", { writable : false});
function check(f) {
assertThrows(function() { f(a) }, TypeError);
assertFalse(0 in a);
assertEquals(0, a.length);
}
function push(a) {
a.push(3);
}
if (mode == "fast properties") %ToFastProperties(a);
%PrepareFunctionForOptimization(push);
check(push);
check(push);
check(push);
%OptimizeFunctionOnNextCall(push);
check(push);
function unshift(a) {
a.unshift(3);
}
%PrepareFunctionForOptimization(unshift);
check(unshift);
check(unshift);
check(unshift);
%OptimizeFunctionOnNextCall(unshift);
check(unshift);
function splice(a) {
a.splice(0, 0, 3);
}
%PrepareFunctionForOptimization(splice);
check(splice);
check(splice);
check(splice);
%OptimizeFunctionOnNextCall(splice);
check(splice);
}
testAdd("fast properties");
testAdd("normalized");
function testRemove(a, mode) {
Object.defineProperty(a, "length", { writable : false});
function check(f) {
assertThrows(function() { f(a) }, TypeError);
assertEquals(3, a.length);
}
if (mode == "fast properties") %ToFastProperties(a);
function pop(a) {
a.pop();
}
%PrepareFunctionForOptimization(pop);
check(pop);
check(pop);
check(pop);
%OptimizeFunctionOnNextCall(pop);
check(pop);
function shift(a) {
a.shift();
}
%PrepareFunctionForOptimization(shift);
check(shift);
check(shift);
check(shift);
%OptimizeFunctionOnNextCall(shift);
check(shift);
function splice(a) {
a.splice(0, 1);
}
%PrepareFunctionForOptimization(splice);
check(splice);
check(splice);
check(splice);
%OptimizeFunctionOnNextCall(splice);
check(splice);
%ClearFunctionFeedback(pop);
%ClearFunctionFeedback(shift);
%ClearFunctionFeedback(splice);
}
for (var i = 0; i < 3; i++) {
var a = [1, 2, 3];
if (i == 1) {
a = [1, 2, 3.5];
} else if (i == 2) {
a = [1, 2, "string"];
}
testRemove(a, "fast properties");
testRemove(a, "normalized");
}
var b = [];
Object.defineProperty(b.__proto__, "0", {
set : function(v) {
b.x = v;
Object.defineProperty(b, "length", { writable : false });
},
get: function() {
return b.x;
}
});
b = [];
try {
b.push(3, 4, 5);
} catch(e) { }
assertFalse(1 in b);
assertFalse(2 in b);
assertEquals(0, b.length);
b = [];
try {
b.unshift(3, 4, 5);
} catch(e) { }
assertFalse(1 in b);
assertFalse(2 in b);
assertEquals(0, b.length);
b = [1, 2];
try {
b.unshift(3, 4, 5);
} catch(e) { }
assertEquals(3, b[0]);
assertEquals(4, b[1]);
assertEquals(5, b[2]);
assertEquals(1, b[3]);
assertEquals(2, b[4]);
assertEquals(5, b.length);
b = [1, 2];
Object.defineProperty(b.__proto__, "4", {
set : function(v) {
b.z = v;
Object.defineProperty(b, "length", { writable : false });
},
get: function() {
return b.z;
}
});
try {
b.unshift(3, 4, 5);
} catch(e) { }
assertFalse(2 in b);
assertFalse(3 in b);
assertEquals(2, b.length);

View File

@ -0,0 +1,313 @@
// Copyright 2012 the V8 project authors. All rights reserved.
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following
// disclaimer in the documentation and/or other materials provided
// with the distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// Flags: --allow-natives-syntax
// IC and Crankshaft support for smi-only elements in dynamic array literals.
function get(foo) { return foo; } // Used to generate dynamic values.
// This code exists to eliminate the learning influence of AllocationSites
// on the following tests.
function make_array_string(literal) {
this.__sequence = this.__sequence + 1;
return "/* " + this.__sequence + " */ " + literal;
}
function make_array(literal) {
return eval(make_array_string(literal));
}
var __sequence = 0;
function array_natives_test() {
// Ensure small array literals start in specific element kind mode.
assertTrue(%HasSmiElements([]));
assertTrue(%HasSmiElements([1]));
assertTrue(%HasSmiElements([1,2]));
assertTrue(%HasDoubleElements([1.1]));
assertTrue(%HasDoubleElements([1.1,2]));
// Push
var a0 = make_array("[1, 2, 3]");
assertTrue(%HasSmiElements(a0));
assertEquals(4, a0.push(4));
assertTrue(%HasSmiElements(a0));
assertEquals(5, a0.push(1.3));
assertTrue(%HasDoubleElements(a0));
assertEquals(6, a0.push(1.5));
assertTrue(%HasDoubleElements(a0));
assertEquals(7, a0.push({}));
assertTrue(%HasObjectElements(a0));
assertEquals(8, a0.push({}));
assertTrue(%HasObjectElements(a0));
assertEquals([1,2,3,4,1.3,1.5,{},{}], a0);
// Concat
var a1;
a1 = [1,2,3].concat([]);
//assertTrue(%HasSmiElements(a1));
assertEquals([1,2,3], a1);
a1 = [1,2,3].concat([4,5,6]);
assertTrue(%HasSmiElements(a1));
assertEquals([1,2,3,4,5,6], a1);
a1 = [1,2,3].concat([4,5,6], [7,8,9]);
assertTrue(%HasSmiElements(a1));
assertEquals([1,2,3,4,5,6,7,8,9], a1);
a1 = [1.1,2,3].concat([]);
assertTrue(%HasDoubleElements(a1));
assertEquals([1.1,2,3], a1);
a1 = [1,2,3].concat([1.1, 2]);
assertTrue(%HasDoubleElements(a1));
assertEquals([1,2,3,1.1,2], a1);
a1 = [1.1,2,3].concat([1, 2]);
assertTrue(%HasDoubleElements(a1));
assertEquals([1.1,2,3,1,2], a1);
a1 = [1.1,2,3].concat([1.2, 2]);
assertTrue(%HasDoubleElements(a1));
assertEquals([1.1,2,3,1.2,2], a1);
a1 = [1,2,3].concat([{}]);
assertTrue(%HasObjectElements(a1));
assertEquals([1,2,3,{}], a1);
a1 = [1.1,2,3].concat([{}]);
assertTrue(%HasObjectElements(a1));
assertEquals([1.1,2,3,{}], a1);
a1 = [{}].concat([1,2,3]);
assertTrue(%HasObjectElements(a1));
assertEquals([{},1,2,3], a1);
a1 = [{}].concat([1.1,2,3]);
assertTrue(%HasObjectElements(a1));
assertEquals([{},1.1,2,3], a1);
// Slice
var a2 = [1,2,3];
assertTrue(%HasSmiElements(a2.slice()));
assertTrue(%HasSmiElements(a2.slice(1)));
assertTrue(%HasSmiElements(a2.slice(1, 2)));
assertEquals([1,2,3], a2.slice());
assertEquals([2,3], a2.slice(1));
assertEquals([2], a2.slice(1,2));
a2 = [1.1,2,3];
assertTrue(%HasDoubleElements(a2.slice()));
assertTrue(%HasDoubleElements(a2.slice(1)) ||
%HasSmiElements(a2.slice(1)));
assertTrue(%HasDoubleElements(a2.slice(1, 2)) ||
%HasSmiElements(a2.slice(1, 2)));
assertEquals([1.1,2,3], a2.slice());
assertEquals([2,3], a2.slice(1));
assertEquals([2], a2.slice(1,2));
a2 = [{},2,3];
assertTrue(%HasObjectElements(a2.slice()));
assertTrue(%HasObjectElements(a2.slice(1)) ||
%HasSmiElements(a2.slice(1)));
assertTrue(%HasObjectElements(a2.slice(1, 2)) ||
%HasSmiElements(a2.slice(1, 2)));
assertEquals([{},2,3], a2.slice());
assertEquals([2,3], a2.slice(1));
assertEquals([2], a2.slice(1,2));
// Splice
var a3 = [1,2,3];
var a3r;
a3r = a3.splice(0, 0);
assertTrue(%HasSmiElements(a3r));
assertTrue(%HasSmiElements(a3));
assertEquals([], a3r);
assertEquals([1, 2, 3], a3);
a3 = [1,2,3];
a3r = a3.splice(0, 1);
assertTrue(%HasSmiElements(a3r));
assertTrue(%HasSmiElements(a3));
assertEquals([1], a3r);
assertEquals([2, 3], a3);
a3 = [1,2,3];
a3r = a3.splice(0, 0, 2);
assertTrue(%HasSmiElements(a3r));
assertTrue(%HasSmiElements(a3));
assertEquals([], a3r);
assertEquals([2, 1, 2, 3], a3);
a3 = [1,2,3];
a3r = a3.splice(0, 1, 2);
assertTrue(%HasSmiElements(a3r));
assertTrue(%HasSmiElements(a3));
assertEquals([1], a3r);
assertEquals([2, 2, 3], a3);
a3 = [1.1,2,3];
a3r = a3.splice(0, 0);
assertTrue(%HasDoubleElements(a3r));
assertTrue(%HasDoubleElements(a3));
assertEquals([], a3r);
assertEquals([1.1, 2, 3], a3);
a3 = [1.1, 2, 3];
a3r = a3.splice(0, 1);
assertTrue(%HasDoubleElements(a3r));
assertTrue(%HasDoubleElements(a3));
assertEquals([1.1], a3r);
assertEquals([2, 3], a3);
a3 = [1.1, 2, 3];
a3r = a3.splice(0, 0, 2);
assertTrue(%HasDoubleElements(a3r));
assertTrue(%HasDoubleElements(a3));
assertEquals([], a3r);
assertEquals([2, 1.1, 2, 3], a3);
a3 = [1.1, 2, 3];
assertTrue(%HasDoubleElements(a3));
a3r = a3.splice(0, 1, 2);
assertTrue(%HasDoubleElements(a3r));
assertTrue(%HasDoubleElements(a3));
assertEquals([1.1], a3r);
assertEquals([2, 2, 3], a3);
a3 = [1.1,2,3];
a3r = a3.splice(0, 0, 2.1);
assertTrue(%HasDoubleElements(a3r));
assertTrue(%HasDoubleElements(a3));
assertEquals([], a3r);
assertEquals([2.1, 1.1, 2, 3], a3);
a3 = [1.1,2,3];
a3r = a3.splice(0, 1, 2.2);
assertTrue(%HasDoubleElements(a3r));
assertTrue(%HasDoubleElements(a3));
assertEquals([1.1], a3r);
assertEquals([2.2, 2, 3], a3);
a3 = [1,2,3];
a3r = a3.splice(0, 0, 2.1);
assertTrue(%HasDoubleElements(a3r));
assertTrue(%HasDoubleElements(a3));
assertEquals([], a3r);
assertEquals([2.1, 1, 2, 3], a3);
a3 = [1,2,3];
a3r = a3.splice(0, 1, 2.2);
assertTrue(%HasDoubleElements(a3r));
assertTrue(%HasDoubleElements(a3));
assertEquals([1], a3r);
assertEquals([2.2, 2, 3], a3);
a3 = [{},2,3];
a3r = a3.splice(0, 0);
assertTrue(%HasObjectElements(a3r));
assertTrue(%HasObjectElements(a3));
assertEquals([], a3r);
assertEquals([{}, 2, 3], a3);
a3 = [1,2,{}];
a3r = a3.splice(0, 1);
assertTrue(%HasObjectElements(a3r));
assertTrue(%HasObjectElements(a3));
assertEquals([1], a3r);
assertEquals([2, {}], a3);
a3 = [1,2,3];
a3r = a3.splice(0, 0, {});
assertTrue(%HasObjectElements(a3r));
assertTrue(%HasObjectElements(a3));
assertEquals([], a3r);
assertEquals([{}, 1, 2, 3], a3);
a3 = [1,2,3];
a3r = a3.splice(0, 1, {});
assertTrue(%HasObjectElements(a3r));
assertTrue(%HasObjectElements(a3));
assertEquals([1], a3r);
assertEquals([{}, 2, 3], a3);
a3 = [1.1,2,3];
a3r = a3.splice(0, 0, {});
assertTrue(%HasObjectElements(a3r));
assertTrue(%HasObjectElements(a3));
assertEquals([], a3r);
assertEquals([{}, 1.1, 2, 3], a3);
a3 = [1.1,2,3];
a3r = a3.splice(0, 1, {});
assertTrue(%HasObjectElements(a3r));
assertTrue(%HasObjectElements(a3));
assertEquals([1.1], a3r);
assertEquals([{}, 2, 3], a3);
a3 = [1.1, 2.2, 3.3];
a3r = a3.splice(2, 1);
assertTrue(%HasDoubleElements(a3r));
assertTrue(%HasDoubleElements(a3));
assertEquals([3.3], a3r);
//assertTrue(%HasDoubleElements(a3r));
assertEquals([1.1, 2.2], a3);
//assertTrue(%HasDoubleElements(a3r));
a3r = a3.splice(1, 1, 4.4, 5.5);
//assertTrue(%HasDoubleElements(a3r));
//assertTrue(%HasDoubleElements(a3));
assertEquals([2.2], a3r);
assertEquals([1.1, 4.4, 5.5], a3);
// Pop
var a4 = [1,2,3];
assertEquals(3, a4.pop());
assertEquals([1,2], a4);
//assertTrue(%HasSmiElements(a4));
a4 = [1.1,2,3];
assertEquals(3, a4.pop());
assertEquals([1.1,2], a4);
//assertTrue(%HasDoubleElements(a4));
a4 = [{},2,3];
assertEquals(3, a4.pop());
assertEquals([{},2], a4);
//assertTrue(%HasObjectElements(a4));
// Shift
var a4 = [1,2,3];
assertEquals(1, a4.shift());
assertEquals([2,3], a4);
//assertTrue(%HasSmiElements(a4));
a4 = [1.1,2,3];
assertEquals(1.1, a4.shift());
assertEquals([2,3], a4);
//assertTrue(%HasDoubleElements(a4));
a4 = [{},2,3];
assertEquals({}, a4.shift());
assertEquals([2,3], a4);
//assertTrue(%HasObjectElements(a4));
// Unshift
var a4 = [1,2,3];
assertEquals(4, a4.unshift(1));
assertTrue(%HasSmiElements(a4));
assertEquals([1,1,2,3], a4);
a4 = [1,2,3];
assertEquals(4, a4.unshift(1.1));
assertTrue(%HasDoubleElements(a4));
assertEquals([1.1,1,2,3], a4);
a4 = [1.1,2,3];
assertEquals(4, a4.unshift(1));
assertTrue(%HasDoubleElements(a4));
assertEquals([1,1.1,2,3], a4);
a4 = [{},2,3];
assertEquals(4, a4.unshift(1));
assertTrue(%HasObjectElements(a4));
assertEquals([1,{},2,3], a4);
a4 = [{},2,3];
assertEquals(4, a4.unshift(1.1));
assertTrue(%HasObjectElements(a4));
assertEquals([1.1,{},2,3], a4);
}
%PrepareFunctionForOptimization(array_natives_test);
for (var i = 0; i < 3; i++) {
array_natives_test();
}
%OptimizeFunctionOnNextCall(array_natives_test);
array_natives_test();

View File

@ -0,0 +1,47 @@
// Copyright 2013 the V8 project authors. All rights reserved.
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following
// disclaimer in the documentation and/or other materials provided
// with the distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// Flags: --allow-natives-syntax
function TestNonSmiArrayLength() {
function f(a) {
return a.length+1;
}
%PrepareFunctionForOptimization(f);
var a = [];
a.length = 0xFFFF;
assertSame(0x10000, f(a));
assertSame(0x10000, f(a));
%OptimizeFunctionOnNextCall(f);
a.length = 0xFFFFFFFF;
assertSame(0x100000000, f(a));
}
TestNonSmiArrayLength();

169
deps/v8/test/mjsunit/array-pop.js vendored Normal file
View File

@ -0,0 +1,169 @@
// Copyright 2010 the V8 project authors. All rights reserved.
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following
// disclaimer in the documentation and/or other materials provided
// with the distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// Flags: --allow-natives-syntax
// Test that elements are replaced with holes.
// This test must be the first test to guarantee elements protectors are valid.
(function() {
function pop(arr) {
return arr.pop();
}
let smi_arr = [1, 2, 3, 4];
let object_arr = [{}, {}, {}, {}];
let double_arr = [1.1, 2.2, 3.3, 4.4];
%PrepareFunctionForOptimization(pop);
assertEquals(4, pop(smi_arr));
assertEquals({}, pop(object_arr));
assertEquals(4.4, pop(double_arr));
assertEquals(3, pop(smi_arr));
assertEquals({}, pop(object_arr));
assertEquals(3.3, pop(double_arr));
%OptimizeFunctionOnNextCall(pop);
assertEquals(2, pop(smi_arr));
assertEquals({}, pop(object_arr));
assertEquals(2.2, pop(double_arr));
smi_arr[2] = 3;
object_arr[2] = {};
double_arr[2] = 3.3;
assertEquals(undefined, smi_arr[1]);
assertEquals(undefined, object_arr[1]);
assertEquals(undefined, double_arr[1]);
})();
// Check pops with various number of arguments.
(function() {
var a = [];
for (var i = 0; i < 7; i++) {
a = [7, 6, 5, 4, 3, 2, 1];
assertEquals(1, a.pop(), "1st pop");
assertEquals(6, a.length, "length 1st pop");
assertEquals(2, a.pop(1), "2nd pop");
assertEquals(5, a.length, "length 2nd pop");
assertEquals(3, a.pop(1, 2), "3rd pop");
assertEquals(4, a.length, "length 3rd pop");
assertEquals(4, a.pop(1, 2, 3), "4th pop");
assertEquals(3, a.length, "length 4th pop");
assertEquals(5, a.pop(), "5th pop");
assertEquals(2, a.length, "length 5th pop");
assertEquals(6, a.pop(), "6th pop");
assertEquals(1, a.length, "length 6th pop");
assertEquals(7, a.pop(), "7th pop");
assertEquals(0, a.length, "length 7th pop");
assertEquals(undefined, a.pop(), "8th pop");
assertEquals(0, a.length, "length 8th pop");
assertEquals(undefined, a.pop(1, 2, 3), "9th pop");
assertEquals(0, a.length, "length 9th pop");
}
// Check that pop works on inherited properties.
for (var i = 0; i < 10 ;i++) { // Ensure ICs are stabilized.
Array.prototype[1] = 1;
Array.prototype[3] = 3;
Array.prototype[5] = 5;
Array.prototype[7] = 7;
Array.prototype[9] = 9;
a = [0,1,2,,4,,6,7,8,,];
assertEquals(10, a.length, "inherit-initial-length");
for (var j = 9; j >= 0; j--) {
assertEquals(j + 1, a.length, "inherit-pre-length-" + j);
assertTrue(j in a, "has property " + j);
var own = a.hasOwnProperty(j);
var inherited = Array.prototype.hasOwnProperty(j);
assertEquals(j, a.pop(), "inherit-pop");
assertEquals(j, a.length, "inherit-post-length");
assertFalse(a.hasOwnProperty(j), "inherit-deleted-own-" + j);
assertEquals(inherited, Array.prototype.hasOwnProperty(j),
"inherit-not-deleted-inherited" + j);
}
Array.prototype.length = 0; // Clean-up.
}
// Check that pop works on inherited properties for
// arrays with array prototype.
for (var i = 0; i < 10 ;i++) { // Ensure ICs are stabilized.
var array_proto = [];
array_proto[1] = 1;
array_proto[3] = 3;
array_proto[5] = 5;
array_proto[7] = 7;
array_proto[9] = 9;
a = [0,1,2,,4,,6,7,8,,];
a.__proto__ = array_proto;
assertEquals(10, a.length, "array_proto-inherit-initial-length");
for (var j = 9; j >= 0; j--) {
assertEquals(j + 1, a.length, "array_proto-inherit-pre-length-" + j);
assertTrue(j in a, "array_proto-has property " + j);
var own = a.hasOwnProperty(j);
var inherited = array_proto.hasOwnProperty(j);
assertEquals(j, a.pop(), "array_proto-inherit-pop");
assertEquals(j, a.length, "array_proto-inherit-post-length");
assertFalse(a.hasOwnProperty(j), "array_proto-inherit-deleted-own-" + j);
assertEquals(inherited, array_proto.hasOwnProperty(j),
"array_proto-inherit-not-deleted-inherited" + j);
}
}
// Check that pop works on inherited properties for
// arrays with array prototype.
})();
// Test the case of not JSArray receiver.
// Regression test for custom call generators, see issue 684.
(function() {
var a = [];
for (var i = 0; i < 100; i++) a.push(i);
var x = {__proto__: a};
for (var i = 0; i < 100; i++) {
assertEquals(99 - i, x.pop(), i + 'th iteration');
}
})();
(function () {
function f(a, deopt) {
var v = a.pop() ? 1 : 2;
if (deopt) %DeoptimizeFunction(f);
return v;
}
%PrepareFunctionForOptimization(f);
var a = [true, true, true, true]
assertEquals(1, f(a, false));
assertEquals(1, f(a, false));
%OptimizeFunctionOnNextCall(f);
assertEquals(1, f(a, false));
assertEquals(1, f(a, true));
})();

View File

@ -0,0 +1,20 @@
// Copyright 2018 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
/* Test behaviors when the prototype has elements */
// every
(function () {
var array = [,];
function every() {
return array.every(v => v > 0);
}
assertEquals(every(), true);
array.__proto__.push(-6);
assertEquals(every(), false);
})();

View File

@ -0,0 +1,22 @@
// Copyright 2018 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
/* Test behaviors when the prototype has elements */
// filter
(function () {
var array = [,];
function filter() {
return array.filter(v => v > 0);
}
assertEquals(filter(), []);
array.__proto__.push(6);
var narr = filter();
assertNotEquals(Object.getOwnPropertyDescriptor(narr, 0), undefined);
assertEquals(narr, [6]);
})();

View File

@ -0,0 +1,20 @@
// Copyright 2018 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
/* Test behaviors when the prototype has elements */
// find
(function () {
var array = [,];
function find() {
return array.find(v => v > 0);
}
assertEquals(find(), undefined);
array.__proto__.push(6);
assertEquals(find(), 6);
})();

View File

@ -0,0 +1,20 @@
// Copyright 2018 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
/* Test behaviors when the prototype has elements */
// findIndex
(function () {
var array = [,];
function findIndex() {
return array.findIndex(v => v > 0);
}
assertEquals(findIndex(), -1);
array.__proto__.push(6);
assertEquals(findIndex(), 0);
})();

View File

@ -0,0 +1,26 @@
// Copyright 2018 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
/* Test behaviors when the prototype has elements */
// forEach
(function () {
var array = [,];
function increment(v, k, arr) { arr[k] = v + 1; }
function forEach() {
array.forEach(increment);
}
forEach();
assertEquals(array, [,]);
// behavior from the prototype
array.__proto__.push(5);
assertEquals(Object.getOwnPropertyDescriptor(array, 0), undefined);
forEach();
assertNotEquals(Object.getOwnPropertyDescriptor(array, 0), undefined);
assertEquals(array[0], 6);
})();

View File

@ -0,0 +1,36 @@
// Copyright 2018 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
/* Test behaviors when the prototype has elements */
// includes
(function() {
const iarr = [,3];
function includes(arr, val) {
return arr.includes(val);
}
assertFalse(includes(iarr, 2));
assertTrue(includes(iarr, 3));
iarr.__proto__ = [2];
assertTrue(includes(iarr, 2));
})();
// This pollutes the Array prototype, so we should not run more tests
// in the same environment after this.
(function () {
var array = [,];
function includes(val) {
return array.includes(val);
}
assertFalse(includes(6));
array.__proto__.push(6);
assertTrue(includes(6));
})();

View File

@ -0,0 +1,36 @@
// Copyright 2018 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// indexOf
/* Test behaviors when the prototype has elements */
(function() {
const iarr = [,3];
function indexOf(arr, val) {
return arr.indexOf(val);
}
assertEquals(-1, indexOf(iarr, 2));
assertEquals(1, indexOf(iarr, 3));
iarr.__proto__ = [2];
assertEquals(0, indexOf(iarr, 2));
})();
// This pollutes the Array prototype, so we should not run more tests
// in the same environment after this.
(function () {
var array = [,];
function indexOf(val) {
return array.indexOf(val);
}
assertEquals(indexOf(6), -1);
array.__proto__.push(6);
assertEquals(indexOf(6), 0);
})();

View File

@ -0,0 +1,20 @@
// Copyright 2018 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
/* Test behaviors when the prototype has elements */
// lastIndexOf
(function () {
var array = [,];
function lastIndexOf(val) {
return array.lastIndexOf(val);
}
assertEquals(lastIndexOf(6), -1);
array.__proto__.push(6);
assertEquals(lastIndexOf(6), 0);
})();

View File

@ -0,0 +1,57 @@
// Copyright 2025 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 --no-always-turbofan
load('test/mjsunit/elements-kinds-helpers.js');
// Tests calling Array.prototype.map on a dictionary mode array invalidate the
// "array constructor" protector, so they must be in a separate file.
function plusOne(x) {
return x + 1;
}
function plusOneInObject(x) {
return {a: x.a + 1};
}
(function testDictionaryElements1() {
function foo(a) {
return a.map(plusOne);
}
const array = [1, 2, 3];
MakeArrayDictionaryMode(array, () => { return 0; });
assertTrue(%HasDictionaryElements(array));
const result = foo(array);
assertTrue(HasHoleySmiElements(result));
})();
(function testDictionaryElements2() {
function foo(a) {
return a.map(plusOne);
}
const array = [1, 2, 3];
MakeArrayDictionaryMode(array, () => { return 0.1; });
assertTrue(%HasDictionaryElements(array));
const result = foo(array);
assertTrue(HasHoleyDoubleElements(result));
})();
(function testDictionaryElements3() {
function foo(a) {
return a.map(plusOneInObject);
}
const array = [{a: 1}, {a: 2}, {a: 3}];
MakeArrayDictionaryMode(array, () => { return {a: 0}; });
assertTrue(%HasDictionaryElements(array));
const result = foo(array);
assertTrue(HasHoleyObjectElements(result));
})();

View File

@ -0,0 +1,308 @@
// Copyright 2025 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 --no-always-turbofan
load('test/mjsunit/elements-kinds-helpers.js');
function identity(x) {
return x;
}
function plusOne(x) {
return x + 1;
}
function plusOneAndMore(x) {
return x + 1.1;
}
function plusOneInObject(x) {
return {a: x.a + 1};
}
function wrapInObject(x) {
return {a: x};
}
function unwrapObject(x) {
return x.a;
}
let ix = 0;
function transitionFromSmiToDouble(x) {
if (ix++ == 0) {
return 0;
}
return 1.1;
}
function transitionFromSmiToObject(x) {
if (ix++ == 0) {
return 0;
}
return {a: 1};
}
function transitionFromDoubleToObject(x) {
if (ix++ == 0) {
return 1.1;
}
return {a: 1};
}
function transitionFromObjectToDouble(x) {
if (ix++ == 0) {
return {a: 1};
}
return 1.1;
}
function resetTransitionFunctions() {
ix = 0;
}
(function testPackedSmiElementsWithIdentity() {
function foo(a) {
return a.map(identity);
}
%PrepareFunctionForOptimization(foo);
const array = [1, 2, 3];
const result = foo(array);
assertTrue(HasPackedSmiElements(result));
})();
(function testPackedSmiElements() {
function foo(a) {
return a.map(plusOne);
}
const array = [1, 2, 3];
const result = foo(array);
assertTrue(HasPackedSmiElements(result));
})();
(function testHoleySmiElements() {
function foo(a) {
return a.map(plusOne);
}
const array = [1, 2, , 3];
const result = foo(array);
assertTrue(HasHoleySmiElements(result));
})();
(function testPackedDoubleElements1() {
function foo(a) {
return a.map(plusOne);
}
const array = [1, 2, 3.3];
const result = foo(array);
assertTrue(HasPackedDoubleElements(result));
})();
(function testPackedDoubleElements2() {
function foo(a) {
return a.map(plusOneAndMore);
}
const array = [1, 2, 3];
const result = foo(array);
assertTrue(HasPackedDoubleElements(result));
})();
(function testHoleyDoubleElements1() {
function foo(a) {
return a.map(plusOne);
}
const array = [1, 2, , 3.3];
const result = foo(array);
assertTrue(HasHoleyDoubleElements(result));
})();
(function testHoleyDoubleElements2() {
function foo(a) {
return a.map(plusOneAndMore);
}
const array = [1, 2, , 3];
const result = foo(array);
assertTrue(HasHoleyDoubleElements(result));
})();
(function testPackedElements1() {
function foo(a) {
return a.map(plusOneInObject);
}
const array = [{a: 1}, {a: 2}, {a: 3}];
const result = foo(array);
assertTrue(HasPackedObjectElements(result));
})();
(function testPackedElements2() {
function foo(a) {
return a.map(wrapInObject);
}
const array = [1, 2, 3];
const result = foo(array);
assertTrue(HasPackedObjectElements(result));
})();
(function testHoleyObjectElements1() {
function foo(a) {
return a.map(plusOneInObject);
}
const array = [{a: 1}, {a: 2}, , {a: 3}];
const result = foo(array);
assertTrue(HasHoleyObjectElements(result));
})();
(function testHoleyObjectElements2() {
function foo(a) {
return a.map(wrapInObject);
}
const array = [1, 2, , 3];
const result = foo(array);
assertTrue(HasHoleyObjectElements(result));
})();
(function testFromObjectToPackedSmi() {
function foo(a) {
return a.map(unwrapObject);
}
const array = [{a: 1}, {a: 2}, {a: 3}];
const result = foo(array);
assertTrue(HasPackedSmiElements(result));
})();
(function testFromObjectToHoleySmi() {
function foo(a) {
return a.map(unwrapObject);
}
const array = [{a: 1}, {a: 2}, , {a: 3}];
const result = foo(array);
assertTrue(HasHoleySmiElements(result));
})();
(function testTransitionFromPackedSmiToDoubleWhileMapping() {
resetTransitionFunctions();
function foo(a) {
return a.map(transitionFromSmiToDouble);
}
const array = [0, 0, 0];
const result = foo(array);
assertTrue(HasPackedDoubleElements(result));
})();
(function testTransitionFromHoleySmiToDoubleWhileMapping() {
resetTransitionFunctions();
function foo(a) {
return a.map(transitionFromSmiToDouble);
}
const array = [0, 0, , 0];
const result = foo(array);
assertTrue(HasHoleyDoubleElements(result));
})();
(function testTransitionFromPackedSmiToObjectWhileMapping() {
resetTransitionFunctions();
function foo(a) {
return a.map(transitionFromSmiToObject);
}
const array = [0, 0, 0];
const result = foo(array);
assertTrue(HasPackedObjectElements(result));
})();
(function testTransitionFromHoleySmiToObjectWhileMapping() {
resetTransitionFunctions();
function foo(a) {
return a.map(transitionFromSmiToObject);
}
const array = [0, 0, , 0];
const result = foo(array);
assertTrue(HasHoleyObjectElements(result));
})();
(function testTransitionFromPackedSmiToDoubleToObjectWhileMapping() {
resetTransitionFunctions();
function foo(a) {
return a.map(transitionFromDoubleToObject);
}
const array = [0, 0, 0];
const result = foo(array);
assertTrue(HasPackedObjectElements(result));
})();
(function testTransitionFromHoleySmiToDoubleToObjectWhileMapping() {
resetTransitionFunctions();
function foo(a) {
return a.map(transitionFromDoubleToObject);
}
const array = [0, 0, , 0];
const result = foo(array);
assertTrue(HasHoleyObjectElements(result));
})();
(function testTransitionFromPackedSmiToObjectToDoubleWhileMapping() {
resetTransitionFunctions();
function foo(a) {
return a.map(transitionFromObjectToDouble);
}
const array = [0, 0, 0];
const result = foo(array);
assertTrue(HasPackedObjectElements(result));
})();
(function testTransitionFromHoleySmiToObjectToDoubleWhileMapping() {
resetTransitionFunctions();
function foo(a) {
return a.map(transitionFromObjectToDouble);
}
const array = [0, 0, , 0];
const result = foo(array);
assertTrue(HasHoleyObjectElements(result));
})();
(function testMapperReducesLength() {
let array = [0, 1, 2];
function evil(x) {
if (x == 1) {
array.length = 1;
}
return x;
}
function foo(a) {
return a.map(evil);
}
const result = foo(array);
assertTrue(HasHoleySmiElements(result));
assertEquals(undefined, result[2]);
})();

View File

@ -0,0 +1,21 @@
// Copyright 2018 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
/* Test behaviors when the prototype has elements */
// map
(function () {
var array = [,];
function map() {
return array.map(x => x + 1);
}
assertEquals(map(), [,]);
array.__proto__.push(5);
var narr = map();
assertNotEquals(Object.getOwnPropertyDescriptor(narr, 0), undefined);
assertEquals(narr[0], 6);
})();

View File

@ -0,0 +1,29 @@
// Copyright 2018 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
/* Test behaviors when the prototype has elements */
// pop
(function () {
var array = [,];
function pop() {
return array.pop();
}
assertEquals(pop(), undefined);
})();
(function () {
var array = [,];
function pop() {
return array.pop();
}
array.__proto__.push(6);
assertEquals(pop(), 6);
})();

View File

@ -0,0 +1,24 @@
// Copyright 2018 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
/* Test behaviors when the prototype has elements */
// reduce
(function () {
var array = [, 3];
function accumulate (prev, cur, curIdx, arr) { arr[curIdx] = cur + prev; }
function reduce() {
array.reduce(accumulate);
}
reduce();
assertEquals(array, [,3]);
array.__proto__.push(3);
reduce();
assertEquals(array, [, 6]);
assertEquals(Object.getOwnPropertyDescriptor(array, 0), undefined);
})();

View File

@ -0,0 +1,21 @@
// Copyright 2018 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
/* Test behaviors when the prototype has elements */
// slice
(function () {
var array = [,];
function slice() {
return array.slice();
}
assertEquals(slice(), [,]);
array.__proto__.push(5);
var narr = slice();
assertNotEquals(Object.getOwnPropertyDescriptor(narr, 0), undefined);
assertEquals(narr[0], 5);
})();

View File

@ -0,0 +1,20 @@
// Copyright 2018 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
/* Test behaviors when the prototype has elements */
// some
(function () {
var array = [,];
function some() {
return array.some(v => v > 0);
}
assertEquals(some(), false);
array.__proto__.push(6);
assertEquals(some(), true);
})();

View File

@ -0,0 +1,23 @@
// Copyright 2016 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Flags: --allow-natives-syntax
[1].push(1);
(function PushHoleBitPattern() {
function g(src, dst, i) {
dst[i] = src[i];
}
var b = new ArrayBuffer(8);
var i32 = new Int32Array(b);
i32[0] = 0xFFF7FFFF;
i32[1] = 0xFFF7FFFF;
var f64 = new Float64Array(b);
var a = [,2.5];
a.push(f64[0]);
assertTrue(Number.isNaN(a[2]));
})();

View File

@ -0,0 +1,36 @@
// Copyright 2013 the V8 project authors. All rights reserved.
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following
// disclaimer in the documentation and/or other materials provided
// with the distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// Check pushes of non-SMI values.
var a = [];
function func() {
return a.push(0x40000000) > 60;
}
assertFalse(func());
assertFalse(func());
assertFalse(func());

161
deps/v8/test/mjsunit/array-push.js vendored Normal file
View File

@ -0,0 +1,161 @@
// Copyright 2010 the V8 project authors. All rights reserved.
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following
// disclaimer in the documentation and/or other materials provided
// with the distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// Flags: --allow-natives-syntax
// Check pushes with various number of arguments.
(function() {
var a = [];
for (var i = 0; i < 7; i++) {
a = [];
assertEquals(0, a.push());
assertEquals([], a, "after .push()");
assertEquals(1, a.push(1), "length after .push(1)");
assertEquals([1], a, "after .push(1)");
assertEquals(3, a.push(2, 3), "length after .push(2, 3)");
assertEquals([1, 2, 3], a, "after .push(2, 3)");
assertEquals(6, a.push(4, 5, 6),
"length after .push(4, 5, 6)");
assertEquals([1, 2, 3, 4, 5, 6], a,
"after .push(4, 5, 5)");
assertEquals(10, a.push(7, 8, 9, 10),
"length after .push(7, 8, 9, 10)");
assertEquals([1, 2, 3, 4, 5, 6, 7, 8, 9, 10], a,
"after .push(7, 8, 9, 10)");
assertEquals(15, a.push(11, 12, 13, 14, 15),
"length after .push(11, 12, 13, 14, 15)");
assertEquals([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15], a,
"after .push(11, 12, 13, 14, 15)");
assertEquals(21, a.push(16, 17, 18, 19, 20, 21),
"length after .push(16, 17, 18, 19, 20, 21)");
assertEquals([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21], a,
"after .push(16, 17, 18, 19, 20, 21)");
assertEquals(28, a.push(22, 23, 24, 25, 26, 27, 28),
"length hafter .push(22, 23, 24, 25, 26, 27, 28)");
assertEquals([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28], a,
"after .push(22, 23, 24, 25, 26, 27, 28)");
}
})();
// Excerises various pushes to the array at the end of new space.
(function() {
var a = undefined;
for (var i = 0; i < 7; i++) {
a = [];
assertEquals(1, a.push(1));
assertEquals(2, a.push(2));
assertEquals(3, a.push(3));
assertEquals(4, a.push(4));
assertEquals(5, a.push(5));
assertEquals(6, a.push(6));
assertEquals(7, a.push(7));
assertEquals(8, a.push(8));
assertEquals(9, a.push(9));
assertEquals(10, a.push(10));
assertEquals(11, a.push(11));
assertEquals(12, a.push(12));
assertEquals(13, a.push(13));
assertEquals(14, a.push(14));
assertEquals(15, a.push(15));
assertEquals(16, a.push(16));
assertEquals(17, a.push(17));
assertEquals(18, a.push(18));
assertEquals(19, a.push(19));
assertEquals(20, a.push(20));
assertEquals(21, a.push(21));
assertEquals(22, a.push(22));
assertEquals(23, a.push(23));
assertEquals(24, a.push(24));
assertEquals(25, a.push(25));
assertEquals(26, a.push(26));
assertEquals(27, a.push(27));
assertEquals(28, a.push(28));
assertEquals(29, a.push(29));
}
})();
// Test the case of not JSArray receiver.
// Regression test for custom call generators, see issue 684.
(function() {
var x = {__proto__: []};
for (var i = 0; i < 100; i++) {
x.push("a");
assertEquals(i + 1, x.length, i + 'th iteration');
}
})();
(function() {
function f(a, i) {
a.push(i);
}
var a = [1,2,3];
a.f = function() { return 10; }
f(a, 4);
f(a, 5);
f(a, 6);
f(a, 7);
f(a, {});
assertEquals(10, a.f());
})();
(function() {
function f(a, i) {
a.push(i);
}
%PrepareFunctionForOptimization(f);
var a = [1,2,3];
a.f = function() { return 10; }
f(a, 4);
f(a, 5);
f(a, 6);
%OptimizeFunctionOnNextCall(f);
f(a, 7);
f(a, {});
assertEquals(10, a.f());
})();
(function testDoubleArrayPush() {
var a = [];
var max = 1000;
for (var i = 0; i < max; i++) {
a.push(i + 0.1);
}
assertEquals(max, a.length);
for (var i = 0; i < max; i++) {
assertEquals(i+0.1, a[i]);
}
})();

15
deps/v8/test/mjsunit/array-push10.js vendored Normal file
View File

@ -0,0 +1,15 @@
// Copyright 2014 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
function __f_17(__v_9) {
var __v_10 = 0;
var count = 10000;
while (count-- != 0) {
__v_9.push(0);
if (++__v_10 >= 2) return __v_9;
__v_10 = {};
}
}
__v_14 = __f_17([]);

18
deps/v8/test/mjsunit/array-push11.js vendored Normal file
View File

@ -0,0 +1,18 @@
// Copyright 2014 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
function __f_17(__v_9) {
var __v_10 = 0;
var count = 100000;
while (count-- != 0) {
var l = __v_9.push(0);
if (++__v_10 >= 2) return __v_9;
__v_10 = {};
}
return __v_9;
}
let a = __f_17([]);
assertEquals(a[0], 0);
assertEquals(a[10000], 0);

24
deps/v8/test/mjsunit/array-push12.js vendored Normal file
View File

@ -0,0 +1,24 @@
// Copyright 2015 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Flags: --allow-natives-syntax
var a = [];
for (var i = -20; i < 0; ++i) {
a[i] = 0;
}
function g() {
[].push.apply(a, arguments);
}
function f() {
g();
}
%PrepareFunctionForOptimization(f);
g();
g();
%OptimizeFunctionOnNextCall(f);
f();

22
deps/v8/test/mjsunit/array-push13.js vendored Normal file
View File

@ -0,0 +1,22 @@
// Copyright 2016 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
function __f_17(__v_9) {
for (var count = 0; count < 20000; ++count) {
if (count < 100) {
__v_9.push(3);
} else if (count < 2500) {
__v_9.push(2.5);
} else {
__v_9.push(true);
}
}
return __v_9;
}
let a = __f_17([]);
assertEquals(a[0], 3);
assertEquals(a[10], 3);
assertEquals(a[2499], 2.5);
assertEquals(a[10000], true);

18
deps/v8/test/mjsunit/array-push14.js vendored Normal file
View File

@ -0,0 +1,18 @@
// Copyright 2016 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
function __f_17(__v_9) {
var __v_10 = 0;
var count = 100000;
while (count-- != 0) {
var l = __v_9.push(0.5);
if (++__v_10 >= 2) return __v_9;
__v_10 = {};
}
return __v_9;
}
let a = __f_17([2.2]);
assertEquals(a[0], 2.2);
assertEquals(a[10000], 0.5);

36
deps/v8/test/mjsunit/array-push15.js vendored Normal file
View File

@ -0,0 +1,36 @@
// Copyright 2023 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Flags: --allow-natives-syntax
// Test polymorphic Array.prototype.push with multiple maps per ElementsKind.
function push(arr) {
return arr.push(99);
}
let double_arr = [2.1, 13.37];
let holey_double_arr = [, 4.9];
let smi_arr1 = [12, 42];
let smi_arr2 = [47, 11];
double_arr.a = "";
holey_double_arr.b = "";
smi_arr1.c = "";
smi_arr2.d = "";
%PrepareFunctionForOptimization(push);
assertEquals(3, push(double_arr));
assertEquals(3, push(holey_double_arr));
assertEquals(3, push(smi_arr1));
assertEquals(3, push(smi_arr2));
%OptimizeFunctionOnNextCall(push);
assertEquals(4, push(double_arr));
assertEquals(4, push(holey_double_arr));
assertEquals(4, push(smi_arr1));
assertEquals(4, push(smi_arr2));
assertEquals([2.1, 13.37, 99, 99], double_arr);
assertEquals([, 4.9, 99, 99], holey_double_arr);
assertEquals([12, 42, 99, 99], smi_arr1);
assertEquals([47, 11, 99, 99], smi_arr2);

21
deps/v8/test/mjsunit/array-push2.js vendored Normal file
View File

@ -0,0 +1,21 @@
// Copyright 2014 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
var array = [];
var v = 0;
Object.defineProperty(Array.prototype, "0", {
get: function() { return "get " + v; },
set: function(value) { v += value; }
});
array[0] = 10;
assertEquals(0, array.length);
assertEquals(10, v);
assertEquals("get 10", array[0]);
array.push(100);
assertEquals(1, array.length);
assertEquals(110, v);
assertEquals("get 110", array[0]);

30
deps/v8/test/mjsunit/array-push3.js vendored Normal file
View File

@ -0,0 +1,30 @@
// Copyright 2014 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Flags: --allow-natives-syntax
var array = [];
function push(array, value) {
array.push(value);
};
%PrepareFunctionForOptimization(push);
push(array, 0);
push(array, 1);
push(array, 2);
%OptimizeFunctionOnNextCall(push);
push(array, 3);
var v = 0;
Object.defineProperty(Array.prototype, "4", {
get: function() { return 100; },
set: function(value) { v = value; }
});
push(array, 4);
assertEquals(5, array.length);
assertEquals(100, array[4]);
assertEquals(4, v);

61
deps/v8/test/mjsunit/array-push4.js vendored Normal file
View File

@ -0,0 +1,61 @@
// Copyright 2014 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Flags: --allow-natives-syntax
var v = 0;
var my_array_proto = {};
my_array_proto.__proto__ = [].__proto__;
Object.defineProperty(my_array_proto, "0", {
get: function() { return "get " + v; },
set: function(value) { v += value; }
});
// Test that element accessors are called in standard push cases.
array = [];
array.__proto__ = my_array_proto;
array[0] = 10;
assertEquals(0, array.length);
assertEquals(10, v);
assertEquals("get 10", array[0]);
Array.prototype.push.call(array, 100);
assertEquals(1, array.length);
assertEquals(110, v);
assertEquals("get 110", array[0]);
array = [];
array.__proto__ = my_array_proto;
assertEquals(0, array.length);
array.push(110);
assertEquals(1, array.length);
assertEquals(220, v);
assertEquals("get 220", array[0]);
// Test that elements setters/getters on prototype chain are property detected
// and don't lead to overzealous optimization.
v = 0;
function push_wrapper_1(array, value) {
array.push(value);
}
%PrepareFunctionForOptimization(push_wrapper_1);
array = [];
array.__proto__ = my_array_proto;
push_wrapper_1(array, 100);
assertEquals(1, array.length);
assertEquals(100, v);
push_wrapper_1(array, 100);
assertEquals(2, array.length);
assertEquals(100, v);
assertEquals("get 100", array[0]);
%OptimizeFunctionOnNextCall(push_wrapper_1);
array = [];
array.__proto__ = my_array_proto;
push_wrapper_1(array, 100);
assertEquals(1, array.length);
assertEquals(200, v);
assertEquals("get 200", array[0]);

43
deps/v8/test/mjsunit/array-push5.js vendored Normal file
View File

@ -0,0 +1,43 @@
// Copyright 2014 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Flags: --allow-natives-syntax --turbofan --no-always-turbofan
var v = 0;
// Test that elements setters/getters on prototype chain set after the fact are
// property detected and don't lead to overzealous optimization.
var my_array_proto = {};
my_array_proto.__proto__ = [].__proto__;
function push_wrapper_2(array, value) {
array.push(value);
}
%PrepareFunctionForOptimization(push_wrapper_2);
array = [];
array.__proto__ = my_array_proto;
push_wrapper_2(array, 66);
assertEquals(1, array.length);
assertEquals(0, v);
assertEquals(66, array[0]);
push_wrapper_2(array, 77);
assertEquals(2, array.length);
assertEquals(0, v);
assertEquals(77, array[1]);
%OptimizeFunctionOnNextCall(push_wrapper_2);
push_wrapper_2(array, 88);
assertEquals(3, array.length);
assertEquals(0, v);
assertEquals(88, array[2]);
assertOptimized(push_wrapper_2);
// Defining accessor should deopt optimized push.
Object.defineProperty(my_array_proto, "3", {
get: function() { return "get " + v; },
set: function(value) { v += value; }
});
assertUnoptimized(push_wrapper_2);
push_wrapper_2(array, 99);
assertEquals(4, array.length);
assertEquals(99, v);
assertEquals("get 99", array[3]);

24
deps/v8/test/mjsunit/array-push6.js vendored Normal file
View File

@ -0,0 +1,24 @@
// Copyright 2014 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Flags: --allow-natives-syntax
function push_wrapper(array, value) {
array.push(value);
}
%PrepareFunctionForOptimization(push_wrapper);
// Test that optimization of Array.push() for non-Arrays works correctly.
var object = { x : 8, length: 3 };
object[18] = 5;
object.__proto__ = Array.prototype;
push_wrapper(object, 1);
push_wrapper(object, 1);
assertEquals(5, object.length);
%OptimizeFunctionOnNextCall(push_wrapper);
push_wrapper(object, 1);
push_wrapper(object, 1);
assertEquals(8, object.x);
assertEquals(7, object.length);

40
deps/v8/test/mjsunit/array-push8.js vendored Normal file
View File

@ -0,0 +1,40 @@
// Copyright 2014 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Flags: --allow-natives-syntax
function push_wrapper(array, value) {
array.push(value);
}
%PrepareFunctionForOptimization(push_wrapper);
function pop_wrapper(array) {
return array.pop();
}
%PrepareFunctionForOptimization(pop_wrapper);
// Test the frzon arrays throw an exception if you try to push to them, both in
// optimized and non-optimized code.
var array = [2, 2];
Object.freeze(array);
try { push_wrapper(array, 1); } catch (e) {}
assertEquals(2, array.length);
try { push_wrapper(array, 1); } catch (e) {}
assertEquals(2, array.length);
%OptimizeFunctionOnNextCall(push_wrapper);
try { push_wrapper(array, 1); } catch (e) {}
assertEquals(2, array.length);
try { push_wrapper(array, 1); } catch (e) {}
assertEquals(2, array.length);
try { pop_wrapper(array); } catch (e) {}
assertEquals(2, array.length);
try { pop_wrapper(array); } catch (e) {}
assertEquals(2, array.length);
%OptimizeFunctionOnNextCall(pop_wrapper);
try { pop_wrapper(array); } catch (e) {}
assertEquals(2, array.length);
try { pop_wrapper(array); } catch (e) {}
assertEquals(2, array.length);

30
deps/v8/test/mjsunit/array-push9.js vendored Normal file
View File

@ -0,0 +1,30 @@
// Copyright 2014 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Flags: --allow-natives-syntax --deopt-every-n-times=5
var array = [];
function push(array, value) {
array.push(value);
}
%PrepareFunctionForOptimization(push);
push(array, 0);
push(array, 1);
push(array, 2);
%OptimizeFunctionOnNextCall(push);
push(array, 3);
var v = 0;
Object.defineProperty(Array.prototype, "4", {
get: function() { return 100; },
set: function(value) { v = value; }
});
push(array, 4);
assertEquals(5, array.length);
assertEquals(100, array[4]);
assertEquals(4, v);

1369
deps/v8/test/mjsunit/array-reduce.js vendored Normal file

File diff suppressed because it is too large Load Diff

72
deps/v8/test/mjsunit/array-reverse.js vendored Normal file
View File

@ -0,0 +1,72 @@
// Copyright 2018 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
assertArrayEquals([], [].reverse());
assertArrayEquals([8, 6, 4, 2], [2, 4, 6, 8].reverse());
assertArrayEquals([0.8, 0.6, 0.4], [0.4, 0.6, 0.8].reverse());
assertArrayEquals(["str4", "str3", "str2"], ["str2", "str3", "str4"].reverse());
assertArrayEquals([4,3,,1], [1,,3,4].reverse());
assertArrayEquals([4,,2,1], [1,2,,4].reverse());
assertArrayEquals([5,,3,,1], [1,,3,,5].reverse());
assertArrayEquals([0.5,,0.3,,0.1], [0.1,,0.3,,0.5].reverse());
assertArrayEquals(["5",,"3",,"1"], ["1",,"3",,"5"].reverse());
function TestReverseWithObject() {
let obj = { length: 5 };
obj[0] = "foo";
obj[3] = "bar";
Array.prototype.reverse.call(obj);
assertArrayEquals([,"bar",,,"foo"], obj);
}
TestReverseWithObject();
function TestReverseWithPrototypeChain() {
let proto = { 0: "foo", 19: "bar" };
let obj = { length: 20, 5: "foobar", __proto__: proto };
Array.prototype.reverse.call(obj);
assertEquals("bar", obj[0]);
assertEquals("foobar", obj[14]);
assertEquals("foo", obj[19]);
}
TestReverseWithPrototypeChain();
function TestReverseWithTypedArrays() {
const constructors = [
Uint8Array,
Int8Array,
Uint16Array,
Int16Array,
Uint32Array,
Int32Array,
Uint8ClampedArray,
Float32Array,
Float64Array
];
for (const constructor of constructors) {
const array_odd = new constructor([1, 2, 3]);
Array.prototype.reverse.call(array_odd);
assertArrayEquals([3, 2, 1], array_odd, constructor);
const array_even = new constructor([1, 2, 3, 4]);
Array.prototype.reverse.call(array_even);
assertArrayEquals([4, 3, 2, 1], array_even, constructor);
// Array.prototype.reverse respects shadowing length on TypedArrays.
const array = new constructor([1, 2, 3, 4]);
Object.defineProperty(array, 'length', {value: 2});
Array.prototype.reverse.call(array);
assertArrayEquals([2, 1], array, constructor);
const array_shadowed_length = new constructor([1, 2]);
Object.defineProperty(array_shadowed_length, 'length', {value: 5});
assertThrows(() => Array.prototype.reverse.call(array_shadowed_length));
}
}
TestReverseWithTypedArrays();

122
deps/v8/test/mjsunit/array-shift.js vendored Normal file
View File

@ -0,0 +1,122 @@
// Copyright 2010 the V8 project authors. All rights reserved.
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following
// disclaimer in the documentation and/or other materials provided
// with the distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// Check that shifting array of holes keeps it as array of holes
(function() {
var array = new Array(10);
array.shift();
assertFalse(0 in array);
})();
// Now check the case with array of holes and some elements on prototype.
(function() {
var len = 9;
var array = new Array(len);
Array.prototype[3] = "@3";
Array.prototype[7] = "@7";
assertEquals(len, array.length);
for (var i = 0; i < array.length; i++) {
assertEquals(array[i], Array.prototype[i]);
}
array.shift();
assertEquals(len - 1, array.length);
// Note that shift copies values from prototype into the array.
assertEquals(array[2], Array.prototype[3]);
assertTrue(array.hasOwnProperty(2));
assertEquals(array[6], Array.prototype[7]);
assertTrue(array.hasOwnProperty(6));
// ... but keeps the rest as holes:
Array.prototype[5] = "@5";
assertEquals(array[5], Array.prototype[5]);
assertFalse(array.hasOwnProperty(5));
assertEquals(array[3], Array.prototype[3]);
assertFalse(array.hasOwnProperty(3));
assertEquals(array[7], Array.prototype[7]);
assertFalse(array.hasOwnProperty(7));
assertTrue(delete Array.prototype[3]);
assertTrue(delete Array.prototype[5]);
assertTrue(delete Array.prototype[7]);
})();
// Now check the case with array of holes and some elements on prototype
// which is an array itself.
(function() {
var len = 9;
var array = new Array(len);
var array_proto = new Array();
array_proto[3] = "@3";
array_proto[7] = "@7";
array.__proto__ = array_proto;
assertEquals(len, array.length);
for (var i = 0; i < array.length; i++) {
assertEquals(array[i], array_proto[i]);
}
array.shift();
assertEquals(len - 1, array.length);
// Note that shift copies values from prototype into the array.
assertEquals(array[2], array_proto[3]);
assertTrue(array.hasOwnProperty(2));
assertEquals(array[6], array_proto[7]);
assertTrue(array.hasOwnProperty(6));
// ... but keeps the rest as holes:
array_proto[5] = "@5";
assertEquals(array[5], array_proto[5]);
assertFalse(array.hasOwnProperty(5));
assertEquals(array[3], array_proto[3]);
assertFalse(array.hasOwnProperty(3));
assertEquals(array[7], array_proto[7]);
assertFalse(array.hasOwnProperty(7));
})();
// Check that non-enumerable elements are treated appropriately
(function() {
var array = [1, 2, 3];
Object.defineProperty(array, '1', {enumerable: false});
assertEquals(1, array.shift());
assertEquals([2, 3], array);
array = [1,,3];
array.__proto__[1] = 2;
Object.defineProperty(array.__proto__, '1', {enumerable: false});
assertEquals(1, array.shift());
assertEquals([2, 3], array);
})();

29
deps/v8/test/mjsunit/array-shift2.js vendored Normal file
View File

@ -0,0 +1,29 @@
// Copyright 2014 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Flags: --allow-natives-syntax
Object.defineProperty(Array.prototype, "1", {
get: function() { return "element 1"; },
set: function(value) { }
});
function test(array) {
array.shift();
return array;
}
%PrepareFunctionForOptimization(test);
var result = test(["0",,2]);
assertEquals(["element 1","element 1"], result);
assertTrue(result.hasOwnProperty("0"));
assertFalse(result.hasOwnProperty("1"));
result = test([{},,{}]);
assertEquals(["element 1","element 1"], result);
assertTrue(result.hasOwnProperty("0"));
assertFalse(result.hasOwnProperty("1"));
%OptimizeFunctionOnNextCall(test);
result = test([{},,0]);
assertEquals(["element 1","element 1"], result);
assertTrue(result.hasOwnProperty("0"));
assertFalse(result.hasOwnProperty("1"));

16
deps/v8/test/mjsunit/array-shift3.js vendored Normal file
View File

@ -0,0 +1,16 @@
// Copyright 2014 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Flags: --allow-natives-syntax
Array.prototype[1] = "element 1";
function test(a) {
a.shift();
return a;
};
%PrepareFunctionForOptimization(test);
assertEquals(['element 1', {}], test([0, , {}]));
assertEquals(['element 1', 10], test([9, , 10]));
%OptimizeFunctionOnNextCall(test);
assertEquals(['element 1', 10], test([9, , 10]));

25
deps/v8/test/mjsunit/array-shift4.js vendored Normal file
View File

@ -0,0 +1,25 @@
// Copyright 2014 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Flags: --allow-natives-syntax --turbofan
// Inlining shift with holey smi arrays shouldn't deopt just because it
// encounters the hole on the copy step.
function doShift(a) {
var x = a.shift();
return x;
}
function makeArray() {
var a = [1, 2,, 3];
a[0] = 2;
return a;
}
%PrepareFunctionForOptimization(doShift);
doShift(makeArray());
doShift(makeArray());
%OptimizeFunctionOnNextCall(doShift);
doShift(makeArray());
assertOptimized(doShift);

73
deps/v8/test/mjsunit/array-shift5.js vendored Normal file
View File

@ -0,0 +1,73 @@
// Copyright 2017 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Flags: --allow-natives-syntax
(function() {
function doShift(a) {
return a.shift();
};
%PrepareFunctionForOptimization(doShift);
function test() {
var a = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16];
assertEquals(0, doShift(a));
assertEquals([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16], a);
}
test();
test();
%OptimizeFunctionOnNextCall(doShift);
test();
})();
(function() {
function doShift(a) {
return a.shift();
};
%PrepareFunctionForOptimization(doShift);
function test() {
var a = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16.1];
assertEquals(0, doShift(a));
assertEquals([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16.1], a);
}
test();
test();
%OptimizeFunctionOnNextCall(doShift);
test();
})();
(function() {
function doShift(a) {
return a.shift();
};
%PrepareFunctionForOptimization(doShift);
function test() {
var a = [, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16.1];
assertEquals(undefined, doShift(a));
assertEquals([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16.1], a);
}
test();
test();
%OptimizeFunctionOnNextCall(doShift);
test();
})();
(function() {
function doShift(a) {
return a.shift();
};
%PrepareFunctionForOptimization(doShift);
function test() {
var a = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, '16'];
assertEquals(0, doShift(a));
assertEquals([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, '16'], a);
}
test();
test();
%OptimizeFunctionOnNextCall(doShift);
test();
})();

Some files were not shown because too many files have changed in this diff Show More