testCallApply.js (5508B)
1 function script1() { return arguments.length; } 2 function script2(x) { return x; } 3 function script3(x) { var o = arguments; return o[0]; } 4 function genClosure() { var x = 3; eval("x = 4"); return function(y) { return x + y } }; 5 var closed1 = genClosure(); 6 var closed2 = genClosure(); 7 var closed3 = genClosure(); 8 var native1 = String.prototype.search; 9 var native2 = String.prototype.match; 10 var tricky1 = { call:function(x,y) { return y }, apply:function(x,y) { return y } }; 11 12 test0(); 13 test1(); 14 test2(); 15 test3(); 16 17 function test0() { 18 assertEq(script1.call(null), 0); 19 assertEq(script1.call(null, 1), 1); 20 assertEq(script1.call(null, 1,2), 2); 21 assertEq(native1.call("aabc", /b/), 2); 22 assertEq(native1.call("abc"), 0); 23 assertEq(tricky1.call(null, 9), 9); 24 assertEq(script1.apply(null), 0); 25 assertEq(script1.apply(null, [1]), 1); 26 assertEq(script1.apply(null, [1,2]), 2); 27 assertEq(native1.apply("aabc", [/b/]), 2); 28 assertEq(native1.apply("abc"), 0); 29 assertEq(tricky1.apply(null, 1), 1); 30 } 31 test0(); 32 33 function test1() { 34 function f(arr) { 35 for (var i = 0; i < 10; ++i) { 36 for (var j = 0; j < arr.length; ++j) { 37 arr[j].call('a'); 38 arr[j].apply('a', []); 39 var arg0 = []; 40 arr[j].apply('a', arg0); 41 (function() { arr[j].apply('a', arguments); })(); 42 43 arr[j].call('a', 1); 44 arr[j].apply('a', [1]); 45 var arg0 = [1]; 46 arr[j].apply('a', arg0); 47 (function() { arr[j].apply('a', arguments); })(1); 48 49 arr[j].call('a', 1,'g'); 50 arr[j].apply('a', [1,'g']); 51 var arg0 = [1,'g']; 52 arr[j].apply('a', arg0); 53 (function() { arr[j].apply('a', arguments); })(1,'g'); 54 55 arr[j].call('a', 1,'g',3,4,5,6,7,8,9); 56 arr[j].apply('a', [1,'g',3,4,5,6,7,8,9]); 57 var arg0 = [1,'g',3,4,5,6,7,8,9]; 58 arr[j].apply('a', arg0); 59 (function() { arr[j].apply('a', arguments); })(1,'g',3,4,5,6,7,8,9); 60 } 61 } 62 } 63 64 f([script1, script1, script1, script1, script2, script2, script1, script2]); 65 f([script1, script2, script3, script1, script2, script3, script3, script3]); 66 f([script1, script2, script2, script2, script2, script3, script1, script2]); 67 f([script1, script1, script1, native1, native1, native1, native1, script1]); 68 f([native1, native1, native1, native2, native2, native2, native2, native1]); 69 f([native1, native2, native1, native2, native1, native2, native1, native2]); 70 f([native1, native1, native1, script1, script2, script2, native1, script3]); 71 f([closed1, closed1, closed1, closed2, closed2, closed2, script3, script3]); 72 f([closed1, closed2, closed1, closed2, closed1, closed2, closed1, closed2]); 73 f([closed1, closed2, closed3, closed1, closed2, closed3, script1, script2]); 74 f([closed1, closed1, closed1, closed2, closed2, closed2, native1, native2]); 75 f([closed1, closed1, closed1, closed2, closed2, closed2, native1, native2]); 76 f([native1, native1, native1, closed1, closed2, script1, script2, native2]); 77 } 78 79 // test things that break our speculation 80 function test2() { 81 var threw = false; 82 try { 83 (3).call(null, 1,2); 84 } catch (e) { 85 threw = true; 86 } 87 assertEq(threw, true); 88 89 var threw = false; 90 try { 91 (3).apply(null, [1,2]); 92 } catch (e) { 93 threw = true; 94 } 95 assertEq(threw, true); 96 97 var threw = false; 98 try { 99 var arr = [1,2]; 100 (3).apply(null, arr); 101 } catch (e) { 102 threw = true; 103 } 104 assertEq(threw, true); 105 106 function tryAndFail(o) { 107 var threw = false; 108 try { 109 o.call(null, 1,2); 110 } catch(e) { 111 threw = true; 112 } 113 assertEq(threw, true); 114 threw = false; 115 try { 116 o.apply(null, [1,2]); 117 } catch(e) { 118 threw = true; 119 } 120 assertEq(threw, true); 121 } 122 123 tryAndFail(1); 124 tryAndFail({}); 125 tryAndFail({call:{}, apply:{}}); 126 tryAndFail({call:function() { throw "not js_fun_call"}, apply:function(){ throw "not js_fun_apply" }}); 127 } 128 129 // hit the stubs::CompileFunction path 130 function test3() { 131 function genFreshFunction(s) { return new Function(s, "return " + s); } 132 133 function callIt(f) { 134 assertEq(f.call(null, 1,2), 1); 135 } 136 callIt(script2); callIt(script2); callIt(script2); callIt(script2); 137 callIt(genFreshFunction("x")); 138 callIt(genFreshFunction("y")); 139 callIt(genFreshFunction("z")); 140 141 function applyIt(f) { 142 var arr = [1,2]; 143 assertEq(f.apply(null, arr), 1); 144 } 145 applyIt(script2); applyIt(script2); applyIt(script2); applyIt(script2); 146 applyIt(genFreshFunction("x")); 147 applyIt(genFreshFunction("y")); 148 applyIt(genFreshFunction("z")); 149 150 function applyIt1(f) { 151 function g() { 152 assertEq(f.apply(null, arguments), 1); 153 } 154 g(1,2); 155 } 156 applyIt1(script2); applyIt1(script2); applyIt1(script2); applyIt1(script2); 157 applyIt1(genFreshFunction("x")); 158 applyIt1(genFreshFunction("y")); 159 applyIt1(genFreshFunction("z")); 160 161 function applyIt2(f) { 162 assertEq(f.apply(null, [1,2]), 1); 163 } 164 applyIt2(script2); applyIt2(script2); applyIt2(script2); applyIt2(script2); 165 applyIt2(genFreshFunction("x")); 166 applyIt2(genFreshFunction("y")); 167 applyIt2(genFreshFunction("z")); 168 }