Bug 449522 - Context menu for HTML5 <video> elements. r=gavin, ui-r=boriss
[wine-gecko.git] / js / src / trace-test.js
blob28e8696e39545bcfef9aca50c174a95d0b1e55a0
1 /**
2 * A number of the tests in this file depend on the setting of
3 * HOTLOOP. Define some constants up front, so they're easy to grep
4 * for.
5 */
6 // The HOTLOOP constant we depend on; only readable from our stats
7 // object in debug builds.
8 const haveTracemonkey = !!(this.tracemonkey)
9 const HOTLOOP = haveTracemonkey ? tracemonkey.HOTLOOP : 2;
10 // The loop count at which we trace
11 const RECORDLOOP = HOTLOOP;
12 // The loop count at which we run the trace
13 const RUNLOOP = HOTLOOP + 1;
15 var testName = null;
16 if ("arguments" in this && arguments.length > 0)
17 testName = arguments[0];
18 var fails = [], passes=[];
20 function jitstatHandler(f)
22 if (!haveTracemonkey) {
23 return;
25 // XXXbz this is a nasty hack, but I can't figure out a way to
26 // just use jitstats.tbl here
27 f("recorderStarted");
28 f("recorderAborted");
29 f("traceCompleted");
30 f("sideExitIntoInterpreter");
31 f("typeMapMismatchAtEntry");
32 f("returnToDifferentLoopHeader");
33 f("traceTriggered");
34 f("globalShapeMismatchAtEntry");
35 f("treesTrashed");
36 f("slotPromoted");
37 f("unstableLoopVariable");
38 f("breakLoopExits");
39 f("returnLoopExits");
42 function test(f)
44 if (!testName || testName == f.name) {
45 // Collect our jit stats
46 var localJITstats = {};
47 jitstatHandler(function(prop, local, global) {
48 localJITstats[prop] = tracemonkey[prop];
49 });
50 check(f.name, f(), f.expected, localJITstats, f.jitstats);
54 function check(desc, actual, expected, oldJITstats, expectedJITstats)
56 if (expected == actual) {
57 var pass = true;
58 jitstatHandler(function(prop) {
59 if (expectedJITstats && prop in expectedJITstats &&
60 expectedJITstats[prop] !=
61 tracemonkey[prop] - oldJITstats[prop]) {
62 pass = false;
64 });
65 if (pass) {
66 passes.push(desc);
67 return print(desc, ": passed");
70 fails.push(desc);
71 var expectedStats = "";
72 if (expectedJITstats) {
73 jitstatHandler(function(prop) {
74 if (prop in expectedJITstats) {
75 if (expectedStats)
76 expectedStats += " ";
77 expectedStats +=
78 prop + ": " + expectedJITstats[prop];
80 });
82 var actualStats = "";
83 if (expectedJITstats) {
84 jitstatHandler(function(prop) {
85 if (prop in expectedJITstats) {
86 if (actualStats)
87 actualStats += " ";
88 actualStats += prop + ": " + (tracemonkey[prop]-oldJITstats[prop]);
90 });
92 print(desc, ": FAILED: expected", typeof(expected), "(", expected, ")",
93 (expectedStats ? " [" + expectedStats + "] " : ""),
94 "!= actual",
95 typeof(actual), "(", actual, ")",
96 (actualStats ? " [" + actualStats + "] " : ""));
99 function ifInsideLoop()
101 var cond = true, intCond = 5, count = 0;
102 for (var i = 0; i < 100; i++) {
103 if (cond)
104 count++;
105 if (intCond)
106 count++;
108 return count;
110 ifInsideLoop.expected = 200;
111 test(ifInsideLoop);
113 function bitwiseAnd_inner(bitwiseAndValue) {
114 for (var i = 0; i < 60000; i++)
115 bitwiseAndValue = bitwiseAndValue & i;
116 return bitwiseAndValue;
118 function bitwiseAnd()
120 return bitwiseAnd_inner(12341234);
122 bitwiseAnd.expected = 0;
123 test(bitwiseAnd);
125 if (!testName || testName == "bitwiseGlobal") {
126 bitwiseAndValue = Math.pow(2,32);
127 for (var i = 0; i < 60000; i++)
128 bitwiseAndValue = bitwiseAndValue & i;
129 check("bitwiseGlobal", bitwiseAndValue, 0);
133 function equalInt()
135 var i1 = 55, one = 1, zero = 0, undef;
136 var o1 = { }, o2 = { };
137 var s = "5";
138 var hits = [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0];
139 for (var i = 0; i < 5000; i++) {
140 if (i1 == 55) hits[0]++;
141 if (i1 != 56) hits[1]++;
142 if (i1 < 56) hits[2]++;
143 if (i1 > 50) hits[3]++;
144 if (i1 <= 60) hits[4]++;
145 if (i1 >= 30) hits[5]++;
146 if (i1 == 7) hits[6]++;
147 if (i1 != 55) hits[7]++;
148 if (i1 < 30) hits[8]++;
149 if (i1 > 90) hits[9]++;
150 if (i1 <= 40) hits[10]++;
151 if (i1 >= 70) hits[11]++;
152 if (o1 == o2) hits[12]++;
153 if (o2 != null) hits[13]++;
154 if (s < 10) hits[14]++;
155 if (true < zero) hits[15]++;
156 if (undef > one) hits[16]++;
157 if (undef < zero) hits[17]++;
159 return hits.toString();
161 equalInt.expected = "5000,5000,5000,5000,5000,5000,0,0,0,0,0,0,0,5000,5000,0,0,0";
162 test(equalInt);
164 var a;
165 function setelem()
167 a = [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0];
168 a = a.concat(a, a, a);
169 var l = a.length;
170 for (var i = 0; i < l; i++) {
171 a[i] = i;
173 return a.toString();
175 setelem.expected = "0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83";
176 test(setelem);
178 function getelem_inner(a)
180 var accum = 0;
181 var l = a.length;
182 for (var i = 0; i < l; i++) {
183 accum += a[i];
185 return accum;
187 function getelem()
189 return getelem_inner(a);
191 getelem.expected = 3486;
192 test(getelem);
194 globalName = 907;
195 function name()
197 var a = 0;
198 for (var i = 0; i < 100; i++)
199 a = globalName;
200 return a;
202 name.expected = 907;
203 test(name);
205 var globalInt = 0;
206 if (!testName || testName == "globalGet") {
207 for (var i = 0; i < 500; i++)
208 globalInt = globalName + i;
209 check("globalGet", globalInt, globalName + 499);
212 if (!testName || testName == "globalSet") {
213 for (var i = 0; i < 500; i++)
214 globalInt = i;
215 check("globalSet", globalInt, 499);
218 function arith()
220 var accum = 0;
221 for (var i = 0; i < 100; i++) {
222 accum += (i * 2) - 1;
224 return accum;
226 arith.expected = 9800;
227 test(arith);
229 function lsh_inner(n)
231 var r;
232 for (var i = 0; i < 35; i++)
233 r = 0x1 << n;
234 return r;
236 function lsh()
238 return [lsh_inner(15),lsh_inner(55),lsh_inner(1),lsh_inner(0)];
240 lsh.expected = "32768,8388608,2,1";
241 test(lsh);
243 function rsh_inner(n)
245 var r;
246 for (var i = 0; i < 35; i++)
247 r = 0x11010101 >> n;
248 return r;
250 function rsh()
252 return [rsh_inner(8),rsh_inner(5),rsh_inner(35),rsh_inner(-1)];
254 rsh.expected = "1114369,8914952,35659808,0";
255 test(rsh);
257 function ursh_inner(n)
259 var r;
260 for (var i = 0; i < 35; i++)
261 r = -55 >>> n;
262 return r;
264 function ursh() {
265 return [ursh_inner(8),ursh_inner(33),ursh_inner(0),ursh_inner(1)];
267 ursh.expected = "16777215,2147483620,4294967241,2147483620";
268 test(ursh);
270 function doMath_inner(cos)
272 var s = 0;
273 var sin = Math.sin;
274 for (var i = 0; i < 200; i++)
275 s = -Math.pow(sin(i) + cos(i * 0.75), 4);
276 return s;
278 function doMath() {
279 return doMath_inner(Math.cos);
281 doMath.expected = -0.5405549555611059;
282 test(doMath);
284 function fannkuch() {
285 var count = Array(8);
286 var r = 8;
287 var done = 0;
288 while (done < 40) {
289 // write-out the first 30 permutations
290 done += r;
291 while (r != 1) { count[r - 1] = r; r--; }
292 while (true) {
293 count[r] = count[r] - 1;
294 if (count[r] > 0) break;
295 r++;
298 return done;
300 fannkuch.expected = 41;
301 test(fannkuch);
303 function xprop()
305 a = 0;
306 for (var i = 0; i < 20; i++)
307 a += 7;
308 return a;
310 xprop.expected = 140;
311 test(xprop);
313 var a = 2;
314 function getprop_inner(o2)
316 var o = {a:5};
317 var t = this;
318 var x = 0;
319 for (var i = 0; i < 20; i++) {
320 t = this;
321 x += o.a + o2.a + this.a + t.a;
323 return x;
325 function getprop() {
326 return getprop_inner({a:9});
328 getprop.expected = 360;
329 test(getprop);
331 function mod()
333 var mods = [-1,-1,-1,-1];
334 var a = 9.5, b = -5, c = 42, d = (1/0);
335 for (var i = 0; i < 20; i++) {
336 mods[0] = a % b;
337 mods[1] = b % 1;
338 mods[2] = c % d;
339 mods[3] = c % a;
340 mods[4] = b % 0;
342 return mods.toString();
344 mod.expected = "4.5,0,42,4,NaN";
345 test(mod);
347 function glob_f1() {
348 return 1;
350 function glob_f2() {
351 return glob_f1();
353 function call()
355 var q1 = 0, q2 = 0, q3 = 0, q4 = 0, q5 = 0;
356 var o = {};
357 function f1() {
358 return 1;
360 function f2(f) {
361 return f();
363 o.f = f1;
364 for (var i = 0; i < 100; ++i) {
365 q1 += f1();
366 q2 += f2(f1);
367 q3 += glob_f1();
368 q4 += o.f();
369 q5 += glob_f2();
371 var ret = [q1, q2, q3, q4, q5];
372 return ret;
374 call.expected = "100,100,100,100,100";
375 test(call);
377 function setprop()
379 var obj = { a:-1 };
380 var obj2 = { b:-1, a:-1 };
381 for (var i = 0; i < 20; i++) {
382 obj2.b = obj.a = i;
384 return [obj.a, obj2.a, obj2.b].toString();
386 setprop.expected = "19,-1,19";
387 test(setprop);
389 function testif() {
390 var q = 0;
391 for (var i = 0; i < 100; i++) {
392 if ((i & 1) == 0)
393 q++;
394 else
395 q--;
397 return q;
399 testif.expected = "0";
400 test(testif);
402 var globalinc = 0;
403 function testincops(n) {
404 var i = 0, o = {p:0}, a = [0];
405 n = 100;
407 for (i = 0; i < n; i++);
408 while (i-- > 0);
409 for (i = 0; i < n; ++i);
410 while (--i >= 0);
412 for (o.p = 0; o.p < n; o.p++) globalinc++;
413 while (o.p-- > 0) --globalinc;
414 for (o.p = 0; o.p < n; ++o.p) ++globalinc;
415 while (--o.p >= 0) globalinc--;
417 ++i; // set to 0
418 for (a[i] = 0; a[i] < n; a[i]++);
419 while (a[i]-- > 0);
420 for (a[i] = 0; a[i] < n; ++a[i]);
421 while (--a[i] >= 0);
423 return [++o.p, ++a[i], globalinc].toString();
425 testincops.expected = "0,0,0";
426 test(testincops);
428 function trees() {
429 var i = 0, o = [0,0,0];
430 for (i = 0; i < 100; ++i) {
431 if ((i & 1) == 0) o[0]++;
432 else if ((i & 2) == 0) o[1]++;
433 else o[2]++;
435 return o;
437 trees.expected = "50,25,25";
438 test(trees);
440 function unboxint() {
441 var q = 0;
442 var o = [4];
443 for (var i = 0; i < 100; ++i)
444 q = o[0] << 1;
445 return q;
447 unboxint.expected = "8";
448 test(unboxint);
450 function strings()
452 var a = [], b = -1;
453 var s = "abcdefghij", s2 = "a";
454 var f = "f";
455 var c = 0, d = 0, e = 0, g = 0;
456 for (var i = 0; i < 10; i++) {
457 a[i] = (s.substring(i, i+1) + s[i] + String.fromCharCode(s2.charCodeAt(0) + i)).concat(i) + i;
458 if (s[i] == f)
459 c++;
460 if (s[i] != 'b')
461 d++;
462 if ("B" > s2)
463 g++; // f already used
464 if (s2 < "b")
465 e++;
466 b = s.length;
468 return a.toString() + b + c + d + e + g;
470 strings.expected = "aaa00,bbb11,ccc22,ddd33,eee44,fff55,ggg66,hhh77,iii88,jjj991019100";
471 test(strings);
473 function dependentStrings()
475 var a = [];
476 var t = "abcdefghijklmnopqrst";
477 for (var i = 0; i < 10; i++) {
478 var s = t.substring(2*i, 2*i + 2);
479 a[i] = s + s.length;
481 return a.join("");
483 dependentStrings.expected = "ab2cd2ef2gh2ij2kl2mn2op2qr2st2";
484 test(dependentStrings);
486 function stringConvert()
488 var a = [];
489 var s1 = "F", s2 = "1.3", s3 = "5";
490 for (var i = 0; i < 10; i++) {
491 a[0] = 1 >> s1;
492 a[1] = 10 - s2;
493 a[2] = 15 * s3;
494 a[3] = s3 | 32;
495 a[4] = s2 + 60;
496 // a[5] = 9 + s3;
497 // a[6] = -s3;
498 a[7] = s3 & "7";
499 // a[8] = ~s3;
501 return a.toString();
503 stringConvert.expected = "1,8.7,75,37,1.360,,,5";
504 test(stringConvert);
506 function orTestHelper(a, b, n)
508 var k = 0;
509 for (var i = 0; i < n; i++) {
510 if (a || b)
511 k += i;
513 return k;
516 var orNaNTest1, orNaNTest2;
518 orNaNTest1 = new Function("return orTestHelper(NaN, NaN, 10);");
519 orNaNTest1.name = 'orNaNTest1';
520 orNaNTest1.expected = '0';
521 orNaNTest2 = new Function("return orTestHelper(NaN, 1, 10);");
522 orNaNTest2.name = 'orNaNTest2';
523 orNaNTest2.expected = '45';
524 test(orNaNTest1);
525 test(orNaNTest2);
527 function andTestHelper(a, b, n)
529 var k = 0;
530 for (var i = 0; i < n; i++) {
531 if (a && b)
532 k += i;
534 return k;
537 if (!testName || testName == "truthies") {
538 (function () {
539 var opsies = ["||", "&&"];
540 var falsies = [null, undefined, false, NaN, 0, ""];
541 var truthies = [{}, true, 1, 42, 1/0, -1/0, "blah"];
542 var boolies = [falsies, truthies];
544 // The for each here should abort tracing, so that this test framework
545 // relies only on the interpreter while the orTestHelper and andTestHelper
546 // functions get trace-JITed.
547 for each (var op in opsies) {
548 for (var i in boolies) {
549 for (var j in boolies[i]) {
550 var x = uneval(boolies[i][j]);
551 for (var k in boolies) {
552 for (var l in boolies[k]) {
553 var y = uneval(boolies[k][l]);
554 var prefix = (op == "||") ? "or" : "and";
555 var f = new Function("return " + prefix + "TestHelper(" + x + "," + y + ",10)");
556 f.name = prefix + "Test(" + x + "," + y + ")";
557 f.expected = eval(x + op + y) ? 45 : 0;
558 test(f);
564 })();
567 function nonEmptyStack1Helper(o, farble) {
568 var a = [];
569 var j = 0;
570 for (var i in o)
571 a[j++] = i;
572 return a.join("");
575 function nonEmptyStack1() {
576 return nonEmptyStack1Helper({a:1,b:2,c:3,d:4,e:5,f:6,g:7,h:8}, "hi");
579 nonEmptyStack1.expected = "abcdefgh";
580 test(nonEmptyStack1);
582 function nonEmptyStack2()
584 var a = 0;
585 for (var c in {a:1, b:2, c:3}) {
586 for (var i = 0; i < 10; i++)
587 a += i;
589 return String(a);
591 nonEmptyStack2.expected = "135";
592 test(nonEmptyStack2);
594 function arityMismatchMissingArg(arg)
596 for (var a = 0, i = 1; i < 10000; i *= 2) {
597 a += i;
599 return a;
601 arityMismatchMissingArg.expected = 16383;
602 test(arityMismatchMissingArg);
604 function arityMismatchExtraArg()
606 return arityMismatchMissingArg(1, 2);
608 arityMismatchExtraArg.expected = 16383;
609 test(arityMismatchExtraArg);
611 function MyConstructor(i)
613 this.i = i;
615 MyConstructor.prototype.toString = function() {return this.i + ""};
617 function newTest()
619 var a = [];
620 for (var i = 0; i < 10; i++)
621 a[i] = new MyConstructor(i);
622 return a.join("");
624 newTest.expected = "0123456789";
625 test(newTest);
627 // The following functions use a delay line of length 2 to change the value
628 // of the callee without exiting the traced loop. This is obviously tuned to
629 // match the current HOTLOOP setting of 2.
630 function shapelessArgCalleeLoop(f, g, h, a)
632 for (var i = 0; i < 10; i++) {
633 f(i, a);
634 f = g;
635 g = h;
639 function shapelessVarCalleeLoop(f0, g, h, a)
641 var f = f0;
642 for (var i = 0; i < 10; i++) {
643 f(i, a);
644 f = g;
645 g = h;
649 function shapelessLetCalleeLoop(f0, g, h, a)
651 for (var i = 0; i < 10; i++) {
652 let f = f0;
653 f(i, a);
654 f = g;
655 g = h;
659 function shapelessUnknownCalleeLoop(n, f, g, h, a)
661 for (var i = 0; i < 10; i++) {
662 (n || f)(i, a);
663 f = g;
664 g = h;
668 function shapelessCalleeTest()
670 var a = [];
672 var helper = function (i, a) a[i] = i;
673 shapelessArgCalleeLoop(helper, helper, function (i, a) a[i] = -i, a);
675 helper = function (i, a) a[10 + i] = i;
676 shapelessVarCalleeLoop(helper, helper, function (i, a) a[10 + i] = -i, a);
678 helper = function (i, a) a[20 + i] = i;
679 shapelessLetCalleeLoop(helper, helper, function (i, a) a[20 + i] = -i, a);
681 helper = function (i, a) a[30 + i] = i;
682 shapelessUnknownCalleeLoop(null, helper, helper, function (i, a) a[30 + i] = -i, a);
684 try {
685 helper = {hack: 42};
686 shapelessUnknownCalleeLoop(null, helper, helper, helper, a);
687 } catch (e) {
688 if (e + "" != "TypeError: f is not a function")
689 print("shapelessUnknownCalleeLoop: unexpected exception " + e);
691 return a.join("");
693 shapelessCalleeTest.expected = "01-2-3-4-5-6-7-8-901-2-3-4-5-6-7-8-9012345678901-2-3-4-5-6-7-8-9";
694 test(shapelessCalleeTest);
696 function typeofTest()
698 var values = ["hi", "hi", "hi", null, 5, 5.1, true, undefined, /foo/, typeofTest, [], {}], types = [];
699 for (var i = 0; i < values.length; i++)
700 types[i] = typeof values[i];
701 return types.toString();
703 typeofTest.expected = "string,string,string,object,number,number,boolean,undefined,object,function,object,object";
704 test(typeofTest);
706 function joinTest()
708 var s = "";
709 var a = [];
710 for (var i = 0; i < 8; i++)
711 a[i] = [String.fromCharCode(97 + i)];
712 for (i = 0; i < 8; i++) {
713 for (var j = 0; j < 8; j++)
714 a[i][1 + j] = j;
716 for (i = 0; i < 8; i++)
717 s += a[i].join(",");
718 return s;
720 joinTest.expected = "a,0,1,2,3,4,5,6,7b,0,1,2,3,4,5,6,7c,0,1,2,3,4,5,6,7d,0,1,2,3,4,5,6,7e,0,1,2,3,4,5,6,7f,0,1,2,3,4,5,6,7g,0,1,2,3,4,5,6,7h,0,1,2,3,4,5,6,7";
721 test(joinTest);
723 function arity1(x)
725 return (x == undefined) ? 1 : 0;
727 function missingArgTest() {
728 var q;
729 for (var i = 0; i < 10; i++) {
730 q = arity1();
732 return q;
734 missingArgTest.expected = "1"
735 test(missingArgTest);
737 JSON = function () {
738 return {
739 stringify: function stringify(value, whitelist) {
740 switch (typeof(value)) {
741 case "object":
742 return value.constructor.name;
746 }();
748 function missingArgTest2() {
749 var testPairs = [
750 ["{}", {}],
751 ["[]", []],
752 ['{"foo":"bar"}', {"foo":"bar"}],
755 var a = [];
756 for (var i=0; i < testPairs.length; i++) {
757 var s = JSON.stringify(testPairs[i][1])
758 a[i] = s;
760 return a.join(",");
762 missingArgTest2.expected = "Object,Array,Object";
763 test(missingArgTest2);
765 function deepForInLoop() {
766 // NB: the number of props set in C is arefully tuned to match HOTLOOP = 2.
767 function C(){this.p = 1, this.q = 2}
768 C.prototype = {p:1, q:2, r:3, s:4, t:5};
769 var o = new C;
770 var j = 0;
771 var a = [];
772 for (var i in o)
773 a[j++] = i;
774 return a.join("");
776 deepForInLoop.expected = "pqrst";
777 test(deepForInLoop);
779 function nestedExit(x) {
780 var q = 0;
781 for (var i = 0; i < 10; ++i)
782 if (x)
783 ++q;
785 function nestedExitLoop() {
786 for (var j = 0; j < 10; ++j)
787 nestedExit(j < 7);
788 return "ok";
790 nestedExitLoop.expected = "ok";
791 test(nestedExitLoop);
793 function bitsinbyte(b) {
794 var m = 1, c = 0;
795 while(m<0x100) {
796 if(b & m) c++;
797 m <<= 1;
799 return 1;
801 function TimeFunc(func) {
802 var x,y;
803 for(var y=0; y<256; y++) func(y);
805 function nestedExit2() {
806 TimeFunc(bitsinbyte);
807 return "ok";
809 nestedExit2.expected = "ok";
810 test(nestedExit2);
812 function parsingNumbers() {
813 var s1 = "123";
814 var s1z = "123zzz";
815 var s2 = "123.456";
816 var s2z = "123.456zzz";
818 var e1 = 123;
819 var e2 = 123.456;
821 var r1, r1z, r2, r2z;
823 for (var i = 0; i < 10; i++) {
824 r1 = parseInt(s1);
825 r1z = parseInt(s1z);
826 r2 = parseFloat(s2);
827 r2z = parseFloat(s2z);
830 if (r1 == e1 && r1z == e1 && r2 == e2 && r2z == e2)
831 return "ok";
832 return "fail";
834 parsingNumbers.expected = "ok";
835 test(parsingNumbers);
837 function matchInLoop() {
838 var k = "hi";
839 for (var i = 0; i < 10; i++) {
840 var result = k.match(/hi/) != null;
842 return result;
844 matchInLoop.expected = true;
845 test(matchInLoop);
847 function deep1(x) {
848 if (x > 90)
849 return 1;
850 return 2;
852 function deep2() {
853 for (var i = 0; i < 100; ++i)
854 deep1(i);
855 return "ok";
857 deep2.expected = "ok";
858 test(deep2);
860 var merge_type_maps_x = 0, merge_type_maps_y = 0;
861 function merge_type_maps() {
862 for (merge_type_maps_x = 0; merge_type_maps_x < 50; ++merge_type_maps_x)
863 if ((merge_type_maps_x & 1) == 1)
864 ++merge_type_maps_y;
865 return [merge_type_maps_x,merge_type_maps_y].join(",");
867 merge_type_maps.expected = "50,25";
868 test(merge_type_maps)
870 function inner_double_outer_int() {
871 function f(i) {
872 for (var m = 0; m < 20; ++m)
873 for (var n = 0; n < 100; n += i)
875 return n;
877 return f(.5);
879 inner_double_outer_int.expected = "100";
880 test(inner_double_outer_int);
882 function newArrayTest()
884 var a = [];
885 for (var i = 0; i < 10; i++)
886 a[i] = new Array();
887 return a.map(function(x) x.length).toString();
889 newArrayTest.expected="0,0,0,0,0,0,0,0,0,0";
890 test(newArrayTest);
892 function stringSplitTest()
894 var s = "a,b"
895 var a = null;
896 for (var i = 0; i < 10; ++i)
897 a = s.split(",");
898 return a.join();
900 stringSplitTest.expected="a,b";
901 test(stringSplitTest);
903 function stringSplitIntoArrayTest()
905 var s = "a,b"
906 var a = [];
907 for (var i = 0; i < 10; ++i)
908 a[i] = s.split(",");
909 return a.join();
911 stringSplitIntoArrayTest.expected="a,b,a,b,a,b,a,b,a,b,a,b,a,b,a,b,a,b,a,b";
912 test(stringSplitIntoArrayTest);
914 function forVarInWith() {
915 function foo() ({notk:42});
916 function bar() ({p:1, q:2, r:3, s:4, t:5});
917 var o = foo();
918 var a = [];
919 with (o) {
920 for (var k in bar())
921 a[a.length] = k;
923 return a.join("");
925 forVarInWith.expected = "pqrst";
926 test(forVarInWith);
928 function inObjectTest() {
929 var o = {p: 1, q: 2, r: 3, s: 4, t: 5};
930 var r = 0;
931 for (var i in o) {
932 if (!(i in o))
933 break;
934 if ((i + i) in o)
935 break;
936 ++r;
938 return r;
940 inObjectTest.expected = 5;
941 test(inObjectTest);
943 function inArrayTest() {
944 var a = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
945 for (var i = 0; i < a.length; i++) {
946 if (!(i in a))
947 break;
949 return i;
951 inArrayTest.expected = 10;
952 test(inArrayTest);
954 function innerLoopIntOuterDouble() {
955 var n = 10000, i=0, j=0, count=0, limit=0;
956 for (i = 1; i <= n; ++i) {
957 limit = i * 1;
958 for (j = 0; j < limit; ++j) {
959 ++count;
962 return "" + count;
964 innerLoopIntOuterDouble.expected="50005000";
965 test(innerLoopIntOuterDouble);
967 function outerline(){
968 var i=0;
969 var j=0;
971 for (i = 3; i<= 100000; i+=2)
972 for (j = 3; j < 1000; j+=2)
973 if ((i & 1) == 1)
974 break;
975 return "ok";
977 outerline.expected="ok";
978 test(outerline);
980 function addAccumulations(f) {
981 var a = f();
982 var b = f();
983 return a() + b();
986 function loopingAccumulator() {
987 var x = 0;
988 return function () {
989 for (var i = 0; i < 10; ++i) {
990 ++x;
992 return x;
996 function testLoopingAccumulator() {
997 var x = addAccumulations(loopingAccumulator);
998 return x;
1000 testLoopingAccumulator.expected = 20;
1001 test(testLoopingAccumulator);
1003 function testBranchingLoop() {
1004 var x = 0;
1005 for (var i=0; i < 100; ++i) {
1006 if (i == 51) {
1007 x += 10;
1009 x++;
1011 return x;
1013 testBranchingLoop.expected = 110;
1014 test(testBranchingLoop);
1016 function testBranchingUnstableLoop() {
1017 var x = 0;
1018 for (var i=0; i < 100; ++i) {
1019 if (i == 51) {
1020 x += 10.1;
1022 x++;
1024 return x;
1026 testBranchingUnstableLoop.expected = 110.1;
1027 test(testBranchingUnstableLoop);
1029 function testBranchingUnstableLoopCounter() {
1030 var x = 0;
1031 for (var i=0; i < 100; ++i) {
1032 if (i == 51) {
1033 i += 1.1;
1035 x++;
1037 return x;
1039 testBranchingUnstableLoopCounter.expected = 99;
1040 test(testBranchingUnstableLoopCounter);
1043 function testBranchingUnstableObject() {
1044 var x = {s: "a"};
1045 var t = "";
1046 for (var i=0; i < 100; ++i) {
1047 if (i == 51)
1049 x.s = 5;
1051 t += x.s;
1053 return t.length;
1055 testBranchingUnstableObject.expected = 100;
1056 test(testBranchingUnstableObject);
1058 function testArrayDensityChange() {
1059 var x = [];
1060 var count = 0;
1061 for (var i=0; i < 100; ++i) {
1062 x[i] = "asdf";
1064 for (var i=0; i < x.length; ++i) {
1065 if (i == 51)
1067 x[199] = "asdf";
1069 if (x[i])
1070 count += x[i].length;
1072 return count;
1074 testArrayDensityChange.expected = 404;
1075 test(testArrayDensityChange);
1077 function testDoubleToStr() {
1078 var x = 0.0;
1079 var y = 5.5;
1080 for (var i = 0; i < 200; i++) {
1081 x += parseFloat(y.toString());
1083 return x;
1085 testDoubleToStr.expected = 5.5*200;
1086 test(testDoubleToStr);
1088 function testNumberToString() {
1089 var x = new Number(0);
1090 for (var i = 0; i < 4; i++)
1091 x.toString();
1093 test(testNumberToString);
1095 function testDecayingInnerLoop() {
1096 var i, j, k = 10;
1097 for (i = 0; i < 5000; ++i) {
1098 for (j = 0; j < k; ++j);
1099 --k;
1101 return i;
1103 testDecayingInnerLoop.expected = 5000;
1104 test(testDecayingInnerLoop);
1106 function testContinue() {
1107 var i;
1108 var total = 0;
1109 for (i = 0; i < 20; ++i) {
1110 if (i == 11)
1111 continue;
1112 total++;
1114 return total;
1116 testContinue.expected = 19;
1117 test(testContinue);
1119 function testContinueWithLabel() {
1120 var i = 0;
1121 var j = 20;
1122 checkiandj :
1123 while (i<10) {
1124 i+=1;
1125 checkj :
1126 while (j>10) {
1127 j-=1;
1128 if ((j%2)==0)
1129 continue checkj;
1132 return i + j;
1134 testContinueWithLabel.expected = 20;
1135 test(testContinueWithLabel);
1137 function testDivision() {
1138 var a = 32768;
1139 var b;
1140 while (b !== 1) {
1141 b = a / 2;
1142 a = b;
1144 return a;
1146 testDivision.expected = 1;
1147 test(testDivision);
1149 function testDivisionFloat() {
1150 var a = 32768.0;
1151 var b;
1152 while (b !== 1) {
1153 b = a / 2.0;
1154 a = b;
1156 return a === 1.0;
1158 testDivisionFloat.expected = true;
1159 test(testDivisionFloat);
1161 function testToUpperToLower() {
1162 var s = "Hello", s1, s2;
1163 for (i = 0; i < 100; ++i) {
1164 s1 = s.toLowerCase();
1165 s2 = s.toUpperCase();
1167 return s1 + s2;
1169 testToUpperToLower.expected = "helloHELLO";
1170 test(testToUpperToLower);
1172 function testReplace2() {
1173 var s = "H e l l o", s1;
1174 for (i = 0; i < 100; ++i) {
1175 s1 = s.replace(" ", "");
1177 return s1;
1179 testReplace2.expected = "He l l o";
1180 test(testReplace2);
1182 function testBitwise() {
1183 var x = 10000;
1184 var y = 123456;
1185 var z = 987234;
1186 for (var i = 0; i < 50; i++) {
1187 x = x ^ y;
1188 y = y | z;
1189 z = ~x;
1191 return x + y + z;
1193 testBitwise.expected = -1298;
1194 test(testBitwise);
1196 function testSwitch() {
1197 var x = 0;
1198 var ret = 0;
1199 for (var i = 0; i < 100; ++i) {
1200 switch (x) {
1201 case 0:
1202 ret += 1;
1203 break;
1204 case 1:
1205 ret += 2;
1206 break;
1207 case 2:
1208 ret += 3;
1209 break;
1210 case 3:
1211 ret += 4;
1212 break;
1213 default:
1214 x = 0;
1216 x++;
1218 return ret;
1220 testSwitch.expected = 226;
1221 test(testSwitch);
1223 function testSwitchString() {
1224 var x = "asdf";
1225 var ret = 0;
1226 for (var i = 0; i < 100; ++i) {
1227 switch (x) {
1228 case "asdf":
1229 x = "asd";
1230 ret += 1;
1231 break;
1232 case "asd":
1233 x = "as";
1234 ret += 2;
1235 break;
1236 case "as":
1237 x = "a";
1238 ret += 3;
1239 break;
1240 case "a":
1241 x = "foo";
1242 ret += 4;
1243 break;
1244 default:
1245 x = "asdf";
1248 return ret;
1250 testSwitchString.expected = 200;
1251 test(testSwitchString);
1253 function testNegZero1Helper(z) {
1254 for (let j = 0; j < 5; ++j) { z = -z; }
1255 return Math.atan2(0, -0) == Math.atan2(0, z);
1258 var testNegZero1 = function() { return testNegZero1Helper(0); }
1259 testNegZero1.expected = true;
1260 testNegZero1.name = 'testNegZero1';
1261 testNegZero1Helper(1);
1262 test(testNegZero1);
1264 // No test case, just make sure this doesn't assert.
1265 function testNegZero2() {
1266 var z = 0;
1267 for (let j = 0; j < 5; ++j) { ({p: (-z)}); }
1269 testNegZero2();
1271 function testConstSwitch() {
1272 var x;
1273 for (var j=0;j<5;++j) { switch(1.1) { case NaN: case 2: } x = 2; }
1274 return x;
1276 testConstSwitch.expected = 2;
1277 test(testConstSwitch);
1279 function testConstSwitch2() {
1280 var x;
1281 for (var j = 0; j < 4; ++j) { switch(0/0) { } }
1282 return "ok";
1284 testConstSwitch2.expected = "ok";
1285 test(testConstSwitch2);
1287 function testConstIf() {
1288 var x;
1289 for (var j=0;j<5;++j) { if (1.1 || 5) { } x = 2;}
1290 return x;
1292 testConstIf.expected = 2;
1293 test(testConstIf);
1295 function testTypeofHole() {
1296 var a = new Array(6);
1297 a[5] = 3;
1298 for (var i = 0; i < 6; ++i)
1299 a[i] = typeof a[i];
1300 return a.join(",");
1302 testTypeofHole.expected = "undefined,undefined,undefined,undefined,undefined,number"
1303 test(testTypeofHole);
1305 function testNativeLog() {
1306 var a = new Array(5);
1307 for (var i = 0; i < 5; i++) {
1308 a[i] = Math.log(Math.pow(Math.E, 10));
1310 return a.join(",");
1312 testNativeLog.expected = "10,10,10,10,10";
1313 test(testNativeLog);
1315 function test_JSOP_ARGSUB() {
1316 function f0() { return arguments[0]; }
1317 function f1() { return arguments[1]; }
1318 function f2() { return arguments[2]; }
1319 function f3() { return arguments[3]; }
1320 function f4() { return arguments[4]; }
1321 function f5() { return arguments[5]; }
1322 function f6() { return arguments[6]; }
1323 function f7() { return arguments[7]; }
1324 function f8() { return arguments[8]; }
1325 function f9() { return arguments[9]; }
1326 var a = [];
1327 for (var i = 0; i < 10; i++) {
1328 a[0] = f0('a');
1329 a[1] = f1('a','b');
1330 a[2] = f2('a','b','c');
1331 a[3] = f3('a','b','c','d');
1332 a[4] = f4('a','b','c','d','e');
1333 a[5] = f5('a','b','c','d','e','f');
1334 a[6] = f6('a','b','c','d','e','f','g');
1335 a[7] = f7('a','b','c','d','e','f','g','h');
1336 a[8] = f8('a','b','c','d','e','f','g','h','i');
1337 a[9] = f9('a','b','c','d','e','f','g','h','i','j');
1339 return a.join("");
1341 test_JSOP_ARGSUB.expected = "abcdefghij";
1342 test(test_JSOP_ARGSUB);
1344 function test_JSOP_ARGCNT() {
1345 function f0() { return arguments.length; }
1346 function f1() { return arguments.length; }
1347 function f2() { return arguments.length; }
1348 function f3() { return arguments.length; }
1349 function f4() { return arguments.length; }
1350 function f5() { return arguments.length; }
1351 function f6() { return arguments.length; }
1352 function f7() { return arguments.length; }
1353 function f8() { return arguments.length; }
1354 function f9() { return arguments.length; }
1355 var a = [];
1356 for (var i = 0; i < 10; i++) {
1357 a[0] = f0('a');
1358 a[1] = f1('a','b');
1359 a[2] = f2('a','b','c');
1360 a[3] = f3('a','b','c','d');
1361 a[4] = f4('a','b','c','d','e');
1362 a[5] = f5('a','b','c','d','e','f');
1363 a[6] = f6('a','b','c','d','e','f','g');
1364 a[7] = f7('a','b','c','d','e','f','g','h');
1365 a[8] = f8('a','b','c','d','e','f','g','h','i');
1366 a[9] = f9('a','b','c','d','e','f','g','h','i','j');
1368 return a.join(",");
1370 test_JSOP_ARGCNT.expected = "1,2,3,4,5,6,7,8,9,10";
1371 test(test_JSOP_ARGCNT);
1373 function testNativeMax() {
1374 var out = [], k;
1375 for (var i = 0; i < 5; ++i) {
1376 k = Math.max(k, i);
1378 out.push(k);
1380 k = 0;
1381 for (var i = 0; i < 5; ++i) {
1382 k = Math.max(k, i);
1384 out.push(k);
1386 for (var i = 0; i < 5; ++i) {
1387 k = Math.max(0, -0);
1389 out.push((1 / k) < 0);
1390 return out.join(",");
1392 testNativeMax.expected = "NaN,4,false";
1393 test(testNativeMax);
1395 function testFloatArrayIndex() {
1396 var a = [];
1397 for (var i = 0; i < 10; ++i) {
1398 a[3] = 5;
1399 a[3.5] = 7;
1401 return a[3] + "," + a[3.5];
1403 testFloatArrayIndex.expected = "5,7";
1404 test(testFloatArrayIndex);
1406 function testStrict() {
1407 var n = 10, a = [];
1408 for (var i = 0; i < 10; ++i) {
1409 a[0] = (n === 10);
1410 a[1] = (n !== 10);
1411 a[2] = (n === null);
1412 a[3] = (n == null);
1414 return a.join(",");
1416 testStrict.expected = "true,false,false,false";
1417 test(testStrict);
1419 function testSetPropNeitherMissNorHit() {
1420 for (var j = 0; j < 5; ++j) { if (({}).__proto__ = 1) { } }
1421 return "ok";
1423 testSetPropNeitherMissNorHit.expected = "ok";
1424 test(testSetPropNeitherMissNorHit);
1426 function testPrimitiveConstructorPrototype() {
1427 var f = function(){};
1428 f.prototype = false;
1429 for (let j=0;j<5;++j) { new f; }
1430 return "ok";
1432 testPrimitiveConstructorPrototype.expected = "ok";
1433 test(testPrimitiveConstructorPrototype);
1435 function testSideExitInConstructor() {
1436 var FCKConfig = {};
1437 FCKConfig.CoreStyles =
1439 'Bold': { },
1440 'Italic': { },
1441 'FontFace': { },
1442 'Size' :
1444 Overrides: [ ]
1447 'Color' :
1449 Element: '',
1450 Styles: { },
1451 Overrides: [ ]
1453 'BackColor': {
1454 Element : '',
1455 Styles : { 'background-color' : '' }
1459 var FCKStyle = function(A) {
1460 A.Element;
1463 var pass = true;
1464 for (var s in FCKConfig.CoreStyles) {
1465 var x = new FCKStyle(FCKConfig.CoreStyles[s]);
1466 if (!x) pass = false;
1468 return pass;
1470 testSideExitInConstructor.expected = true;
1471 test(testSideExitInConstructor);
1473 function testNot() {
1474 var a = new Object(), b = null, c = "foo", d = "", e = 5, f = 0, g = 5.5, h = -0, i = true, j = false, k = undefined;
1475 var r;
1476 for (var i = 0; i < 10; ++i) {
1477 r = [!a, !b, !c, !d, !e, !f, !g, !h, !i, !j, !k];
1479 return r.join(",");
1481 testNot.expected = "false,true,false,true,false,true,false,true,false,true,true";
1482 test(testNot);
1484 function doTestDifferingArgc(a, b)
1486 var k = 0;
1487 for (var i = 0; i < 10; i++)
1489 k += i;
1491 return k;
1493 function testDifferingArgc()
1495 var x = 0;
1496 x += doTestDifferingArgc(1, 2);
1497 x += doTestDifferingArgc(1);
1498 x += doTestDifferingArgc(1, 2, 3);
1499 return x;
1501 testDifferingArgc.expected = 45*3;
1502 test(testDifferingArgc);
1504 function doTestMoreArgcThanNargs()
1506 var x = 0;
1507 for (var i = 0; i < 10; i++)
1509 x = x + arguments[3];
1511 return x;
1513 function testMoreArgcThanNargs()
1515 return doTestMoreArgcThanNargs(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
1517 testMoreArgcThanNargs.expected = 4*10;
1518 test(testMoreArgcThanNargs);
1520 // Test stack reconstruction after a nested exit
1521 function testNestedExitStackInner(j, counter) {
1522 ++counter;
1523 var b = 0;
1524 for (var i = 1; i <= RUNLOOP; i++) {
1525 ++b;
1526 var a;
1527 // Make sure that once everything has been traced we suddenly switch to
1528 // a different control flow the first time we run the outermost tree,
1529 // triggering a side exit.
1530 if (j < RUNLOOP)
1531 a = 1;
1532 else
1533 a = 0;
1534 ++b;
1535 b += a;
1537 return counter + b;
1539 function testNestedExitStackOuter() {
1540 var counter = 0;
1541 for (var j = 1; j <= RUNLOOP; ++j) {
1542 for (var k = 1; k <= RUNLOOP; ++k) {
1543 counter = testNestedExitStackInner(j, counter);
1546 return counter;
1548 testNestedExitStackOuter.expected = 81;
1549 testNestedExitStackOuter.jitstats = {
1550 recorderStarted: 4,
1551 recorderAborted: 0,
1552 traceTriggered: 8
1554 test(testNestedExitStackOuter);
1556 function testHOTLOOPSize() {
1557 return HOTLOOP > 1;
1559 testHOTLOOPSize.expected = true;
1560 test(testHOTLOOPSize);
1562 function testMatchStringObject() {
1563 var a = new String("foo");
1564 var b;
1565 for (i = 0; i < 300; i++) {
1566 b = a.match(/bar/);
1568 return b;
1570 testMatchStringObject.expected = null;
1571 test(testMatchStringObject);
1573 function innerSwitch(k)
1575 var m = 0;
1577 switch (k)
1579 case 0:
1580 m = 1;
1581 break;
1584 return m;
1586 function testInnerSwitchBreak()
1588 var r = new Array(5);
1589 for (var i = 0; i < 5; i++)
1591 r[i] = innerSwitch(0);
1594 return r.join(",");
1596 testInnerSwitchBreak.expected = "1,1,1,1,1";
1597 test(testInnerSwitchBreak);
1599 function testArrayNaNIndex()
1601 for (var j = 0; j < 4; ++j) { [this[NaN]]; }
1602 for (var j = 0; j < 5; ++j) { if([1][-0]) { } }
1603 return "ok";
1605 testArrayNaNIndex.expected = "ok";
1606 test(testArrayNaNIndex);
1608 function innerTestInnerMissingArgs(a,b,c,d)
1610 if (a) {
1611 } else {
1614 function doTestInnerMissingArgs(k)
1616 for (i = 0; i < 10; i++) {
1617 innerTestInnerMissingArgs(k);
1620 function testInnerMissingArgs()
1622 doTestInnerMissingArgs(1);
1623 doTestInnerMissingArgs(0);
1624 return 1;
1626 testInnerMissingArgs.expected = 1; //Expected: that we don't crash.
1627 test(testInnerMissingArgs);
1629 function regexpLastIndex()
1631 var n = 0;
1632 var re = /hi/g;
1633 var ss = " hi hi hi hi hi hi hi hi hi hi";
1634 for (var i = 0; i < 10; i++) {
1635 // re.exec(ss);
1636 n += (re.lastIndex > 0) ? 3 : 0;
1637 re.lastIndex = 0;
1639 return n;
1641 regexpLastIndex.expected = 0; // 30;
1642 test(regexpLastIndex);
1644 function testHOTLOOPCorrectness() {
1645 var b = 0;
1646 for (var i = 0; i < HOTLOOP; ++i) {
1647 ++b;
1649 return b;
1651 testHOTLOOPCorrectness.expected = HOTLOOP;
1652 testHOTLOOPCorrectness.jitstats = {
1653 recorderStarted: 1,
1654 recorderAborted: 0,
1655 traceTriggered: 0
1657 // Change the global shape right before doing the test
1658 this.testHOTLOOPCorrectnessVar = 1;
1659 test(testHOTLOOPCorrectness);
1661 function testRUNLOOPCorrectness() {
1662 var b = 0;
1663 for (var i = 0; i < RUNLOOP; ++i) {
1664 ++b;
1666 return b;
1668 testRUNLOOPCorrectness.expected = RUNLOOP;
1669 testRUNLOOPCorrectness.jitstats = {
1670 recorderStarted: 1,
1671 recorderAborted: 0,
1672 traceTriggered: 1
1674 // Change the global shape right before doing the test
1675 this.testRUNLOOPCorrectnessVar = 1;
1676 test(testRUNLOOPCorrectness);
1678 function testDateNow() {
1679 // Accessing global.Date for the first time will change the global shape,
1680 // so do it before the loop starts; otherwise we have to loop an extra time
1681 // to pick things up.
1682 var time = Date.now();
1683 for (var j = 0; j < RUNLOOP; ++j) {
1684 time = Date.now();
1686 return "ok";
1688 testDateNow.expected = "ok";
1689 testDateNow.jitstats = {
1690 recorderStarted: 1,
1691 recorderAborted: 0,
1692 traceTriggered: 1
1694 test(testDateNow);
1696 function testINITELEM()
1698 var x;
1699 for (var i = 0; i < 10; ++i)
1700 x = { 0: 5, 1: 5 };
1701 return x[0] + x[1];
1703 testINITELEM.expected = 10;
1704 test(testINITELEM);
1706 function testUndefinedBooleanCmp()
1708 var t = true, f = false, x = [];
1709 for (var i = 0; i < 10; ++i) {
1710 x[0] = t == undefined;
1711 x[1] = t != undefined;
1712 x[2] = t === undefined;
1713 x[3] = t !== undefined;
1714 x[4] = t < undefined;
1715 x[5] = t > undefined;
1716 x[6] = t <= undefined;
1717 x[7] = t >= undefined;
1718 x[8] = f == undefined;
1719 x[9] = f != undefined;
1720 x[10] = f === undefined;
1721 x[11] = f !== undefined;
1722 x[12] = f < undefined;
1723 x[13] = f > undefined;
1724 x[14] = f <= undefined;
1725 x[15] = f >= undefined;
1727 return x.join(",");
1729 testUndefinedBooleanCmp.expected = "false,true,false,true,false,false,false,false,false,true,false,true,false,false,false,false";
1730 test(testUndefinedBooleanCmp);
1732 function testConstantBooleanExpr()
1734 for (var j = 0; j < 3; ++j) { if(true <= true) { } }
1735 return "ok";
1737 testConstantBooleanExpr.expected = "ok";
1738 test(testConstantBooleanExpr);
1740 function testNegativeGETELEMIndex()
1742 for (let i=0;i<3;++i) /x/[-4];
1743 return "ok";
1745 testNegativeGETELEMIndex.expected = "ok";
1746 test(testNegativeGETELEMIndex);
1748 function doTestInvalidCharCodeAt(input)
1750 var q = "";
1751 for (var i = 0; i < 10; i++)
1752 q += input.charCodeAt(i);
1753 return q;
1755 function testInvalidCharCodeAt()
1757 return doTestInvalidCharCodeAt("");
1759 testInvalidCharCodeAt.expected = "NaNNaNNaNNaNNaNNaNNaNNaNNaNNaN";
1760 test(testInvalidCharCodeAt);
1762 function FPQuadCmp()
1764 for (let j = 0; j < 3; ++j) { true == 0; }
1765 return "ok";
1767 FPQuadCmp.expected = "ok";
1768 test(FPQuadCmp);
1770 function testDestructuring() {
1771 var t = 0;
1772 for (var i = 0; i < HOTLOOP + 1; ++i) {
1773 var [r, g, b] = [1, 1, 1];
1774 t += r + g + b;
1776 return t
1778 testDestructuring.expected = (HOTLOOP + 1) * 3;
1779 test(testDestructuring);
1781 // BEGIN MANDELBROT STUFF
1782 // XXXbz I would dearly like to wrap it up into a function to avoid polluting
1783 // the global scope, but the function ends up heavyweight, and then we lose on
1784 // the jit.
1785 load("mandelbrot-results.js");
1786 //function testMandelbrotAll() {
1787 // Configuration options that affect which codepaths we follow.
1788 var doImageData = true;
1789 var avoidSparseArray = true;
1791 // Control of iteration numbers and sizing. We'll do
1792 // scaler * colorNames.length iterations or so before deciding that we
1793 // don't escape.
1794 const scaler = 5;
1795 const numRows = 600;
1796 const numCols = 600;
1798 // For now, avoid hitting memory pressure
1799 gcparam("maxBytes", 1300000000);
1800 gcparam("maxMallocBytes", 1300000000);
1802 const colorNames = [
1803 "black",
1804 "green",
1805 "blue",
1806 "red",
1807 "purple",
1808 "orange",
1809 "cyan",
1810 "yellow",
1811 "magenta",
1812 "brown",
1813 "pink",
1814 "chartreuse",
1815 "darkorange",
1816 "crimson",
1817 "gray",
1818 "deeppink",
1819 "firebrick",
1820 "lavender",
1821 "lawngreen",
1822 "lightsalmon",
1823 "lime",
1824 "goldenrod"
1826 const threshold = (colorNames.length - 1) * scaler;
1828 // Now set up our colors
1829 var colors = [];
1830 // 3-part for loop (iterators buggy, we will add a separate test for them)
1831 for (var colorNameIdx = 0; colorNameIdx < colorNames.length; ++colorNameIdx) {
1832 //for (var colorNameIdx in colorNames) {
1833 colorNameIdx = parseInt(colorNameIdx);
1834 colors.push([colorNameIdx, colorNameIdx, colorNameIdx, 0]);
1837 // Storage for our point data
1838 var points;
1840 var scratch = {};
1841 var scratchZ = {};
1842 function complexMult(a, b) {
1843 var newr = a.r * b.r - a.i * b.i;
1844 var newi = a.r * b.i + a.i * b.r;
1845 scratch.r = newr;
1846 scratch.i = newi;
1847 return scratch;
1849 function complexAdd(a, b) {
1850 scratch.r = a.r + b.r;
1851 scratch.i = a.i + b.i;
1852 return scratch;
1854 function abs(a) {
1855 return Math.sqrt(a.r * a.r + a.i * a.i);
1858 function escapeAbsDiff(normZ, absC) {
1859 var absZ = Math.sqrt(normZ);
1860 return normZ > absZ + absC;
1863 function escapeNorm2(normZ) {
1864 return normZ > 4;
1867 function fuzzyColors(i) {
1868 return Math.floor(i / scaler) + 1;
1871 function moddedColors(i) {
1872 return (i % (colorNames.length - 1)) + 1;
1875 function computeEscapeSpeedObjects(real, imag) {
1876 var c = { r: real, i: imag }
1877 scratchZ.r = scratchZ.i = 0;
1878 var absC = abs(c);
1879 for (var i = 0; i < threshold; ++i) {
1880 scratchZ = complexAdd(c, complexMult(scratchZ, scratchZ));
1881 if (escape(scratchZ.r * scratchZ.r + scratchZ.i * scratchZ.i,
1882 absC)) {
1883 return colorMap(i);
1886 return 0;
1889 function computeEscapeSpeedOneObject(real, imag) {
1890 // fold in the fact that we start with 0
1891 var r = real;
1892 var i = imag;
1893 var absC = abs({r: real, i: imag});
1894 for (var j = 0; j < threshold; ++j) {
1895 var r2 = r * r;
1896 var i2 = i * i;
1897 if (escape(r2 + i2, absC)) {
1898 return colorMap(j);
1900 i = 2 * r * i + imag;
1901 r = r2 - i2 + real;
1903 return 0;
1906 function computeEscapeSpeedDoubles(real, imag) {
1907 // fold in the fact that we start with 0
1908 var r = real;
1909 var i = imag;
1910 var absC = Math.sqrt(real * real + imag * imag);
1911 for (var j = 0; j < threshold; ++j) {
1912 var r2 = r * r;
1913 var i2 = i * i;
1914 if (escape(r2 + i2, absC)) {
1915 return colorMap(j);
1917 i = 2 * r * i + imag;
1918 r = r2 - i2 + real;
1920 return 0;
1923 var computeEscapeSpeed = computeEscapeSpeedDoubles;
1924 var escape = escapeNorm2;
1925 var colorMap = fuzzyColors;
1927 function addPointOrig(pointArray, n, i, j) {
1928 if (!points[n]) {
1929 points[n] = [];
1930 points[n].push([i, j, 1, 1]);
1931 } else {
1932 var point = points[n][points[n].length-1];
1933 if (point[0] == i && point[1] == j - point[3]) {
1934 ++point[3];
1935 } else {
1936 points[n].push([i, j, 1, 1]);
1941 function addPointImagedata(pointArray, n, col, row) {
1942 var slotIdx = ((row * numCols) + col) * 4;
1943 pointArray[slotIdx] = colors[n][0];
1944 pointArray[slotIdx+1] = colors[n][1];
1945 pointArray[slotIdx+2] = colors[n][2];
1946 pointArray[slotIdx+3] = colors[n][3];
1949 function createMandelSet() {
1950 var realRange = { min: -2.1, max: 1 };
1951 var imagRange = { min: -1.5, max: 1.5 };
1953 var addPoint;
1954 if (doImageData) {
1955 addPoint = addPointImagedata;
1956 points = new Array(4*numCols*numRows);
1957 if (avoidSparseArray) {
1958 for (var idx = 0; idx < 4*numCols*numRows; ++idx) {
1959 points[idx] = 0;
1962 } else {
1963 addPoint = addPointOrig;
1964 points = [];
1966 var realStep = (realRange.max - realRange.min)/numCols;
1967 var imagStep = (imagRange.min - imagRange.max)/numRows;
1968 for (var i = 0, curReal = realRange.min;
1969 i < numCols;
1970 ++i, curReal += realStep) {
1971 for (var j = 0, curImag = imagRange.max;
1972 j < numRows;
1973 ++j, curImag += imagStep) {
1974 var n = computeEscapeSpeed(curReal, curImag);
1975 addPoint(points, n, i, j)
1978 var result;
1979 if (doImageData) {
1980 if (colorMap == fuzzyColors) {
1981 result = mandelbrotImageDataFuzzyResult;
1982 } else {
1983 result = mandelbrotImageDataModdedResult;
1985 } else {
1986 result = mandelbrotNoImageDataResult;
1988 return points.toSource() == result;
1991 createMandelSet.expected = true;
1993 const escapeTests = [ escapeAbsDiff ];
1994 const colorMaps = [ fuzzyColors, moddedColors ];
1995 const escapeComputations = [ computeEscapeSpeedObjects,
1996 computeEscapeSpeedOneObject,
1997 computeEscapeSpeedDoubles ];
1998 // Test all possible escape-speed generation codepaths, using the
1999 // imageData + sparse array avoidance storage.
2000 doImageData = true;
2001 avoidSparseArray = true;
2002 for (var escapeIdx in escapeTests) {
2003 escape = escapeTests[escapeIdx];
2004 for (var colorMapIdx in colorMaps) {
2005 colorMap = colorMaps[colorMapIdx];
2006 for (var escapeComputationIdx in escapeComputations) {
2007 computeEscapeSpeed = escapeComputations[escapeComputationIdx];
2008 test(createMandelSet);
2013 // Test all possible storage strategies. Note that we already tested
2014 // doImageData == true with avoidSparseArray == true.
2015 escape = escapeAbsDiff;
2016 colorMap = fuzzyColors; // This part doesn't really matter too much here
2017 computeEscapeSpeed = computeEscapeSpeedDoubles;
2019 doImageData = true;
2020 avoidSparseArray = false;
2021 test(createMandelSet);
2023 escape = escapeNorm2;
2024 doImageData = false; // avoidSparseArray doesn't matter here
2025 test(createMandelSet);
2027 //testMandelbrotAll();
2028 // END MANDELBROT STUFF
2030 /* Keep this test last, since it screws up all for...in loops after it */
2031 function testGlobalProtoAccess() {
2032 return "ok";
2034 this.__proto__.a = 3; for (var j = 0; j < 4; ++j) { [a]; }
2035 testGlobalProtoAccess.expected = "ok";
2036 test(testGlobalProtoAccess);
2038 function testNewDate()
2040 // Accessing global.Date for the first time will change the global shape,
2041 // so do it before the loop starts; otherwise we have to loop an extra time
2042 // to pick things up.
2043 var start = new Date();
2044 var time = new Date();
2045 for (var j = 0; j < RUNLOOP; ++j) {
2046 time = new Date();
2048 return time > 0 && time >= start;
2050 testNewDate.expected = true;
2051 testNewDate.jitstats = {
2052 recorderStarted: 1,
2053 recorderAborted: 0,
2054 traceTriggered: 1
2056 test(testNewDate);
2058 function testArrayPushPop() {
2059 var a = [], sum1 = 0, sum2 = 0;
2060 for (var i = 0; i < 10; ++i)
2061 sum1 += a.push(i);
2062 for (var i = 0; i < 10; ++i)
2063 sum2 += a.pop();
2064 a.push(sum1);
2065 a.push(sum2);
2066 return a.join(",");
2068 testArrayPushPop.expected = "55,45";
2069 test(testArrayPushPop);
2071 function testResumeOp() {
2072 var a = [1,"2",3,"4",5,"6",7,"8",9,"10",11,"12",13,"14",15,"16"];
2073 var x = "";
2074 while (a.length > 0)
2075 x += a.pop();
2076 return x;
2078 testResumeOp.expected = "16151413121110987654321";
2079 test(testResumeOp);
2081 function testUndefinedCmp() {
2082 var a = false;
2083 for (var j = 0; j < 4; ++j) { if (undefined < false) { a = true; } }
2084 return a;
2086 testUndefinedCmp.expected = false;
2087 test(testUndefinedCmp);
2089 function reallyDeepNestedExit(schedule)
2091 var c = 0, j = 0;
2092 for (var i = 0; i < 5; i++) {
2093 for (j = 0; j < 4; j++) {
2094 c += (schedule[i*4 + j] == 1) ? 1 : 2;
2097 return c;
2099 function testReallyDeepNestedExit()
2101 var c = 0;
2102 var schedule1 = new Array(5*4);
2103 var schedule2 = new Array(5*4);
2104 for (var i = 0; i < 5*4; i++) {
2105 schedule1[i] = 0;
2106 schedule2[i] = 0;
2109 * First innermost compile: true branch runs through.
2110 * Second '': false branch compiles new loop edge.
2111 * First outer compile: expect true branch.
2112 * Second '': hit false branch.
2114 schedule1[0*4 + 3] = 1;
2115 var schedules = [schedule1,
2116 schedule2,
2117 schedule1,
2118 schedule2,
2119 schedule2];
2121 for (var i = 0; i < 5; i++) {
2122 c += reallyDeepNestedExit(schedules[i]);
2124 return c;
2126 testReallyDeepNestedExit.expected = 198;
2127 test(testReallyDeepNestedExit);
2129 /* Keep these at the end so that we can see the summary after the trace-debug spew. */
2130 print("\npassed:", passes.length && passes.join(","));
2131 print("\nFAILED:", fails.length && fails.join(","));