diff --git a/js/src/frontend/BytecodeEmitter.h b/js/src/frontend/BytecodeEmitter.h index f7ebab45d352..fb29d7f0debe 100644 --- a/js/src/frontend/BytecodeEmitter.h +++ b/js/src/frontend/BytecodeEmitter.h @@ -349,6 +349,10 @@ struct MOZ_STACK_CLASS BytecodeEmitter { Scope* outermostScope() const { return scopeList.vector[0]; } Scope* innermostScope() const; + Scope* bodyScope() const { + MOZ_ASSERT(bodyScopeIndex < scopeList.length()); + return scopeList.vector[bodyScopeIndex]; + } MOZ_ALWAYS_INLINE MOZ_MUST_USE bool makeAtomIndex(JSAtom* atom, uint32_t* indexp) { diff --git a/js/src/vm/JSScript.cpp b/js/src/vm/JSScript.cpp index 77d2eaa8a98c..be37c2814533 100644 --- a/js/src/vm/JSScript.cpp +++ b/js/src/vm/JSScript.cpp @@ -3452,6 +3452,17 @@ static void InitAtomMap(frontend::AtomIndexMap& indices, GCPtrAtom* atoms) { } } +static bool HasAnyAliasedFormal(frontend::BytecodeEmitter* bce) { + PositionalFormalParameterIter fi(bce->bodyScope()); + for (; fi; fi++) { + // Check if the formal parameter is closed over. + if (fi.closedOver()) { + return true; + } + } + return false; +} + /* static */ void JSScript::initFromFunctionBox(HandleScript script, frontend::FunctionBox* funbox) { @@ -3489,12 +3500,6 @@ void JSScript::initFromFunctionBox(HandleScript script, script->setFlag(ImmutableFlags::IsAsync, funbox->isAsync()); script->setFlag(ImmutableFlags::HasRest, funbox->hasRest()); - PositionalFormalParameterIter fi(script); - while (fi && !fi.closedOver()) { - fi++; - } - script->setFlag(ImmutableFlags::FunHasAnyAliasedFormal, !!fi); - script->setFlag(ImmutableFlags::HasInnerFunctions, funbox->hasInnerFunctions()); @@ -3586,6 +3591,8 @@ bool JSScript::fullyInitFromEmitter(JSContext* cx, HandleScript script, script->bodyScopeIndex_ = bce->bodyScopeIndex; script->setFlag(ImmutableFlags::HasNonSyntacticScope, bce->outermostScope()->hasOnChain(ScopeKind::NonSyntactic)); + script->setFlag(ImmutableFlags::FunHasAnyAliasedFormal, + HasAnyAliasedFormal(bce)); // There shouldn't be any fallible operation after initFromFunctionBox, // JSFunction::hasUncompletedScript relies on the fact that the existence diff --git a/js/src/vm/Scope.cpp b/js/src/vm/Scope.cpp index 204fda20cb65..5617379470fa 100644 --- a/js/src/vm/Scope.cpp +++ b/js/src/vm/Scope.cpp @@ -1577,15 +1577,18 @@ void BindingIter::init(WasmFunctionScope::Data& data) { data.trailingNames.start(), data.length); } -PositionalFormalParameterIter::PositionalFormalParameterIter(JSScript* script) - : BindingIter(script) { +PositionalFormalParameterIter::PositionalFormalParameterIter(Scope* scope) + : BindingIter(scope) { // Reinit with flags = 0, i.e., iterate over all positional parameters. - if (script->bodyScope()->is()) { - init(script->bodyScope()->as().data(), /* flags = */ 0); + if (scope->is()) { + init(scope->as().data(), /* flags = */ 0); } settle(); } +PositionalFormalParameterIter::PositionalFormalParameterIter(JSScript* script) + : PositionalFormalParameterIter(script->bodyScope()) { } + void js::DumpBindings(JSContext* cx, Scope* scopeArg) { RootedScope scope(cx, scopeArg); for (Rooted bi(cx, BindingIter(scope)); bi; bi++) { diff --git a/js/src/vm/Scope.h b/js/src/vm/Scope.h index eaef8cdaa4fe..c082cc6ba70f 100644 --- a/js/src/vm/Scope.h +++ b/js/src/vm/Scope.h @@ -1322,6 +1322,7 @@ class PositionalFormalParameterIter : public BindingIter { } public: + explicit PositionalFormalParameterIter(Scope* scope); explicit PositionalFormalParameterIter(JSScript* script); void operator++(int) {