Closed github-actions[bot] closed 1 year ago
/js/src/frontend/CompilationStencil.h
/js/src/frontend/Stencil.cpp
--- 343425669f57e2e8c8a0115847ad5f4da36615d3/js/src/frontend/CompilationStencil.h +++ 047eb1db59fbccacedde0642173da9c323131805/js/src/frontend/CompilationStencil.h @@ -367,19 +367,19 @@ struct InputName { // Compare an InputName, which is not yet interned, with `other` is either an // interned name or a well-known or static string. // // The `otherCached` argument should be a reference to a JSAtom*, initialized // to nullptr, which is used to cache the JSAtom representation of the `other` // argument if needed. If a different `other` parameter is provided, the // `otherCached` argument should be reset to nullptr. - bool isEqualTo(JSContext* cx, FrontendContext* fc, - ParserAtomsTable& parserAtoms, CompilationAtomCache& atomCache, - TaggedParserAtomIndex other, JSAtom** otherCached) const; + bool isEqualTo(FrontendContext* fc, ParserAtomsTable& parserAtoms, + CompilationAtomCache& atomCache, TaggedParserAtomIndex other, + JSAtom** otherCached) const; bool isNull() const { return variant_.match( [](JSAtom* ptr) { return !ptr; }, [](const NameStencilRef& ref) { return !ref.atomIndex_; }); } }; @@ -488,36 +488,35 @@ struct ScopeContext { bool init(JSContext* cx, FrontendContext* fc, CompilationInput& input, ParserAtomsTable& parserAtoms, ScopeBindingCache* scopeCache, InheritThis inheritThis, JSObject* enclosingEnv); mozilla::Maybe<EnclosingLexicalBindingKind> lookupLexicalBindingInEnclosingScope(TaggedParserAtomIndex name); - NameLocation searchInEnclosingScope(JSContext* cx, FrontendContext* fc, + NameLocation searchInEnclosingScope(FrontendContext* fc, CompilationInput& input, ParserAtomsTable& parserAtoms, TaggedParserAtomIndex name); bool effectiveScopePrivateFieldCacheHas(TaggedParserAtomIndex name); mozilla::Maybe<NameLocation> getPrivateFieldLocation( TaggedParserAtomIndex name); private: void computeThisBinding(const InputScope& scope); void computeThisEnvironment(const InputScope& enclosingScope); void computeInScope(const InputScope& enclosingScope); void cacheEnclosingScope(const InputScope& enclosingScope); - NameLocation searchInEnclosingScopeWithCache(JSContext* cx, - FrontendContext* fc, + NameLocation searchInEnclosingScopeWithCache(FrontendContext* fc, CompilationInput& input, ParserAtomsTable& parserAtoms, TaggedParserAtomIndex name); - NameLocation searchInEnclosingScopeNoCache(JSContext* cx, FrontendContext* fc, + NameLocation searchInEnclosingScopeNoCache(FrontendContext* fc, CompilationInput& input, ParserAtomsTable& parserAtoms, TaggedParserAtomIndex name); InputScope determineEffectiveScope(InputScope& scope, JSObject* environment); bool cachePrivateFieldsForEval(JSContext* cx, FrontendContext* fc, CompilationInput& input,
--- 343425669f57e2e8c8a0115847ad5f4da36615d3/js/src/frontend/Stencil.cpp +++ 047eb1db59fbccacedde0642173da9c323131805/js/src/frontend/Stencil.cpp @@ -103,27 +103,31 @@ TaggedParserAtomIndex InputName::internI return parserAtoms.internJSAtom(cx, fc, atomCache, ptr); }, [&](NameStencilRef& ref) -> TaggedParserAtomIndex { return parserAtoms.internExternalParserAtomIndex(fc, ref.context_, ref.atomIndex_); }); } -bool InputName::isEqualTo(JSContext* cx, FrontendContext* fc, - ParserAtomsTable& parserAtoms, +bool InputName::isEqualTo(FrontendContext* fc, ParserAtomsTable& parserAtoms, CompilationAtomCache& atomCache, TaggedParserAtomIndex other, JSAtom** otherCached) const { return variant_.match( [&](const JSAtom* ptr) -> bool { if (ptr->hash() != parserAtoms.hash(other)) { return false; } + // JSAtom variant is used only on the main thread delazification, + // where JSContext is always available. + JSContext* cx = fc->maybeCurrentJSContext(); + MOZ_ASSERT(cx); + if (!*otherCached) { // TODO-Stencil: // Here, we convert our name into a JSAtom*, and hard-crash on failure // to allocate. This conversion should not be required as we should be // able to iterate up snapshotted scope chains that use parser atoms. // // This will be fixed when the enclosing scopes are snapshotted. // @@ -139,21 +143,20 @@ bool InputName::isEqualTo(JSContext* cx, return ptr == *otherCached; }, [&](const NameStencilRef& ref) -> bool { return parserAtoms.isEqualToExternalParserAtomIndex(other, ref.context_, ref.atomIndex_); }); } -GenericAtom::GenericAtom(JSContext* cx, FrontendContext* fc, - ParserAtomsTable& parserAtoms, +GenericAtom::GenericAtom(FrontendContext* fc, ParserAtomsTable& parserAtoms, CompilationAtomCache& atomCache, TaggedParserAtomIndex index) - : ref(EmitterName(cx, fc, parserAtoms, atomCache, index)) { + : ref(EmitterName(fc, parserAtoms, atomCache, index)) { hash = parserAtoms.hash(index); } GenericAtom::GenericAtom(const CompilationStencil& context, TaggedParserAtomIndex index) : ref(StencilName{context, index}) { if (index.isParserAtomIndex()) { ParserAtom* atom = context.parserAtomData[index.toParserAtomIndex()]; @@ -171,29 +174,33 @@ BindingHasher<TaggedParserAtomIndex>::Lo : keyStencil(scope_ref.context_), other(other) {} bool GenericAtom::operator==(const GenericAtom& other) const { return ref.match( [&other](const EmitterName& name) -> bool { return other.ref.match( [&name](const EmitterName& other) -> bool { // We never have multiple Emitter context at the same time. - MOZ_ASSERT(name.cx == other.cx); + MOZ_ASSERT(name.fc == other.fc); MOZ_ASSERT(&name.parserAtoms == &other.parserAtoms); MOZ_ASSERT(&name.atomCache == &other.atomCache); return name.index == other.index; }, [&name](const StencilName& other) -> bool { return name.parserAtoms.isEqualToExternalParserAtomIndex( name.index, other.stencil, other.index); }, [&name](JSAtom* other) -> bool { + // JSAtom variant is used only on the main thread delazification, + // where JSContext is always available. + JSContext* cx = name.fc->maybeCurrentJSContext(); + MOZ_ASSERT(cx); AutoEnterOOMUnsafeRegion oomUnsafe; JSAtom* namePtr = name.parserAtoms.toJSAtom( - name.cx, name.fc, name.index, name.atomCache); + cx, name.fc, name.index, name.atomCache); if (!namePtr) { oomUnsafe.crash("GenericAtom(EmitterName == JSAtom*)"); } return namePtr == other; }); }, [&other](const StencilName& name) -> bool { return other.ref.match( @@ -216,19 +223,23 @@ bool GenericAtom::operator==(const Gener [](JSAtom* other) -> bool { MOZ_CRASH("Never used."); return false; }); }, [&other](JSAtom* name) -> bool { return other.ref.match( [&name](const EmitterName& other) -> bool { + // JSAtom variant is used only on the main thread delazification, + // where JSContext is always available. + JSContext* cx = other.fc->maybeCurrentJSContext(); + MOZ_ASSERT(cx); AutoEnterOOMUnsafeRegion oomUnsafe; JSAtom* otherPtr = other.parserAtoms.toJSAtom( - other.cx, other.fc, other.index, other.atomCache); + cx, other.fc, other.index, other.atomCache); if (!otherPtr) { oomUnsafe.crash("GenericAtom(JSAtom* == EmitterName)"); } return name == otherPtr; }, [](const StencilName& other) -> bool { MOZ_CRASH("Never used."); return false; @@ -939,40 +950,40 @@ bool ScopeContext::cachePrivateFieldsFor // optimized out). hops++; } return true; } #ifdef DEBUG -static bool NameIsOnEnvironment(JSContext* cx, FrontendContext* fc, +static bool NameIsOnEnvironment(FrontendContext* fc, ParserAtomsTable& parserAtoms, CompilationAtomCache& atomCache, InputScope& scope, TaggedParserAtomIndex name) { JSAtom* jsname = nullptr; return scope.match([&](auto& scope_ref) { for (auto bi = InputBindingIter(scope_ref); bi; bi++) { // If found, the name must already be on the environment or an import, // or else there is a bug in the closed-over name analysis in the // Parser. InputName binding(scope_ref, bi.name()); - if (binding.isEqualTo(cx, fc, parserAtoms, atomCache, name, &jsname)) { + if (binding.isEqualTo(fc, parserAtoms, atomCache, name, &jsname)) { BindingLocation::Kind kind = bi.location().kind(); if (bi.hasArgumentSlot()) { // The following is equivalent to // functionScope.script()->functionAllowsParameterRedeclaration() if (scope.hasMappedArgsObj()) { // Check for duplicate positional formal parameters. using InputBindingIter = decltype(bi); for (InputBindingIter bi2(bi); bi2 && bi2.hasArgumentSlot(); bi2++) { InputName binding2(scope_ref, bi2.name()); - if (binding2.isEqualTo(cx, fc, parserAtoms, atomCache, name, + if (binding2.isEqualTo(fc, parserAtoms, atomCache, name, &jsname)) { kind = bi2.location().kind(); } } } } return kind == BindingLocation::Kind::Global || @@ -982,60 +993,59 @@ static bool NameIsOnEnvironment(JSContex } // If not found, assume it's on the global or dynamically accessed. return true; }); } #endif -NameLocation ScopeContext::searchInEnclosingScope(JSContext* cx, - FrontendContext* fc, +NameLocation ScopeContext::searchInEnclosingScope(FrontendContext* fc, CompilationInput& input, ParserAtomsTable& parserAtoms, TaggedParserAtomIndex name) { MOZ_ASSERT(input.target == CompilationInput::CompilationTarget::Delazification || input.target == CompilationInput::CompilationTarget::Eval); MOZ_ASSERT(scopeCache); if (scopeCacheGen != scopeCache->getCurrentGeneration()) { - return searchInEnclosingScopeNoCache(cx, fc, input, parserAtoms, name); + return searchInEnclosingScopeNoCache(fc, input, parserAtoms, name); } #ifdef DEBUG // Catch assertion failures in the NoCache variant before looking at the // cached content. NameLocation expect = - searchInEnclosingScopeNoCache(cx, fc, input, parserAtoms, name); + searchInEnclosingScopeNoCache(fc, input, parserAtoms, name); #endif NameLocation found = - searchInEnclosingScopeWithCache(cx, fc, input, parserAtoms, name); + searchInEnclosingScopeWithCache(fc, input, parserAtoms, name); MOZ_ASSERT(expect == found); return found; } NameLocation ScopeContext::searchInEnclosingScopeWithCache( - JSContext* cx, FrontendContext* fc, CompilationInput& input, - ParserAtomsTable& parserAtoms, TaggedParserAtomIndex name) { + FrontendContext* fc, CompilationInput& input, ParserAtomsTable& parserAtoms, + TaggedParserAtomIndex name) { MOZ_ASSERT(input.target == CompilationInput::CompilationTarget::Delazification || input.target == CompilationInput::CompilationTarget::Eval); // Generic atom of the looked up name. - GenericAtom genName(cx, fc, parserAtoms, input.atomCache, name); + GenericAtom genName(fc, parserAtoms, input.atomCache, name); mozilla::Maybe<NameLocation> found; // Number of enclosing scope we walked over. uint8_t hops = 0; for (InputScopeIter si(input.enclosingScope); si; si++) { - MOZ_ASSERT(NameIsOnEnvironment(cx, fc, parserAtoms, input.atomCache, - si.scope(), name)); + MOZ_ASSERT(NameIsOnEnvironment(fc, parserAtoms, input.atomCache, si.scope(), + name)); // If the result happens to be in the cached content of the scope that we // are iterating over, then return it. si.scope().match([&](auto& scope_ref) { using BindingMapPtr = decltype(scopeCache->lookupScope(scope_ref, scopeCacheGen)); BindingMapPtr bindingMapPtr = scopeCache->lookupScope(scope_ref, scopeCacheGen); @@ -1078,47 +1088,47 @@ NameLocation ScopeContext::searchInEnclo hops++; } } MOZ_CRASH("Malformed scope chain"); } NameLocation ScopeContext::searchInEnclosingScopeNoCache( - JSContext* cx, FrontendContext* fc, CompilationInput& input, - ParserAtomsTable& parserAtoms, TaggedParserAtomIndex name) { + FrontendContext* fc, CompilationInput& input, ParserAtomsTable& parserAtoms, + TaggedParserAtomIndex name) { MOZ_ASSERT(input.target == CompilationInput::CompilationTarget::Delazification || input.target == CompilationInput::CompilationTarget::Eval); // Cached JSAtom equivalent of the TaggedParserAtomIndex `name` argument. JSAtom* jsname = nullptr; // NameLocation which contains relative locations to access `name`. mozilla::Maybe<NameLocation> result; // Number of enclosing scoep we walked over. uint8_t hops = 0; for (InputScopeIter si(input.enclosingScope); si; si++) { - MOZ_ASSERT(NameIsOnEnvironment(cx, fc, parserAtoms, input.atomCache, - si.scope(), name)); + MOZ_ASSERT(NameIsOnEnvironment(fc, parserAtoms, input.atomCache, si.scope(), + name)); bool hasEnv = si.hasSyntacticEnvironment(); switch (si.kind()) { case ScopeKind::Function: if (hasEnv) { if (si.scope().funHasExtensibleScope()) { return NameLocation::Dynamic(); } si.scope().match([&](auto& scope_ref) { for (auto bi = InputBindingIter(scope_ref); bi; bi++) { InputName binding(scope_ref, bi.name()); - if (!binding.isEqualTo(cx, fc, parserAtoms, input.atomCache, name, + if (!binding.isEqualTo(fc, parserAtoms, input.atomCache, name, &jsname)) { continue; } BindingLocation bindLoc = bi.location(); // hasMappedArgsObj == script.functionAllowsParameterRedeclaration if (bi.hasArgumentSlot() && si.scope().hasMappedArgsObj()) { // Check for duplicate positional formal parameters. @@ -1148,17 +1158,17 @@ NameLocation ScopeContext::searchInEnclo case ScopeKind::SimpleCatch: case ScopeKind::Catch: case ScopeKind::FunctionLexical: case ScopeKind::ClassBody: if (hasEnv) { si.scope().match([&](auto& scope_ref) { for (auto bi = InputBindingIter(scope_ref); bi; bi++) { InputName binding(scope_ref, bi.name()); - if (!binding.isEqualTo(cx, fc, parserAtoms, input.atomCache, name, + if (!binding.isEqualTo(fc, parserAtoms, input.atomCache, name, &jsname)) { continue; } // The name must already have been marked as closed // over. If this assertion is hit, there is a bug in the // name analysis. BindingLocation bindLoc = bi.location(); @@ -1174,17 +1184,17 @@ NameLocation ScopeContext::searchInEnclo case ScopeKind::Module: // This case is used only when delazifying a function inside // module. // Initial compilation of module doesn't have enlcosing scope. if (hasEnv) { si.scope().match([&](auto& scope_ref) { for (auto bi = InputBindingIter(scope_ref); bi; bi++) { InputName binding(scope_ref, bi.name()); - if (!binding.isEqualTo(cx, fc, parserAtoms, input.atomCache, name, + if (!binding.isEqualTo(fc, parserAtoms, input.atomCache, name, &jsname)) { continue; } BindingLocation bindLoc = bi.location(); // Imports are on the environment but are indirect // bindings and must be accessed dynamically instead of
Files
/js/src/frontend/CompilationStencil.h
/js/src/frontend/Stencil.cpp
Changesets
Diffs
/js/src/frontend/CompilationStencil.h
/js/src/frontend/Stencil.cpp