Source code
Revision control
Copy as Markdown
Other Tools
function script1() { return arguments.length; }
function script2(x) { return x; }
function script3(x) { var o = arguments; return o[0]; }
function genClosure() { var x = 3; eval("x = 4"); return function(y) { return x + y } };
var closed1 = genClosure();
var closed2 = genClosure();
var closed3 = genClosure();
var native1 = String.prototype.search;
var native2 = String.prototype.match;
var tricky1 = { call:function(x,y) { return y }, apply:function(x,y) { return y } };
test0();
test1();
test2();
test3();
function test0() {
assertEq(script1.call(null), 0);
assertEq(script1.call(null, 1), 1);
assertEq(script1.call(null, 1,2), 2);
assertEq(native1.call("aabc", /b/), 2);
assertEq(native1.call("abc"), 0);
assertEq(tricky1.call(null, 9), 9);
assertEq(script1.apply(null), 0);
assertEq(script1.apply(null, [1]), 1);
assertEq(script1.apply(null, [1,2]), 2);
assertEq(native1.apply("aabc", [/b/]), 2);
assertEq(native1.apply("abc"), 0);
assertEq(tricky1.apply(null, 1), 1);
}
test0();
function test1() {
function f(arr) {
for (var i = 0; i < 10; ++i) {
for (var j = 0; j < arr.length; ++j) {
arr[j].call('a');
arr[j].apply('a', []);
var arg0 = [];
arr[j].apply('a', arg0);
(function() { arr[j].apply('a', arguments); })();
arr[j].call('a', 1);
arr[j].apply('a', [1]);
var arg0 = [1];
arr[j].apply('a', arg0);
(function() { arr[j].apply('a', arguments); })(1);
arr[j].call('a', 1,'g');
arr[j].apply('a', [1,'g']);
var arg0 = [1,'g'];
arr[j].apply('a', arg0);
(function() { arr[j].apply('a', arguments); })(1,'g');
arr[j].call('a', 1,'g',3,4,5,6,7,8,9);
arr[j].apply('a', [1,'g',3,4,5,6,7,8,9]);
var arg0 = [1,'g',3,4,5,6,7,8,9];
arr[j].apply('a', arg0);
(function() { arr[j].apply('a', arguments); })(1,'g',3,4,5,6,7,8,9);
}
}
}
f([script1, script1, script1, script1, script2, script2, script1, script2]);
f([script1, script2, script3, script1, script2, script3, script3, script3]);
f([script1, script2, script2, script2, script2, script3, script1, script2]);
f([script1, script1, script1, native1, native1, native1, native1, script1]);
f([native1, native1, native1, native2, native2, native2, native2, native1]);
f([native1, native2, native1, native2, native1, native2, native1, native2]);
f([native1, native1, native1, script1, script2, script2, native1, script3]);
f([closed1, closed1, closed1, closed2, closed2, closed2, script3, script3]);
f([closed1, closed2, closed1, closed2, closed1, closed2, closed1, closed2]);
f([closed1, closed2, closed3, closed1, closed2, closed3, script1, script2]);
f([closed1, closed1, closed1, closed2, closed2, closed2, native1, native2]);
f([closed1, closed1, closed1, closed2, closed2, closed2, native1, native2]);
f([native1, native1, native1, closed1, closed2, script1, script2, native2]);
}
// test things that break our speculation
function test2() {
var threw = false;
try {
(3).call(null, 1,2);
} catch (e) {
threw = true;
}
assertEq(threw, true);
var threw = false;
try {
(3).apply(null, [1,2]);
} catch (e) {
threw = true;
}
assertEq(threw, true);
var threw = false;
try {
var arr = [1,2];
(3).apply(null, arr);
} catch (e) {
threw = true;
}
assertEq(threw, true);
function tryAndFail(o) {
var threw = false;
try {
o.call(null, 1,2);
} catch(e) {
threw = true;
}
assertEq(threw, true);
threw = false;
try {
o.apply(null, [1,2]);
} catch(e) {
threw = true;
}
assertEq(threw, true);
}
tryAndFail(1);
tryAndFail({});
tryAndFail({call:{}, apply:{}});
tryAndFail({call:function() { throw "not js_fun_call"}, apply:function(){ throw "not js_fun_apply" }});
}
// hit the stubs::CompileFunction path
function test3() {
function genFreshFunction(s) { return new Function(s, "return " + s); }
function callIt(f) {
assertEq(f.call(null, 1,2), 1);
}
callIt(script2); callIt(script2); callIt(script2); callIt(script2);
callIt(genFreshFunction("x"));
callIt(genFreshFunction("y"));
callIt(genFreshFunction("z"));
function applyIt(f) {
var arr = [1,2];
assertEq(f.apply(null, arr), 1);
}
applyIt(script2); applyIt(script2); applyIt(script2); applyIt(script2);
applyIt(genFreshFunction("x"));
applyIt(genFreshFunction("y"));
applyIt(genFreshFunction("z"));
function applyIt1(f) {
function g() {
assertEq(f.apply(null, arguments), 1);
}
g(1,2);
}
applyIt1(script2); applyIt1(script2); applyIt1(script2); applyIt1(script2);
applyIt1(genFreshFunction("x"));
applyIt1(genFreshFunction("y"));
applyIt1(genFreshFunction("z"));
function applyIt2(f) {
assertEq(f.apply(null, [1,2]), 1);
}
applyIt2(script2); applyIt2(script2); applyIt2(script2); applyIt2(script2);
applyIt2(genFreshFunction("x"));
applyIt2(genFreshFunction("y"));
applyIt2(genFreshFunction("z"));
}