diff --git a/js/src/jit-test/tests/ion/bug1089761.js b/js/src/jit-test/tests/ion/bug1089761.js new file mode 100644 index 000000000000..b2940b671408 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug1089761.js @@ -0,0 +1,14 @@ +var hits = 0; +for (var j = 0; j < 9; ++j) { + try { + (function() { + (function() { + eval("x") + let x + })() + })() + } catch (e) { + hits++; + } +} +assertEq(hits, 9); diff --git a/js/src/vm/ScopeObject-inl.h b/js/src/vm/ScopeObject-inl.h index 8176333f3f51..26f4785e88a0 100644 --- a/js/src/vm/ScopeObject-inl.h +++ b/js/src/vm/ScopeObject-inl.h @@ -57,9 +57,9 @@ inline void CallObject::setAliasedLexicalsToThrowOnTouch(JSScript *script) { uint32_t aliasedLexicalBegin = script->bindings.aliasedBodyLevelLexicalBegin(); - uint32_t aliasedLexicalEnd = numFixedSlots(); + uint32_t aliasedLexicalEnd = slotSpan(); for (uint32_t slot = aliasedLexicalBegin; slot < aliasedLexicalEnd; slot++) - initFixedSlot(slot, MagicValue(JS_UNINITIALIZED_LEXICAL)); + initSlot(slot, MagicValue(JS_UNINITIALIZED_LEXICAL)); } template diff --git a/js/src/vm/ScopeObject.cpp b/js/src/vm/ScopeObject.cpp index 9547a6480543..fed7d2b96413 100644 --- a/js/src/vm/ScopeObject.cpp +++ b/js/src/vm/ScopeObject.cpp @@ -198,6 +198,10 @@ CallObject::createTemplateObject(JSContext *cx, HandleScript script, gc::Initial if (!obj) return nullptr; + // Set uninitialized lexicals even on template objects, as Ion will + // copy over the template object's slot values in the fast path. + obj->as().setAliasedLexicalsToThrowOnTouch(script); + return &obj->as(); } @@ -217,7 +221,6 @@ CallObject::create(JSContext *cx, HandleScript script, HandleObject enclosing, H callobj->as().setEnclosingScope(enclosing); callobj->initFixedSlot(CALLEE_SLOT, ObjectOrNullValue(callee)); - callobj->setAliasedLexicalsToThrowOnTouch(script); if (script->treatAsRunOnce()) { Rooted ncallobj(cx, callobj);