blob: 429e8948eabf54f4641fbf97168d76b015003759 [file] [log] [blame]
load(libdir + 'bytecode-cache.js');
var test = "";
var checkAfter;
// code a function which has both used and unused inner functions.
test = (function () {
function f(x) {
function ifTrue() {
return true;
};
function ifFalse() {
return false;
};
if (x) return ifTrue();
else return ifFalse();
}
return f.toSource() + "; f(true)";
})();
evalWithCache(test, { assertEqBytecode: true, assertEqResult : true });
// code a function which uses different inner functions based on the generation.
test = (function () {
function f(x) {
function ifTrue() {
return true;
};
function ifFalse() {
return false;
};
if (x) return ifTrue();
else return ifFalse();
}
return f.toSource() + "; f((generation % 2) == 0)";
})();
evalWithCache(test, { });
// Code a function which has an enclosing scope.
test = (function () {
function f() {
var upvar = "";
function g() { upvar += ""; return upvar; }
return g;
}
return f.toSource() + "; f()();";
})();
evalWithCache(test, { assertEqBytecode: true, assertEqResult : true });
// Code a lazy function which has an enclosing scope.
test = (function () {
function f() {
var upvar = "";
function g() { upvar += ""; return upvar; }
return g;
}
return f.toSource() + "; f();";
})();
evalWithCache(test, { assertEqBytecode: true });
// (basic/bug535930) Code an enclosing scope which is a Call object.
test = (function () {
return "(" + (function () {
p = function () {
Set()
};
var Set = function () {};
for (var x = 0; x < 5; x++) {
Set = function (z) {
return function () {
[z]
}
} (x)
}
}).toSource() + ")()";
})();
evalWithCache(test, { assertEqBytecode: true });
// Code an arrow function, and execute it.
test = (function () {
function f() {
var g = (a) => a + a;
return g;
}
return f.toSource() + "; f()(1);";
})();
evalWithCache(test, { assertEqBytecode: true, assertEqResult : true });
// Code an arrow function, and do not execute it.
test = (function () {
function f() {
var g = (a) => a + a;
return g;
}
return f.toSource() + "; f();";
})();
evalWithCache(test, { assertEqBytecode: true });
// Extra zeal GCs can cause isRelazifiableFunction() to become true after we
// record its value by throwing away JIT code for the function.
gczeal(0);
// Ensure that decoded functions can be relazified.
test = "function f() { }; f();"
+ "assertEq(isLazyFunction(f), false);"
+ "var expect = isRelazifiableFunction(f);";
checkAfter = function (ctx) {
gc(ctx.global.f); // relazify f, if possible.
evaluate("assertEq(isLazyFunction(f), expect);", ctx);
};
evalWithCache(test, {
assertEqBytecode: true, // Check that we re-encode the same thing.
assertEqResult: true, // The function should remain relazifiable, if it was
// during the first run.
checkAfter: checkAfter // Check that relazifying the restored function works
// if the original was relazifiable.
});
// Ensure that decoded functions can be relazified, even if they have free
// variables.
test = "function f() { return isRelazifiableFunction(f) }; var expect = f();"
+ "assertEq(isLazyFunction(f), false);"
+ "expect";
checkAfter = function (ctx) {
gc(ctx.global.f); // relazify f, if possible.
evaluate("assertEq(isLazyFunction(f), expect);", ctx);
};
evalWithCache(test, {
assertEqBytecode: true, // Check that we re-encode the same thing.
assertEqResult: true, // The function should remain relazifiable, if it was
// during the first run.
checkAfter: checkAfter // Check that relazifying the restored function works
// if the original was relazifiable.
});
// Ensure that if a function is encoded when non-lazy but relazifiable, then
// decoded, relazified, and then delazified, the result actually works.
test = `
function f() { return true; };
var canBeLazy = isRelazifiableFunction(f) || isLazyFunction(f);
relazifyFunctions();
assertEq(isLazyFunction(f), canBeLazy);
f()`
evalWithCache(test, { assertEqBytecode: true, assertEqResult: true });
// And more of the same, in a slightly different way
var g1 = newGlobal({ cloneSingletons: true });
var g2 = newGlobal();
var res = "function f(){}";
var code = cacheEntry(res + "; f();");
evaluate(code, {global:g1, compileAndGo: true, saveBytecode: {value: true}});
evaluate(code, {global:g2, loadBytecode: true});
gc();
assertEq(g2.f.toString(), res);
// Another relazification case.
var src = "function f() { return 3; }; f(); relazifyFunctions(); 4";
evalWithCache(src, {assertEqBytecode: true, assertEqResult: true});