diff --git a/js/src/jit-test/tests/environments/bug1710089.js b/js/src/jit-test/tests/environments/bug1710089.js new file mode 100644 index 000000000000..9737456c397f --- /dev/null +++ b/js/src/jit-test/tests/environments/bug1710089.js @@ -0,0 +1,34 @@ +var iters = 250; + +// Generate a deeply nested version of: +// function outer() { +// var top_level_var = 42; +// let x3 = 0; +// function f2() { +// let x2 = x3; +// function f1() { +// let x1 = x2; +// function f0() { +// let x0 = x1; +// return top_level_var + x0; +// } +// return f0(); +// } +// return f1(); +// } +// return f2(); +// } + +var src = "return top_level_var + x0; " + +for (var i = 0; i < iters; i++) { + var def = "let x" + i + " = x" + (i+1) + "; "; + src = "function f" + i + "() { " + def + src + "} return f" + i + "();" +} +src = "let x" + iters + " = 0;" + src; +src = "var top_level_var = 42; " + src; + +var outer = Function(src); +for (var i = 0; i < 2; i++) { + assertEq(outer(), 42); +} diff --git a/js/src/jit/WarpBuilder.cpp b/js/src/jit/WarpBuilder.cpp index c3bc583e9e8f..18d7db6502d3 100644 --- a/js/src/jit/WarpBuilder.cpp +++ b/js/src/jit/WarpBuilder.cpp @@ -1627,6 +1627,10 @@ MDefinition* WarpBuilder::walkEnvironmentChain(uint32_t numHops) { MDefinition* env = current->environmentChain(); for (uint32_t i = 0; i < numHops; i++) { + if (!alloc().ensureBallast()) { + return nullptr; + } + MInstruction* ins = MEnclosingEnvironment::New(alloc(), env); current->add(ins); env = ins; @@ -1638,6 +1642,9 @@ MDefinition* WarpBuilder::walkEnvironmentChain(uint32_t numHops) { bool WarpBuilder::build_GetAliasedVar(BytecodeLocation loc) { EnvironmentCoordinate ec = loc.getEnvironmentCoordinate(); MDefinition* obj = walkEnvironmentChain(ec.hops()); + if (!obj) { + return false; + } MInstruction* load; if (EnvironmentObject::nonExtensibleIsFixedSlot(ec)) { @@ -1659,6 +1666,9 @@ bool WarpBuilder::build_SetAliasedVar(BytecodeLocation loc) { EnvironmentCoordinate ec = loc.getEnvironmentCoordinate(); MDefinition* val = current->peek(-1); MDefinition* obj = walkEnvironmentChain(ec.hops()); + if (!obj) { + return false; + } current->add(MPostWriteBarrier::New(alloc(), obj, val)); @@ -1684,6 +1694,10 @@ bool WarpBuilder::build_InitAliasedLexical(BytecodeLocation loc) { bool WarpBuilder::build_EnvCallee(BytecodeLocation loc) { uint32_t numHops = loc.getEnvCalleeNumHops(); MDefinition* env = walkEnvironmentChain(numHops); + if (!env) { + return false; + } + auto* callee = MLoadFixedSlot::New(alloc(), env, CallObject::calleeSlot()); current->add(callee); current->push(callee); @@ -2022,6 +2036,9 @@ bool WarpBuilder::build_PushClassBodyEnv(BytecodeLocation loc) { bool WarpBuilder::build_PopLexicalEnv(BytecodeLocation) { MDefinition* enclosingEnv = walkEnvironmentChain(1); + if (!enclosingEnv) { + return false; + } current->setEnvironmentChain(enclosingEnv); return true; }