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