blob: 0e23faaf15151e24ca95bbcddd6b781d16b63f7d [file] [log] [blame]
// Copyright 2013 the V8 project authors. All rights reserved.
// Copyright (C) 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
// 1. Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// 2. 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.
//
// THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS 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 APPLE INC. OR ITS 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.
description(
"This test thoroughly checks the behaviour of the 'arguments' object."
);
function access_1(a, b, c)
{
return arguments[0];
}
function access_2(a, b, c)
{
return arguments[1];
}
function access_3(a, b, c)
{
return arguments[2];
}
function access_4(a, b, c)
{
return arguments[3];
}
function access_5(a, b, c)
{
return arguments[4];
}
function argumentLengthIs5() {
arguments.length = 5;
return arguments.length;
}
function duplicateArgumentAndReturnLast_call(a) {
Array.prototype.push.call(arguments, a);
return arguments[1];
}
function duplicateArgumentAndReturnFirst_call(a) {
Array.prototype.push.call(arguments, a);
return arguments[0];
}
function duplicateArgumentAndReturnLast_apply(a) {
Array.prototype.push.apply(arguments, arguments);
return arguments[1];
}
function duplicateArgumentAndReturnFirst_apply(a) {
Array.prototype.push.apply(arguments, arguments);
return arguments[0];
}
shouldBe("access_1(1, 2, 3)", "1");
shouldBe("access_2(1, 2, 3)", "2");
shouldBe("access_3(1, 2, 3)", "3");
shouldBe("access_4(1, 2, 3)", "undefined");
shouldBe("access_5(1, 2, 3)", "undefined");
shouldBe("access_1(1)", "1");
shouldBe("access_2(1)", "undefined");
shouldBe("access_3(1)", "undefined");
shouldBe("access_4(1)", "undefined");
shouldBe("access_5(1)", "undefined");
shouldBe("access_1(1, 2, 3, 4, 5)", "1");
shouldBe("access_2(1, 2, 3, 4, 5)", "2");
shouldBe("access_3(1, 2, 3, 4, 5)", "3");
shouldBe("access_4(1, 2, 3, 4, 5)", "4");
shouldBe("access_5(1, 2, 3, 4, 5)", "5");
shouldBe("argumentLengthIs5()", "5");
shouldBe("argumentLengthIs5(1,2,3,4,5)", "5");
shouldBe("argumentLengthIs5(1,2,3,4,5,6,7,8,9,10)", "5");
shouldBe("duplicateArgumentAndReturnLast_call(1)", "1");
shouldBe("duplicateArgumentAndReturnFirst_call(1)", "1");
shouldBe("duplicateArgumentAndReturnLast_apply(1)", "1");
shouldBe("duplicateArgumentAndReturnFirst_apply(1)", "1");
function f(a, b, c)
{
return arguments;
}
function tear_off_equal_access_1(a, b, c)
{
return f(a, b, c)[0];
}
function tear_off_equal_access_2(a, b, c)
{
return f(a, b, c)[1];
}
function tear_off_equal_access_3(a, b, c)
{
return f(a, b, c)[2];
}
function tear_off_equal_access_4(a, b, c)
{
return f(a, b, c)[3];
}
function tear_off_equal_access_5(a, b, c)
{
return f(a, b, c)[4];
}
shouldBe("tear_off_equal_access_1(1, 2, 3)", "1");
shouldBe("tear_off_equal_access_2(1, 2, 3)", "2");
shouldBe("tear_off_equal_access_3(1, 2, 3)", "3");
shouldBe("tear_off_equal_access_4(1, 2, 3)", "undefined");
shouldBe("tear_off_equal_access_5(1, 2, 3)", "undefined");
function tear_off_too_few_access_1(a)
{
return f(a)[0];
}
function tear_off_too_few_access_2(a)
{
return f(a)[1];
}
function tear_off_too_few_access_3(a)
{
return f(a)[2];
}
function tear_off_too_few_access_4(a)
{
return f(a)[3];
}
function tear_off_too_few_access_5(a)
{
return f(a)[4];
}
shouldBe("tear_off_too_few_access_1(1)", "1");
shouldBe("tear_off_too_few_access_2(1)", "undefined");
shouldBe("tear_off_too_few_access_3(1)", "undefined");
shouldBe("tear_off_too_few_access_4(1)", "undefined");
shouldBe("tear_off_too_few_access_5(1)", "undefined");
function tear_off_too_many_access_1(a, b, c, d, e)
{
return f(a, b, c, d, e)[0];
}
function tear_off_too_many_access_2(a, b, c, d, e)
{
return f(a, b, c, d, e)[1];
}
function tear_off_too_many_access_3(a, b, c, d, e)
{
return f(a, b, c, d, e)[2];
}
function tear_off_too_many_access_4(a, b, c, d, e)
{
return f(a, b, c, d, e)[3];
}
function tear_off_too_many_access_5(a, b, c, d, e)
{
return f(a, b, c, d, e)[4];
}
shouldBe("tear_off_too_many_access_1(1, 2, 3, 4, 5)", "1");
shouldBe("tear_off_too_many_access_2(1, 2, 3, 4, 5)", "2");
shouldBe("tear_off_too_many_access_3(1, 2, 3, 4, 5)", "3");
shouldBe("tear_off_too_many_access_4(1, 2, 3, 4, 5)", "4");
shouldBe("tear_off_too_many_access_5(1, 2, 3, 4, 5)", "5");
function live_1(a, b, c)
{
arguments[0] = 1;
return a;
}
function live_2(a, b, c)
{
arguments[1] = 2;
return b;
}
function live_3(a, b, c)
{
arguments[2] = 3;
return c;
}
shouldBe("live_1(0, 2, 3)", "1");
shouldBe("live_2(1, 0, 3)", "2");
shouldBe("live_3(1, 2, 0)", "3");
// Arguments that were not provided are not live
shouldBe("live_1(0)", "1");
shouldBe("live_2(1)", "undefined");
shouldBe("live_3(1)", "undefined");
shouldBe("live_1(0, 2, 3, 4, 5)", "1");
shouldBe("live_2(1, 0, 3, 4, 5)", "2");
shouldBe("live_3(1, 2, 0, 4, 5)", "3");
function extra_args_modify_4(a, b, c)
{
arguments[3] = 4;
return arguments[3];
}
function extra_args_modify_5(a, b, c)
{
arguments[4] = 5;
return arguments[4];
}
shouldBe("extra_args_modify_4(1, 2, 3, 0, 5)", "4");
shouldBe("extra_args_modify_5(1, 2, 3, 4, 0)", "5");
function tear_off_live_1(a, b, c)
{
var args = arguments;
return function()
{
args[0] = 1;
return a;
};
}
function tear_off_live_2(a, b, c)
{
var args = arguments;
return function()
{
args[1] = 2;
return b;
};
}
function tear_off_live_3(a, b, c)
{
var args = arguments;
return function()
{
args[2] = 3;
return c;
};
}
shouldBe("tear_off_live_1(0, 2, 3)()", "1");
shouldBe("tear_off_live_2(1, 0, 3)()", "2");
shouldBe("tear_off_live_3(1, 2, 0)()", "3");
// Arguments that were not provided are not live
shouldBe("tear_off_live_1(0)()", "1");
shouldBe("tear_off_live_2(1)()", "undefined");
shouldBe("tear_off_live_3(1)()", "undefined");
shouldBe("tear_off_live_1(0, 2, 3, 4, 5)()", "1");
shouldBe("tear_off_live_2(1, 0, 3, 4, 5)()", "2");
shouldBe("tear_off_live_3(1, 2, 0, 4, 5)()", "3");
function tear_off_extra_args_modify_4(a, b, c)
{
return function()
{
arguments[3] = 4;
return arguments[3];
}
}
function tear_off_extra_args_modify_5(a, b, c)
{
return function()
{
arguments[4] = 5;
return arguments[4];
}
}
shouldBe("tear_off_extra_args_modify_4(1, 2, 3, 0, 5)()", "4");
shouldBe("tear_off_extra_args_modify_5(1, 2, 3, 4, 0)()", "5");
function delete_1(a, b, c)
{
delete arguments[0];
return arguments[0];
}
function delete_2(a, b, c)
{
delete arguments[1];
return arguments[1];
}
function delete_3(a, b, c)
{
delete arguments[2];
return arguments[2];
}
function delete_4(a, b, c)
{
delete arguments[3];
return arguments[3];
}
function delete_5(a, b, c)
{
delete arguments[4];
return arguments[4];
}
shouldBe("delete_1(1, 2, 3)", "undefined");
shouldBe("delete_2(1, 2, 3)", "undefined");
shouldBe("delete_3(1, 2, 3)", "undefined");
shouldBe("delete_4(1, 2, 3)", "undefined");
shouldBe("delete_5(1, 2, 3)", "undefined");
shouldBe("delete_1(1)", "undefined");
shouldBe("delete_2(1)", "undefined");
shouldBe("delete_3(1)", "undefined");
shouldBe("delete_4(1)", "undefined");
shouldBe("delete_5(1)", "undefined");
shouldBe("delete_1(1, 2, 3, 4, 5)", "undefined");
shouldBe("delete_2(1, 2, 3, 4, 5)", "undefined");
shouldBe("delete_3(1, 2, 3, 4, 5)", "undefined");
shouldBe("delete_4(1, 2, 3, 4, 5)", "undefined");
shouldBe("delete_5(1, 2, 3, 4, 5)", "undefined");
function tear_off_delete_1(a, b, c)
{
return function()
{
delete arguments[0];
return arguments[0];
};
}
function tear_off_delete_2(a, b, c)
{
return function()
{
delete arguments[1];
return arguments[1];
};
}
function tear_off_delete_3(a, b, c)
{
return function()
{
delete arguments[2];
return arguments[2];
};
}
function tear_off_delete_4(a, b, c)
{
return function()
{
delete arguments[3];
return arguments[3];
};
}
function tear_off_delete_5(a, b, c)
{
return function()
{
delete arguments[4];
return arguments[4];
};
}
shouldBe("tear_off_delete_1(1, 2, 3)()", "undefined");
shouldBe("tear_off_delete_2(1, 2, 3)()", "undefined");
shouldBe("tear_off_delete_3(1, 2, 3)()", "undefined");
shouldBe("tear_off_delete_4(1, 2, 3)()", "undefined");
shouldBe("tear_off_delete_5(1, 2, 3)()", "undefined");
shouldBe("tear_off_delete_1(1)()", "undefined");
shouldBe("tear_off_delete_2(1)()", "undefined");
shouldBe("tear_off_delete_3(1)()", "undefined");
shouldBe("tear_off_delete_4(1)()", "undefined");
shouldBe("tear_off_delete_5(1)()", "undefined");
shouldBe("tear_off_delete_1(1, 2, 3, 4, 5)()", "undefined");
shouldBe("tear_off_delete_2(1, 2, 3, 4, 5)()", "undefined");
shouldBe("tear_off_delete_3(1, 2, 3, 4, 5)()", "undefined");
shouldBe("tear_off_delete_4(1, 2, 3, 4, 5)()", "undefined");
shouldBe("tear_off_delete_5(1, 2, 3, 4, 5)()", "undefined");
function delete_not_live_1(a, b, c)
{
delete arguments[0];
return a;
}
function delete_not_live_2(a, b, c)
{
delete arguments[1];
return b;
}
function delete_not_live_3(a, b, c)
{
delete arguments[2];
return c;
}
shouldBe("delete_not_live_1(1, 2, 3)", "1");
shouldBe("delete_not_live_2(1, 2, 3)", "2");
shouldBe("delete_not_live_3(1, 2, 3)", "3");
shouldBe("delete_not_live_1(1)", "1");
shouldBe("delete_not_live_2(1)", "undefined");
shouldBe("delete_not_live_3(1)", "undefined");
shouldBe("delete_not_live_1(1, 2, 3, 4, 5)", "1");
shouldBe("delete_not_live_2(1, 2, 3, 4, 5)", "2");
shouldBe("delete_not_live_3(1, 2, 3, 4, 5)", "3");
function tear_off_delete_not_live_1(a, b, c)
{
return function()
{
delete arguments[0];
return a;
};
}
function tear_off_delete_not_live_2(a, b, c)
{
return function ()
{
delete arguments[1];
return b;
};
}
function tear_off_delete_not_live_3(a, b, c)
{
return function()
{
delete arguments[2];
return c;
};
}
shouldBe("tear_off_delete_not_live_1(1, 2, 3)()", "1");
shouldBe("tear_off_delete_not_live_2(1, 2, 3)()", "2");
shouldBe("tear_off_delete_not_live_3(1, 2, 3)()", "3");
shouldBe("tear_off_delete_not_live_1(1)()", "1");
shouldBe("tear_off_delete_not_live_2(1)()", "undefined");
shouldBe("tear_off_delete_not_live_3(1)()", "undefined");
shouldBe("tear_off_delete_not_live_1(1, 2, 3, 4, 5)()", "1");
shouldBe("tear_off_delete_not_live_2(1, 2, 3, 4, 5)()", "2");
shouldBe("tear_off_delete_not_live_3(1, 2, 3, 4, 5)()", "3");
function access_after_delete_named_2(a, b, c)
{
delete arguments[0];
return b;
}
function access_after_delete_named_3(a, b, c)
{
delete arguments[0];
return c;
}
function access_after_delete_named_4(a, b, c)
{
delete arguments[0];
return arguments[3];
}
shouldBe("access_after_delete_named_2(1, 2, 3)", "2");
shouldBe("access_after_delete_named_3(1, 2, 3)", "3");
shouldBe("access_after_delete_named_4(1, 2, 3)", "undefined");
shouldBe("access_after_delete_named_2(1)", "undefined");
shouldBe("access_after_delete_named_3(1)", "undefined");
shouldBe("access_after_delete_named_4(1)", "undefined");
shouldBe("access_after_delete_named_2(1, 2, 3, 4)", "2");
shouldBe("access_after_delete_named_3(1, 2, 3, 4)", "3");
shouldBe("access_after_delete_named_4(1, 2, 3, 4)", "4");
function access_after_delete_extra_1(a, b, c)
{
delete arguments[3];
return a;
}
function access_after_delete_extra_2(a, b, c)
{
delete arguments[3];
return b;
}
function access_after_delete_extra_3(a, b, c)
{
delete arguments[3];
return c;
}
function access_after_delete_extra_5(a, b, c)
{
delete arguments[3];
return arguments[4];
}
shouldBe("access_after_delete_extra_1(1, 2, 3)", "1");
shouldBe("access_after_delete_extra_2(1, 2, 3)", "2");
shouldBe("access_after_delete_extra_3(1, 2, 3)", "3");
shouldBe("access_after_delete_extra_5(1, 2, 3)", "undefined");
shouldBe("access_after_delete_extra_1(1)", "1");
shouldBe("access_after_delete_extra_2(1)", "undefined");
shouldBe("access_after_delete_extra_3(1)", "undefined");
shouldBe("access_after_delete_extra_5(1)", "undefined");
shouldBe("access_after_delete_extra_1(1, 2, 3, 4, 5)", "1");
shouldBe("access_after_delete_extra_2(1, 2, 3, 4, 5)", "2");
shouldBe("access_after_delete_extra_3(1, 2, 3, 4, 5)", "3");
shouldBe("access_after_delete_extra_5(1, 2, 3, 4, 5)", "5");
function argumentsParam(arguments)
{
return arguments;
}
shouldBeTrue("argumentsParam(true)");
var argumentsFunctionConstructorParam = new Function("arguments", "return arguments;");
shouldBeTrue("argumentsFunctionConstructorParam(true)");
function argumentsVarUndefined()
{
var arguments;
return String(arguments);
}
shouldBe("argumentsVarUndefined()", "'[object Arguments]'");
function argumentCalleeInException() {
try {
throw "";
} catch (e) {
return arguments.callee;
}
}
shouldBe("argumentCalleeInException()", "argumentCalleeInException")
function shadowedArgumentsApply(arguments) {
return function(a){ return a; }.apply(null, arguments);
}
function shadowedArgumentsLength(arguments) {
return arguments.length;
}
function shadowedArgumentsCallee(arguments) {
return arguments.callee;
}
function shadowedArgumentsIndex(arguments) {
return arguments[0]
}
shouldBeTrue("shadowedArgumentsApply([true])");
shouldBe("shadowedArgumentsLength([])", '0');
shouldThrow("shadowedArgumentsLength()");
shouldBeUndefined("shadowedArgumentsCallee([])");
shouldBeTrue("shadowedArgumentsIndex([true])");
descriptor = (function(){ return Object.getOwnPropertyDescriptor(arguments, 1); })("zero","one","two");
shouldBe("descriptor.value", '"one"');
shouldBe("descriptor.writable", 'true');
shouldBe("descriptor.enumerable", 'true');
shouldBe("descriptor.configurable", 'true');
// Test cases for [[DefineOwnProperty]] applied to the arguments object.
(function(a0,a1,a2,a3){
Object.defineProperties(arguments, {
1: { get: function(){ return 201; } },
2: { value: 202, writable: false },
3: { writable: false },
});
// Test a0 is a live mapped argument.
shouldBeTrue(String( a0 === 100 ));
shouldBeTrue(String( arguments[0] === 100 ));
a0 = 300;
shouldBeTrue(String( a0 === 300 ));
shouldBeTrue(String( arguments[0] === 300 ));
arguments[0] = 400;
shouldBeTrue(String( a0 === 400 ));
shouldBeTrue(String( arguments[0] === 400 ));
// When a1 is redefined as an accessor, it is no longer live.
shouldBeTrue(String( a1 === 101 ));
shouldBeTrue(String( arguments[1] === 201 ));
a1 = 301;
shouldBeTrue(String( a1 === 301 ));
shouldBeTrue(String( arguments[1] === 201 ));
arguments[1] = 401;
shouldBeTrue(String( a1 === 301 ));
shouldBeTrue(String( arguments[1] === 201 ));
// When a2 is made read-only the value is set, but it is no longer live.
// (per 10.6 [[DefineOwnProperty]] 5.b.ii.1)
shouldBeTrue(String( a2 === 202 ));
shouldBeTrue(String( arguments[2] === 202 ));
a2 = 302;
shouldBeTrue(String( a2 === 302 ));
shouldBeTrue(String( arguments[2] === 202 ));
arguments[2] = 402;
shouldBeTrue(String( a2 === 302 ));
shouldBeTrue(String( arguments[2] === 202 ));
// When a3 is made read-only, it is no longer live.
// (per 10.6 [[DefineOwnProperty]] 5.b.ii.1)
shouldBeTrue(String( a3 === 103 ));
shouldBeTrue(String( arguments[3] === 103 ));
a3 = 303;
shouldBeTrue(String( a3 === 303 ));
shouldBeTrue(String( arguments[3] === 103 ));
arguments[3] = 403;
shouldBeTrue(String( a3 === 303 ));
shouldBeTrue(String( arguments[3] === 103 ));
})(100,101,102,103);
// Test cases for [[DefineOwnProperty]] applied to the arguments object.
(function(arg){
shouldBeTrue(String( Object.getOwnPropertyDescriptor(arguments, 0).writable ));
shouldBeTrue(String( Object.getOwnPropertyDescriptor(arguments, 0).enumerable ));
Object.defineProperty(arguments, 0, { writable: false });
shouldBeFalse(String( Object.getOwnPropertyDescriptor(arguments, 0).writable ));
shouldBeTrue(String( Object.getOwnPropertyDescriptor(arguments, 0).enumerable ));
Object.defineProperty(arguments, 0, { enumerable: false });
shouldBeFalse(String( Object.getOwnPropertyDescriptor(arguments, 0).writable ));
shouldBeFalse(String( Object.getOwnPropertyDescriptor(arguments, 0).enumerable ));
delete arguments[1];
shouldBeUndefined(String( Object.getOwnPropertyDescriptor(arguments, 1) ));
Object.defineProperty(arguments, 1, { writable: true });
shouldBeTrue(String( Object.getOwnPropertyDescriptor(arguments, 1).writable ));
shouldBeFalse(String( Object.getOwnPropertyDescriptor(arguments, 1).enumerable ));
})(0,1);