blob: fce5f756c22f7cc1646164b41c285649362d8462 [file] [log] [blame]
/*
* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/licenses/publicdomain/
*/
var gTestfile = 'strict-arguments.js';
var BUGNUMBER = 516255;
var summary =
"ES5 strict mode: arguments objects of strict mode functions must copy " +
"argument values";
print(BUGNUMBER + ": " + summary);
/**************
* BEGIN TEST *
**************/
function arrayEvery(arr, fun)
{
return Array.prototype.every.call(arr, fun);
}
function arraysEqual(a1, a2)
{
return a1.length === a2.length &&
arrayEvery(a1, function(v, i) { return v === a2[i]; });
}
/************************
* NON-STRICT ARGUMENTS *
************************/
var obj = {};
function noargs() { return arguments; }
assertEq(arraysEqual(noargs(), []), true);
assertEq(arraysEqual(noargs(1), [1]), true);
assertEq(arraysEqual(noargs(2, obj, 8), [2, obj, 8]), true);
function args(a) { return arguments; }
assertEq(arraysEqual(args(), []), true);
assertEq(arraysEqual(args(1), [1]), true);
assertEq(arraysEqual(args(1, obj), [1, obj]), true);
assertEq(arraysEqual(args("foopy"), ["foopy"]), true);
function assign(a)
{
a = 17;
return arguments;
}
assertEq(arraysEqual(assign(1), [17]), true);
function getLaterAssign(a)
{
var o = arguments;
a = 17;
return o;
}
assertEq(arraysEqual(getLaterAssign(1), [17]), true);
function assignElementGetParameter(a)
{
arguments[0] = 17;
return a;
}
assertEq(assignElementGetParameter(42), 17);
function assignParameterGetElement(a)
{
a = 17;
return arguments[0];
}
assertEq(assignParameterGetElement(42), 17);
function assignArgSub(x, y)
{
arguments[0] = 3;
return arguments[0];
}
assertEq(assignArgSub(1), 3);
function assignArgSubParamUse(x, y)
{
arguments[0] = 3;
assertEq(x, 3);
return arguments[0];
}
assertEq(assignArgSubParamUse(1), 3);
function assignArgumentsElement(x, y)
{
arguments[0] = 3;
return arguments[Math.random() ? "0" : 0]; // nix arguments[const] optimizations
}
assertEq(assignArgumentsElement(1), 3);
function assignArgumentsElementParamUse(x, y)
{
arguments[0] = 3;
assertEq(x, 3);
return arguments[Math.random() ? "0" : 0]; // nix arguments[const] optimizations
}
assertEq(assignArgumentsElementParamUse(1), 3);
/********************
* STRICT ARGUMENTS *
********************/
function strictNoargs()
{
"use strict";
return arguments;
}
assertEq(arraysEqual(strictNoargs(), []), true);
assertEq(arraysEqual(strictNoargs(1), [1]), true);
assertEq(arraysEqual(strictNoargs(1, obj), [1, obj]), true);
function strictArgs(a)
{
"use strict";
return arguments;
}
assertEq(arraysEqual(strictArgs(), []), true);
assertEq(arraysEqual(strictArgs(1), [1]), true);
assertEq(arraysEqual(strictArgs(1, obj), [1, obj]), true);
function strictAssign(a)
{
"use strict";
a = 17;
return arguments;
}
assertEq(arraysEqual(strictAssign(), []), true);
assertEq(arraysEqual(strictAssign(1), [1]), true);
assertEq(arraysEqual(strictAssign(1, obj), [1, obj]), true);
var upper;
function strictAssignAfter(a)
{
"use strict";
upper = arguments;
a = 42;
return upper;
}
assertEq(arraysEqual(strictAssignAfter(), []), true);
assertEq(arraysEqual(strictAssignAfter(17), [17]), true);
assertEq(arraysEqual(strictAssignAfter(obj), [obj]), true);
function strictMaybeAssignOuterParam(p)
{
"use strict";
function inner() { p = 17; }
return arguments;
}
assertEq(arraysEqual(strictMaybeAssignOuterParam(), []), true);
assertEq(arraysEqual(strictMaybeAssignOuterParam(42), [42]), true);
assertEq(arraysEqual(strictMaybeAssignOuterParam(obj), [obj]), true);
function strictAssignOuterParam(p)
{
"use strict";
function inner() { p = 17; }
inner();
return arguments;
}
assertEq(arraysEqual(strictAssignOuterParam(), []), true);
assertEq(arraysEqual(strictAssignOuterParam(17), [17]), true);
assertEq(arraysEqual(strictAssignOuterParam(obj), [obj]), true);
function strictAssignOuterParamPSYCH(p)
{
"use strict";
function inner(p) { p = 17; }
inner();
return arguments;
}
assertEq(arraysEqual(strictAssignOuterParamPSYCH(), []), true);
assertEq(arraysEqual(strictAssignOuterParamPSYCH(17), [17]), true);
assertEq(arraysEqual(strictAssignOuterParamPSYCH(obj), [obj]), true);
function strictEval(code, p)
{
"use strict";
eval(code);
return arguments;
}
assertEq(arraysEqual(strictEval("1", 2), ["1", 2]), true);
assertEq(arraysEqual(strictEval("arguments"), ["arguments"]), true);
assertEq(arraysEqual(strictEval("p = 2"), ["p = 2"]), true);
assertEq(arraysEqual(strictEval("p = 2", 17), ["p = 2", 17]), true);
assertEq(arraysEqual(strictEval("arguments[0] = 17"), [17]), true);
assertEq(arraysEqual(strictEval("arguments[0] = 17", 42), [17, 42]), true);
function strictMaybeNestedEval(code, p)
{
"use strict";
function inner() { eval(code); }
return arguments;
}
assertEq(arraysEqual(strictMaybeNestedEval("1", 2), ["1", 2]), true);
assertEq(arraysEqual(strictMaybeNestedEval("arguments"), ["arguments"]), true);
assertEq(arraysEqual(strictMaybeNestedEval("p = 2"), ["p = 2"]), true);
assertEq(arraysEqual(strictMaybeNestedEval("p = 2", 17), ["p = 2", 17]), true);
function strictNestedEval(code, p)
{
"use strict";
function inner() { eval(code); }
inner();
return arguments;
}
assertEq(arraysEqual(strictNestedEval("1", 2), ["1", 2]), true);
assertEq(arraysEqual(strictNestedEval("arguments"), ["arguments"]), true);
assertEq(arraysEqual(strictNestedEval("p = 2"), ["p = 2"]), true);
assertEq(arraysEqual(strictNestedEval("p = 2", 17), ["p = 2", 17]), true);
assertEq(arraysEqual(strictNestedEval("arguments[0] = 17"), ["arguments[0] = 17"]), true);
assertEq(arraysEqual(strictNestedEval("arguments[0] = 17", 42), ["arguments[0] = 17", 42]), true);
function strictAssignArguments(a)
{
"use strict";
arguments[0] = 42;
return a;
}
assertEq(strictAssignArguments(), undefined);
assertEq(strictAssignArguments(obj), obj);
assertEq(strictAssignArguments(17), 17);
function strictAssignParameterGetElement(a)
{
"use strict";
a = 17;
return arguments[0];
}
assertEq(strictAssignParameterGetElement(42), 42);
function strictAssignArgSub(x, y)
{
"use strict";
arguments[0] = 3;
return arguments[0];
}
assertEq(strictAssignArgSub(1), 3);
function strictAssignArgSubParamUse(x, y)
{
"use strict";
arguments[0] = 3;
assertEq(x, 1);
return arguments[0];
}
assertEq(strictAssignArgSubParamUse(1), 3);
function strictAssignArgumentsElement(x, y)
{
"use strict";
arguments[0] = 3;
return arguments[Math.random() ? "0" : 0]; // nix arguments[const] optimizations
}
assertEq(strictAssignArgumentsElement(1), 3);
function strictAssignArgumentsElementParamUse(x, y)
{
"use strict";
arguments[0] = 3;
assertEq(x, 1);
return arguments[Math.random() ? "0" : 0]; // nix arguments[const] optimizations
}
assertEq(strictAssignArgumentsElementParamUse(1), 3);
function strictNestedAssignShadowVar(p)
{
"use strict";
function inner()
{
var p = 12;
function innermost() { p = 1776; return 12; }
return innermost();
}
return arguments;
}
assertEq(arraysEqual(strictNestedAssignShadowVar(), []), true);
assertEq(arraysEqual(strictNestedAssignShadowVar(99), [99]), true);
assertEq(arraysEqual(strictNestedAssignShadowVar(""), [""]), true);
assertEq(arraysEqual(strictNestedAssignShadowVar(obj), [obj]), true);
function strictNestedAssignShadowCatch(p)
{
"use strict";
function inner()
{
try
{
}
catch (p)
{
var f = function innermost() { p = 1776; return 12; };
f();
}
}
return arguments;
}
assertEq(arraysEqual(strictNestedAssignShadowCatch(), []), true);
assertEq(arraysEqual(strictNestedAssignShadowCatch(99), [99]), true);
assertEq(arraysEqual(strictNestedAssignShadowCatch(""), [""]), true);
assertEq(arraysEqual(strictNestedAssignShadowCatch(obj), [obj]), true);
function strictNestedAssignShadowCatchCall(p)
{
"use strict";
function inner()
{
try
{
}
catch (p)
{
var f = function innermost() { p = 1776; return 12; };
f();
}
}
inner();
return arguments;
}
assertEq(arraysEqual(strictNestedAssignShadowCatchCall(), []), true);
assertEq(arraysEqual(strictNestedAssignShadowCatchCall(99), [99]), true);
assertEq(arraysEqual(strictNestedAssignShadowCatchCall(""), [""]), true);
assertEq(arraysEqual(strictNestedAssignShadowCatchCall(obj), [obj]), true);
function strictNestedAssignShadowFunction(p)
{
"use strict";
function inner()
{
function p() { }
p = 1776;
}
return arguments;
}
assertEq(arraysEqual(strictNestedAssignShadowFunction(), []), true);
assertEq(arraysEqual(strictNestedAssignShadowFunction(99), [99]), true);
assertEq(arraysEqual(strictNestedAssignShadowFunction(""), [""]), true);
assertEq(arraysEqual(strictNestedAssignShadowFunction(obj), [obj]), true);
function strictNestedAssignShadowFunctionCall(p)
{
"use strict";
function inner()
{
function p() { }
p = 1776;
}
return arguments;
}
assertEq(arraysEqual(strictNestedAssignShadowFunctionCall(), []), true);
assertEq(arraysEqual(strictNestedAssignShadowFunctionCall(99), [99]), true);
assertEq(arraysEqual(strictNestedAssignShadowFunctionCall(""), [""]), true);
assertEq(arraysEqual(strictNestedAssignShadowFunctionCall(obj), [obj]), true);
function strictNestedShadowAndMaybeEval(code, p)
{
"use strict";
function inner(p) { eval(code); }
return arguments;
}
assertEq(arraysEqual(strictNestedShadowAndMaybeEval("1", 2), ["1", 2]), true);
assertEq(arraysEqual(strictNestedShadowAndMaybeEval("arguments"), ["arguments"]), true);
assertEq(arraysEqual(strictNestedShadowAndMaybeEval("p = 2"), ["p = 2"]), true);
assertEq(arraysEqual(strictNestedShadowAndMaybeEval("p = 2", 17), ["p = 2", 17]), true);
assertEq(arraysEqual(strictNestedShadowAndMaybeEval("arguments[0] = 17"), ["arguments[0] = 17"]), true);
assertEq(arraysEqual(strictNestedShadowAndMaybeEval("arguments[0] = 17", 42), ["arguments[0] = 17", 42]), true);
function strictNestedShadowAndEval(code, p)
{
"use strict";
function inner(p) { eval(code); }
return arguments;
}
assertEq(arraysEqual(strictNestedShadowAndEval("1", 2), ["1", 2]), true);
assertEq(arraysEqual(strictNestedShadowAndEval("arguments"), ["arguments"]), true);
assertEq(arraysEqual(strictNestedShadowAndEval("p = 2"), ["p = 2"]), true);
assertEq(arraysEqual(strictNestedShadowAndEval("p = 2", 17), ["p = 2", 17]), true);
assertEq(arraysEqual(strictNestedShadowAndEval("arguments[0] = 17"), ["arguments[0] = 17"]), true);
assertEq(arraysEqual(strictNestedShadowAndEval("arguments[0] = 17", 42), ["arguments[0] = 17", 42]), true);
function strictEvalContainsMutation(code)
{
"use strict";
return eval(code);
}
assertEq(arraysEqual(strictEvalContainsMutation("code = 17; arguments"), ["code = 17; arguments"]), true);
assertEq(arraysEqual(strictEvalContainsMutation("arguments[0] = 17; arguments"), [17]), true);
assertEq(strictEvalContainsMutation("arguments[0] = 17; code"), "arguments[0] = 17; code");
function strictNestedAssignShadowFunctionName(p)
{
"use strict";
function inner()
{
function p() { p = 1776; }
p();
}
inner();
return arguments;
}
assertEq(arraysEqual(strictNestedAssignShadowFunctionName(), []), true);
assertEq(arraysEqual(strictNestedAssignShadowFunctionName(99), [99]), true);
assertEq(arraysEqual(strictNestedAssignShadowFunctionName(""), [""]), true);
assertEq(arraysEqual(strictNestedAssignShadowFunctionName(obj), [obj]), true);
/******************************************************************************/
if (typeof reportCompare === "function")
reportCompare(true, true);
print("All tests passed!");