michael@0: load(libdir + 'bytecode-cache.js'); michael@0: var test = ""; michael@0: var checkAfter; michael@0: michael@0: // code a function which has both used and unused inner functions. michael@0: test = (function () { michael@0: function f(x) { michael@0: function ifTrue() { michael@0: return true; michael@0: }; michael@0: function ifFalse() { michael@0: return false; michael@0: }; michael@0: michael@0: if (x) return ifTrue(); michael@0: else return ifFalse(); michael@0: } michael@0: michael@0: return f.toSource() + "; f(true)"; michael@0: })(); michael@0: evalWithCache(test, { assertEqBytecode: true, assertEqResult : true }); michael@0: michael@0: // code a function which uses different inner functions based on the generation. michael@0: test = (function () { michael@0: function f(x) { michael@0: function ifTrue() { michael@0: return true; michael@0: }; michael@0: function ifFalse() { michael@0: return false; michael@0: }; michael@0: michael@0: if (x) return ifTrue(); michael@0: else return ifFalse(); michael@0: } michael@0: michael@0: return f.toSource() + "; f((generation % 2) == 0)"; michael@0: })(); michael@0: evalWithCache(test, { }); michael@0: michael@0: // Code a function which has an enclosing scope. michael@0: test = (function () { michael@0: function f() { michael@0: var upvar = ""; michael@0: function g() { upvar += ""; return upvar; } michael@0: return g; michael@0: } michael@0: michael@0: return f.toSource() + "; f()();"; michael@0: })(); michael@0: evalWithCache(test, { assertEqBytecode: true, assertEqResult : true }); michael@0: michael@0: // Code a lazy function which has an enclosing scope. michael@0: test = (function () { michael@0: function f() { michael@0: var upvar = ""; michael@0: function g() { upvar += ""; return upvar; } michael@0: return g; michael@0: } michael@0: michael@0: return f.toSource() + "; f();"; michael@0: })(); michael@0: evalWithCache(test, { assertEqBytecode: true }); michael@0: michael@0: // (basic/bug535930) Code an enclosing scope which is a Call object. michael@0: test = (function () { michael@0: return "(" + (function () { michael@0: p = function () { michael@0: Set() michael@0: }; michael@0: var Set = function () {}; michael@0: for (var x = 0; x < 5; x++) { michael@0: Set = function (z) { michael@0: return function () { michael@0: [z] michael@0: } michael@0: } (x) michael@0: } michael@0: }).toSource() + ")()"; michael@0: })(); michael@0: evalWithCache(test, { assertEqBytecode: true }); michael@0: michael@0: // Code an arrow function, and execute it. michael@0: test = (function () { michael@0: function f() { michael@0: var g = (a) => a + a; michael@0: return g; michael@0: } michael@0: michael@0: return f.toSource() + "; f()(1);"; michael@0: })(); michael@0: evalWithCache(test, { assertEqBytecode: true, assertEqResult : true }); michael@0: michael@0: // Code an arrow function, and do not execute it. michael@0: test = (function () { michael@0: function f() { michael@0: var g = (a) => a + a; michael@0: return g; michael@0: } michael@0: michael@0: return f.toSource() + "; f();"; michael@0: })(); michael@0: evalWithCache(test, { assertEqBytecode: true }); michael@0: michael@0: // Ensure that decoded functions can be relazified. michael@0: test = "function f() { }; f();" michael@0: + "assertEq(isLazyFunction(f), false);" michael@0: + "var expect = isRelazifiableFunction(f);"; michael@0: checkAfter = function (ctx) { michael@0: gc(ctx.global.f); // relazify f, if possible. michael@0: evaluate("assertEq(isLazyFunction(f), expect);", ctx); michael@0: }; michael@0: evalWithCache(test, { michael@0: assertEqBytecode: true, // Check that we re-encode the same thing. michael@0: assertEqResult: true, // The function should remain relazifiable, if it was michael@0: // during the first run. michael@0: checkAfter: checkAfter // Check that relazifying the restored function works michael@0: // if the original was relazifiable. michael@0: }); michael@0: michael@0: // Ensure that decoded functions can be relazified, even if they have free michael@0: // variables. michael@0: test = "function f() { return isRelazifiableFunction(f) }; var expect = f();" michael@0: + "assertEq(isLazyFunction(f), false);" michael@0: + "expect"; michael@0: checkAfter = function (ctx) { michael@0: gc(ctx.global.f); // relazify f, if possible. michael@0: evaluate("assertEq(isLazyFunction(f), expect);", ctx); michael@0: }; michael@0: evalWithCache(test, { michael@0: assertEqBytecode: true, // Check that we re-encode the same thing. michael@0: assertEqResult: true, // The function should remain relazifiable, if it was michael@0: // during the first run. michael@0: checkAfter: checkAfter // Check that relazifying the restored function works michael@0: // if the original was relazifiable. michael@0: });