lazy.js (4776B)
1 load(libdir + 'bytecode-cache.js'); 2 var test = ""; 3 var checkAfter; 4 5 // code a function which has both used and unused inner functions. 6 test = (function () { 7 function f(x) { 8 function ifTrue() { 9 return true; 10 }; 11 function ifFalse() { 12 return false; 13 }; 14 15 if (x) return ifTrue(); 16 else return ifFalse(); 17 } 18 19 return f.toString() + "; f(true)"; 20 })(); 21 evalWithCache(test, { assertEqBytecode: true, assertEqResult : true }); 22 23 // code a function which uses different inner functions based on the generation. 24 test = (function () { 25 function f(x) { 26 function ifTrue() { 27 return true; 28 }; 29 function ifFalse() { 30 return false; 31 }; 32 33 if (x) return ifTrue(); 34 else return ifFalse(); 35 } 36 37 return f.toString() + "; f((generation % 2) == 0)"; 38 })(); 39 evalWithCache(test, { }); 40 41 // Code a function which has an enclosing scope. 42 test = (function () { 43 function f() { 44 var upvar = ""; 45 function g() { upvar += ""; return upvar; } 46 return g; 47 } 48 49 return f.toString() + "; f()();"; 50 })(); 51 evalWithCache(test, { assertEqBytecode: true, assertEqResult : true }); 52 53 // Code a lazy function which has an enclosing scope. 54 test = (function () { 55 function f() { 56 var upvar = ""; 57 function g() { upvar += ""; return upvar; } 58 return g; 59 } 60 61 return f.toString() + "; f();"; 62 })(); 63 evalWithCache(test, { assertEqBytecode: true }); 64 65 // (basic/bug535930) Code an enclosing scope which is a Call object. 66 test = (function () { 67 return "(" + (function () { 68 p = function () { 69 Set() 70 }; 71 var Set = function () {}; 72 for (var x = 0; x < 5; x++) { 73 Set = function (z) { 74 return function () { 75 [z] 76 } 77 } (x) 78 } 79 }).toString() + ")()"; 80 })(); 81 evalWithCache(test, { assertEqBytecode: true }); 82 83 // Code an arrow function, and execute it. 84 test = (function () { 85 function f() { 86 var g = (a) => a + a; 87 return g; 88 } 89 90 return f.toString() + "; f()(1);"; 91 })(); 92 evalWithCache(test, { assertEqBytecode: true, assertEqResult : true }); 93 94 // Code an arrow function, and do not execute it. 95 test = (function () { 96 function f() { 97 var g = (a) => a + a; 98 return g; 99 } 100 101 return f.toString() + "; f();"; 102 })(); 103 evalWithCache(test, { assertEqBytecode: true }); 104 105 // Extra zeal GCs can cause isRelazifiableFunction() to become true after we 106 // record its value by throwing away JIT code for the function. 107 gczeal(0); 108 109 // Ensure that decoded functions can be relazified. 110 test = "function f() { }; f();" 111 + "assertEq(isLazyFunction(f), false);" 112 + "var expect = isRelazifiableFunction(f);"; 113 checkAfter = function (ctx) { 114 relazifyFunctions(); // relazify f, if possible. 115 evaluate("assertEq(isLazyFunction(f), expect);", ctx); 116 }; 117 evalWithCache(test, { 118 assertEqBytecode: true, // Check that we re-encode the same thing. 119 assertEqResult: true, // The function should remain relazifiable, if it was 120 // during the first run. 121 checkAfter: checkAfter // Check that relazifying the restored function works 122 // if the original was relazifiable. 123 }); 124 125 // Ensure that decoded functions can be relazified, even if they have free 126 // variables. 127 test = "function f() { return isRelazifiableFunction(f) }; var expect = f();" 128 + "assertEq(isLazyFunction(f), false);" 129 + "expect"; 130 checkAfter = function (ctx) { 131 relazifyFunctions(); // relazify f, if possible. 132 evaluate("assertEq(isLazyFunction(f), expect);", ctx); 133 }; 134 evalWithCache(test, { 135 assertEqBytecode: true, // Check that we re-encode the same thing. 136 assertEqResult: true, // The function should remain relazifiable, if it was 137 // during the first run. 138 checkAfter: checkAfter // Check that relazifying the restored function works 139 // if the original was relazifiable. 140 }); 141 142 // Ensure that if a function is encoded when non-lazy but relazifiable, then 143 // decoded, relazified, and then delazified, the result actually works. 144 test = ` 145 function f() { return true; }; 146 var canBeLazy = isRelazifiableFunction(f) || isLazyFunction(f); 147 relazifyFunctions(); 148 assertEq(isLazyFunction(f), canBeLazy); 149 f()` 150 evalWithCache(test, { assertEqBytecode: true, assertEqResult: true }); 151 152 // And more of the same, in a slightly different way 153 var g1 = newGlobal({ cloneSingletons: true }); 154 var g2 = newGlobal(); 155 var res = "function f(){}"; 156 var code = cacheEntry(res + "; f();"); 157 evaluate(code, {global:g1, saveBytecodeWithDelazifications: {value: true}}); 158 evaluate(code, {global:g2, loadBytecode: true}); 159 gc(); 160 assertEq(g2.f.toString(), res); 161 162 // Another relazification case. 163 var src = "function f() { return 3; }; f(); relazifyFunctions(); 4"; 164 evalWithCache(src, {assertEqBytecode: true, assertEqResult: true});