summaryrefslogtreecommitdiffstats
path: root/js/src/jit-test/tests/basic/testCallApply.js
diff options
context:
space:
mode:
Diffstat (limited to 'js/src/jit-test/tests/basic/testCallApply.js')
-rw-r--r--js/src/jit-test/tests/basic/testCallApply.js168
1 files changed, 168 insertions, 0 deletions
diff --git a/js/src/jit-test/tests/basic/testCallApply.js b/js/src/jit-test/tests/basic/testCallApply.js
new file mode 100644
index 000000000..9141f80bc
--- /dev/null
+++ b/js/src/jit-test/tests/basic/testCallApply.js
@@ -0,0 +1,168 @@
+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"));
+}