Bug 1238555 - Always update the LazyScript's static scope chain when emitting functions. (r=till)

This commit is contained in:
Shu-yu Guo 2016-03-17 18:53:04 -07:00
parent 3490838493
commit 0f91ae27d6
4 changed files with 26 additions and 9 deletions

View File

@ -6390,11 +6390,16 @@ BytecodeEmitter::emitFunction(ParseNode* pn, bool needsProto)
SharedContext* outersc = sc;
if (fun->isInterpretedLazy()) {
if (!fun->lazyScript()->sourceObject()) {
JSObject* scope = innermostStaticScope();
JSObject* source = script->sourceObject();
fun->lazyScript()->setParent(scope, &source->as<ScriptSourceObject>());
}
// We need to update the static scope chain regardless of whether
// the LazyScript has already been initialized, due to the case
// where we previously successfully compiled an inner function's
// lazy script but failed to compile the outer script after the
// fact. If we attempt to compile the outer script again, the
// static scope chain will be newly allocated and will mismatch
// the previously compiled LazyScript's.
ScriptSourceObject* source = &script->sourceObject()->as<ScriptSourceObject>();
JSObject* scope = innermostStaticScope();
fun->lazyScript()->setEnclosingScopeAndSource(scope, source);
if (emittingRunOnceLambda)
fun->lazyScript()->setTreatAsRunOnce();
} else {

View File

@ -0,0 +1,9 @@
oomTest(
function x() {
try {
eval('let ')
} catch (ex) {
(function() {})()
}
}
);

View File

@ -4281,11 +4281,14 @@ LazyScript::resetScript()
}
void
LazyScript::setParent(JSObject* enclosingScope, ScriptSourceObject* sourceObject)
LazyScript::setEnclosingScopeAndSource(JSObject* enclosingScope, ScriptSourceObject* sourceObject)
{
MOZ_ASSERT(!sourceObject_ && !enclosingScope_);
MOZ_ASSERT_IF(enclosingScope, function_->compartment() == enclosingScope->compartment());
MOZ_ASSERT(function_->compartment() == sourceObject->compartment());
// This method may be called to update the enclosing scope. See comment
// above the callsite in BytecodeEmitter::emitFunction.
MOZ_ASSERT_IF(sourceObject_, sourceObject_ == sourceObject && enclosingScope_);
MOZ_ASSERT_IF(!sourceObject_, !enclosingScope_);
enclosingScope_ = enclosingScope;
sourceObject_ = sourceObject;
@ -4396,7 +4399,7 @@ LazyScript::Create(ExclusiveContext* cx, HandleFunction fun,
// Set the enclosing scope of the lazy function, this would later be
// used to define the environment when the function would be used.
MOZ_ASSERT(!res->sourceObject());
res->setParent(enclosingScope, &sourceObjectScript->scriptSourceUnwrap());
res->setEnclosingScopeAndSource(enclosingScope, &sourceObjectScript->scriptSourceUnwrap());
MOZ_ASSERT(!res->hasScript());
if (script)

View File

@ -2272,7 +2272,7 @@ class LazyScript : public gc::TenuredCell
return (p_.version == JS_BIT(8) - 1) ? JSVERSION_UNKNOWN : JSVersion(p_.version);
}
void setParent(JSObject* enclosingScope, ScriptSourceObject* sourceObject);
void setEnclosingScopeAndSource(JSObject* enclosingScope, ScriptSourceObject* sourceObject);
uint32_t numFreeVariables() const {
return p_.numFreeVariables;