From 9693552c5ca6694bd9b60917a98bda10f7aea158 Mon Sep 17 00:00:00 2001 From: Job Bautista Date: Sat, 6 May 2023 15:15:33 +0800 Subject: [PATCH 1/6] Issue #2232 - Parse exported async functions. --- js/src/frontend/Parser.cpp | 19 +++++++++++++++++-- js/src/frontend/Parser.h | 3 ++- 2 files changed, 19 insertions(+), 3 deletions(-) diff --git a/js/src/frontend/Parser.cpp b/js/src/frontend/Parser.cpp index a33b3d0d90..841eb5f096 100644 --- a/js/src/frontend/Parser.cpp +++ b/js/src/frontend/Parser.cpp @@ -5778,14 +5778,15 @@ Parser::exportVariableStatement(uint32_t begin) template typename ParseHandler::UnaryNodeType -Parser::exportFunctionDeclaration(uint32_t begin) +Parser::exportFunctionDeclaration(uint32_t begin, + FunctionAsyncKind asyncKind /* = SyncFunction */) { if (!abortIfSyntaxParser()) return null(); MOZ_ASSERT(tokenStream.isCurrentTokenType(TOK_FUNCTION)); - Node kid = functionStmt(pos().begin, YieldIsKeyword, NameRequired); + Node kid = functionStmt(pos().begin, YieldIsKeyword, NameRequired, asyncKind); if (!kid) return null(); @@ -6008,6 +6009,20 @@ Parser::exportDeclaration() case TOK_FUNCTION: return exportFunctionDeclaration(begin); + case TOK_ASYNC: { + TokenKind nextSameLine = TOK_EOF; + if (!tokenStream.peekTokenSameLine(&nextSameLine)) + return null(); + + if (nextSameLine == TOK_FUNCTION) { + tokenStream.consumeKnownToken(TOK_FUNCTION); + return exportFunctionDeclaration(begin, AsyncFunction); + } + + error(JSMSG_DECLARATION_AFTER_EXPORT); + return null(); + } + case TOK_CLASS: return exportClassDeclaration(begin); diff --git a/js/src/frontend/Parser.h b/js/src/frontend/Parser.h index 6976487c50..1819873308 100644 --- a/js/src/frontend/Parser.h +++ b/js/src/frontend/Parser.h @@ -1337,7 +1337,8 @@ FOR_EACH_PARSENODE_SUBCLASS(DECLARE_TYPE) BinaryNodeType exportBatch(uint32_t begin); bool checkLocalExportNames(ListNodeType node); Node exportClause(uint32_t begin); - UnaryNodeType exportFunctionDeclaration(uint32_t begin); + UnaryNodeType exportFunctionDeclaration(uint32_t begin, + FunctionAsyncKind asyncKind = SyncFunction); UnaryNodeType exportVariableStatement(uint32_t begin); UnaryNodeType exportClassDeclaration(uint32_t begin); UnaryNodeType exportLexicalDeclaration(uint32_t begin, DeclarationKind kind); From ab1c0a384d23824e842d3c88c68011104f8be2e9 Mon Sep 17 00:00:00 2001 From: FranklinDM Date: Sun, 7 May 2023 00:43:59 +0800 Subject: [PATCH 2/6] Issue #2234 - Part 1: Create async function wrapper when instantiating module functions This excludes the change that removes "excessive" rooting from the Lambda* methods in Interpreter.cpp. Based on https://bugzilla.mozilla.org/show_bug.cgi?id=1382306 --- js/src/builtin/ModuleObject.cpp | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/js/src/builtin/ModuleObject.cpp b/js/src/builtin/ModuleObject.cpp index 194959cf31..3fc195499f 100644 --- a/js/src/builtin/ModuleObject.cpp +++ b/js/src/builtin/ModuleObject.cpp @@ -12,6 +12,8 @@ #include "gc/Policy.h" #include "gc/Tracer.h" #include "vm/SelfHosting.h" +#include "vm/AsyncFunction.h" +#include "vm/AsyncIteration.h" #include "jsobjinlines.h" #include "jsscriptinlines.h" @@ -954,15 +956,24 @@ ModuleObject::instantiateFunctionDeclarations(JSContext* cx, HandleModuleObject RootedModuleEnvironmentObject env(cx, &self->initialEnvironment()); RootedFunction fun(cx); + RootedObject obj(cx); RootedValue value(cx); for (const auto& funDecl : *funDecls) { fun = funDecl.fun; - RootedObject obj(cx, Lambda(cx, fun, env)); + obj = Lambda(cx, fun, env); if (!obj) return false; - value = ObjectValue(*fun); + if (fun->isAsync()) { + if (fun->isStarGenerator()) { + obj = WrapAsyncGenerator(cx, obj.as()); + } else { + obj = WrapAsyncFunction(cx, obj.as()); + } + } + + value = ObjectValue(*obj); if (!SetProperty(cx, env, funDecl.name->asPropertyName(), value)) return false; } From e52da4707d2501ad0885449502cc844062238e3b Mon Sep 17 00:00:00 2001 From: FranklinDM Date: Sun, 7 May 2023 00:57:41 +0800 Subject: [PATCH 3/6] Issue #2234 - Part 2: Ensure that the created async function wrapper is valid This excludes the GC-related changes (cell pointer asserts) since we don't have them. This bug should be revisited if we'd ever plan on porting those asserts over. Partially based on https://bugzilla.mozilla.org/show_bug.cgi?id=1402649 --- js/src/builtin/ModuleObject.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/js/src/builtin/ModuleObject.cpp b/js/src/builtin/ModuleObject.cpp index 3fc195499f..dd03017fc0 100644 --- a/js/src/builtin/ModuleObject.cpp +++ b/js/src/builtin/ModuleObject.cpp @@ -973,6 +973,9 @@ ModuleObject::instantiateFunctionDeclarations(JSContext* cx, HandleModuleObject } } + if (!obj) + return false; + value = ObjectValue(*obj); if (!SetProperty(cx, env, funDecl.name->asPropertyName(), value)) return false; From 2d6c419661d88ba73fef012329947f76c987225f Mon Sep 17 00:00:00 2001 From: FranklinDM Date: Sun, 7 May 2023 00:58:34 +0800 Subject: [PATCH 4/6] Issue #2234 - Part 3: Update tests Based on https://bugzilla.mozilla.org/show_bug.cgi?id=1402649 and https://bugzilla.mozilla.org/show_bug.cgi?id=1382306 --- js/src/jit-test/tests/modules/bug-1402649.js | 15 +++++++++++++++ .../async-function-declaration-in-modules.js | 13 +++++++++++++ .../async-generator-declaration-in-modules.js | 13 +++++++++++++ js/src/tests/ecma_2018/AsyncGenerators/browser.js | 0 js/src/tests/ecma_2018/AsyncGenerators/shell.js | 0 js/src/tests/ecma_2018/browser.js | 0 js/src/tests/ecma_2018/shell.js | 0 7 files changed, 41 insertions(+) create mode 100644 js/src/jit-test/tests/modules/bug-1402649.js create mode 100644 js/src/tests/ecma_2017/AsyncFunctions/async-function-declaration-in-modules.js create mode 100644 js/src/tests/ecma_2018/AsyncGenerators/async-generator-declaration-in-modules.js create mode 100644 js/src/tests/ecma_2018/AsyncGenerators/browser.js create mode 100644 js/src/tests/ecma_2018/AsyncGenerators/shell.js create mode 100644 js/src/tests/ecma_2018/browser.js create mode 100644 js/src/tests/ecma_2018/shell.js diff --git a/js/src/jit-test/tests/modules/bug-1402649.js b/js/src/jit-test/tests/modules/bug-1402649.js new file mode 100644 index 0000000000..2e5487210b --- /dev/null +++ b/js/src/jit-test/tests/modules/bug-1402649.js @@ -0,0 +1,15 @@ +if (!('oomTest' in this)) + quit(); + +loadFile(` +function parseAndEvaluate(source) { + let m = parseModule(source); + m.declarationInstantiation(); +} +parseAndEvaluate("async function a() { await 2 + 3; }") +`); +function loadFile(lfVarx) { + oomTest(function() { + eval(lfVarx); + }); +} diff --git a/js/src/tests/ecma_2017/AsyncFunctions/async-function-declaration-in-modules.js b/js/src/tests/ecma_2017/AsyncFunctions/async-function-declaration-in-modules.js new file mode 100644 index 0000000000..41cc37bf33 --- /dev/null +++ b/js/src/tests/ecma_2017/AsyncFunctions/async-function-declaration-in-modules.js @@ -0,0 +1,13 @@ +// |reftest| module + +async function f() { + return "success"; +} + +var AsyncFunction = (async function(){}).constructor; + +assertEq(f instanceof AsyncFunction, true); + +f().then(v => { + reportCompare("success", v); +}); diff --git a/js/src/tests/ecma_2018/AsyncGenerators/async-generator-declaration-in-modules.js b/js/src/tests/ecma_2018/AsyncGenerators/async-generator-declaration-in-modules.js new file mode 100644 index 0000000000..6cac859579 --- /dev/null +++ b/js/src/tests/ecma_2018/AsyncGenerators/async-generator-declaration-in-modules.js @@ -0,0 +1,13 @@ +// |reftest| module skip-if(release_or_beta) + +async function* f() { + return "success"; +} + +var AsyncGenerator = (async function*(){}).constructor; + +assertEq(f instanceof AsyncGenerator, true); + +f().next().then(v => { + reportCompare("success", v.value); +}); diff --git a/js/src/tests/ecma_2018/AsyncGenerators/browser.js b/js/src/tests/ecma_2018/AsyncGenerators/browser.js new file mode 100644 index 0000000000..e69de29bb2 diff --git a/js/src/tests/ecma_2018/AsyncGenerators/shell.js b/js/src/tests/ecma_2018/AsyncGenerators/shell.js new file mode 100644 index 0000000000..e69de29bb2 diff --git a/js/src/tests/ecma_2018/browser.js b/js/src/tests/ecma_2018/browser.js new file mode 100644 index 0000000000..e69de29bb2 diff --git a/js/src/tests/ecma_2018/shell.js b/js/src/tests/ecma_2018/shell.js new file mode 100644 index 0000000000..e69de29bb2 From 1c70f64e7cacb2fabb10f77170564a355d408a5a Mon Sep 17 00:00:00 2001 From: Brian Smith Date: Mon, 8 May 2023 18:28:18 -0500 Subject: [PATCH 5/6] Issue #2236 - Fix import.meta module error in lambdas by moving parseGoal() into SharedContext. Based on https://bugzilla.mozilla.org/show_bug.cgi?id=1604792 Also remove ParseGoal being passed through Parser introduced in #1691 Part 2. --- js/src/builtin/ReflectParse.cpp | 2 +- js/src/frontend/BytecodeCompiler.cpp | 24 +++++++++++------------- js/src/frontend/Parser.cpp | 23 ++++++++++++++--------- js/src/frontend/Parser.h | 8 +++----- js/src/frontend/SharedContext.h | 8 +++++++- js/src/jsapi.cpp | 3 +-- js/src/jsscript.cpp | 10 +++++++--- js/src/jsscript.h | 21 ++++++++++++++++----- js/src/shell/js.cpp | 6 ++---- js/src/vm/Debugger.cpp | 3 +-- 10 files changed, 63 insertions(+), 45 deletions(-) diff --git a/js/src/builtin/ReflectParse.cpp b/js/src/builtin/ReflectParse.cpp index 0205887ff6..f0b2001422 100644 --- a/js/src/builtin/ReflectParse.cpp +++ b/js/src/builtin/ReflectParse.cpp @@ -4055,7 +4055,7 @@ reflect_parse(JSContext* cx, uint32_t argc, Value* vp) return false; Parser parser(cx, cx->tempLifoAlloc(), options, chars.begin().get(), chars.length(), /* foldConstants = */ false, usedNames, - nullptr, nullptr, target); + nullptr, nullptr); if (!parser.checkOptions()) return false; diff --git a/js/src/frontend/BytecodeCompiler.cpp b/js/src/frontend/BytecodeCompiler.cpp index 7f5b705f92..cdb386f249 100644 --- a/js/src/frontend/BytecodeCompiler.cpp +++ b/js/src/frontend/BytecodeCompiler.cpp @@ -74,9 +74,8 @@ class MOZ_STACK_CLASS BytecodeCompiler bool createScriptSource(Maybe parameterListEnd); bool maybeCompressSource(); bool canLazilyParse(); - bool createParser(ParseGoal goal); - bool createSourceAndParser(ParseGoal goal, - Maybe parameterListEnd = Nothing()); + bool createParser(); + bool createSourceAndParser(Maybe parameterListEnd = Nothing()); // If toString{Start,End} are not explicitly passed, assume the script's // offsets in the source used to parse it are the same as what should be @@ -213,7 +212,7 @@ BytecodeCompiler::canLazilyParse() } bool -BytecodeCompiler::createParser(ParseGoal goal) +BytecodeCompiler::createParser() { usedNames.emplace(cx); if (!usedNames->init()) @@ -222,14 +221,14 @@ BytecodeCompiler::createParser(ParseGoal goal) if (canLazilyParse()) { syntaxParser.emplace(cx, alloc, options, sourceBuffer.get(), sourceBuffer.length(), /* foldConstants = */ false, *usedNames, - (Parser*) nullptr, (LazyScript*) nullptr, goal); + (Parser*) nullptr, (LazyScript*) nullptr); if (!syntaxParser->checkOptions()) return false; } parser.emplace(cx, alloc, options, sourceBuffer.get(), sourceBuffer.length(), - /* foldConstants = */ true, *usedNames, syntaxParser.ptrOr(nullptr), nullptr, goal); + /* foldConstants = */ true, *usedNames, syntaxParser.ptrOr(nullptr), nullptr); parser->sct = sourceCompressor; parser->ss = scriptSource; if (!parser->checkOptions()) @@ -240,12 +239,11 @@ BytecodeCompiler::createParser(ParseGoal goal) } bool -BytecodeCompiler::createSourceAndParser(ParseGoal goal, - Maybe parameterListEnd /* = Nothing() */) +BytecodeCompiler::createSourceAndParser(Maybe parameterListEnd /* = Nothing() */) { return createScriptSource(parameterListEnd) && maybeCompressSource() && - createParser(goal); + createParser(); } bool @@ -324,7 +322,7 @@ BytecodeCompiler::maybeCompleteCompressSource() JSScript* BytecodeCompiler::compileScript(HandleObject environment, SharedContext* sc) { - if (!createSourceAndParser(ParseGoal::Script)) + if (!createSourceAndParser()) return nullptr; if (!createScript()) @@ -394,7 +392,7 @@ BytecodeCompiler::compileEvalScript(HandleObject environment, HandleScope enclos ModuleObject* BytecodeCompiler::compileModule() { - if (!createSourceAndParser(ParseGoal::Module)) + if (!createSourceAndParser()) return nullptr; Rooted module(cx, ModuleObject::create(cx)); @@ -451,7 +449,7 @@ BytecodeCompiler::compileStandaloneFunction(MutableHandleFunction fun, MOZ_ASSERT(fun); MOZ_ASSERT(fun->isTenured()); - if (!createSourceAndParser(ParseGoal::Script, parameterListEnd)) + if (!createSourceAndParser(parameterListEnd)) return false; // Speculatively parse using the default directives implied by the context. @@ -651,7 +649,7 @@ frontend::CompileLazyFunction(JSContext* cx, Handle lazy, const cha if (!usedNames.init()) return false; Parser parser(cx, cx->tempLifoAlloc(), options, chars, length, - /* foldConstants = */ true, usedNames, nullptr, lazy, lazy->parseGoal()); + /* foldConstants = */ true, usedNames, nullptr, lazy); if (!parser.checkOptions()) return false; diff --git a/js/src/frontend/Parser.cpp b/js/src/frontend/Parser.cpp index 841eb5f096..d617941503 100644 --- a/js/src/frontend/Parser.cpp +++ b/js/src/frontend/Parser.cpp @@ -491,6 +491,9 @@ FunctionBox::initFromLazyFunction() setDerivedClassConstructor(); if (fun->lazyScript()->needsHomeObject()) setNeedsHomeObject(); + if (fun->lazyScript()->hasModuleGoal()) { + setHasModuleGoal(); + } enclosingScope_ = fun->lazyScript()->enclosingScope(); initWithEnclosingScope(enclosingScope_); } @@ -557,6 +560,9 @@ FunctionBox::initWithEnclosingParseContext(ParseContext* enclosing, FunctionSynt } } + // We inherit the parse goal from our top-level. + hasModuleGoal_ = sc->hasModuleGoal(); + if (sc->inWith()) { inWith_ = true; } else { @@ -787,8 +793,7 @@ ParserBase::ParserBase(ExclusiveContext* cx, LifoAlloc& alloc, bool foldConstants, UsedNameTracker& usedNames, Parser* syntaxParser, - LazyScript* lazyOuterFunction, - ParseGoal parseGoal) + LazyScript* lazyOuterFunction) : context(cx), alloc(alloc), tokenStream(cx, options, chars, length, thisForCtor()), @@ -804,8 +809,7 @@ ParserBase::ParserBase(ExclusiveContext* cx, LifoAlloc& alloc, #endif abortedSyntaxParse(false), isUnexpectedEOF_(false), - awaitHandling_(AwaitIsName), - parseGoal_(uint8_t(parseGoal)) + awaitHandling_(AwaitIsName) { cx->perThreadData->frontendCollectionPool.addActiveCompilation(); tempPoolMark = alloc.mark(); @@ -832,10 +836,9 @@ Parser::Parser(ExclusiveContext* cx, LifoAlloc& alloc, bool foldConstants, UsedNameTracker& usedNames, Parser* syntaxParser, - LazyScript* lazyOuterFunction, - ParseGoal parseGoal) + LazyScript* lazyOuterFunction) : ParserBase(cx, alloc, options, chars, length, foldConstants, usedNames, syntaxParser, - lazyOuterFunction, parseGoal), + lazyOuterFunction), AutoGCRooter(cx, PARSER), handler(cx, alloc, tokenStream, syntaxParser, lazyOuterFunction) { @@ -949,6 +952,7 @@ ModuleSharedContext::ModuleSharedContext(ExclusiveContext* cx, ModuleObject* mod builder(builder) { thisBinding_ = ThisBinding::Module; + hasModuleGoal_ = true; } template @@ -2471,8 +2475,7 @@ Parser::finishFunction(bool isStandaloneFunction /* = false pc->innerFunctionsForLazy, versionNumber(), funbox->bufStart, funbox->bufEnd, funbox->toStringStart, - funbox->startLine, funbox->startColumn, - parseGoal()); + funbox->startLine, funbox->startColumn); if (!lazy) return false; @@ -2496,6 +2499,8 @@ Parser::finishFunction(bool isStandaloneFunction /* = false lazy->setShouldDeclareArguments(); if (funbox->hasThisBinding()) lazy->setHasThisBinding(); + if (funbox->hasModuleGoal()) + lazy->setHasModuleGoal(); // Flags that need to copied back into the parser when we do the full // parse. diff --git a/js/src/frontend/Parser.h b/js/src/frontend/Parser.h index 1819873308..fd1bd034c4 100644 --- a/js/src/frontend/Parser.h +++ b/js/src/frontend/Parser.h @@ -817,8 +817,6 @@ class ParserBase : public StrictModeGetter /* AwaitHandling */ uint8_t awaitHandling_:2; - uint8_t parseGoal_:1; - public: bool awaitIsKeyword() const { return awaitHandling_ == AwaitIsKeyword || awaitHandling_ == AwaitIsModuleKeyword; @@ -828,13 +826,13 @@ class ParserBase : public StrictModeGetter } ParseGoal parseGoal() const { - return ParseGoal(parseGoal_); + return pc->sc()->hasModuleGoal() ? ParseGoal::Module : ParseGoal::Script; } ParserBase(ExclusiveContext* cx, LifoAlloc& alloc, const ReadOnlyCompileOptions& options, const char16_t* chars, size_t length, bool foldConstants, UsedNameTracker& usedNames, Parser* syntaxParser, - LazyScript* lazyOuterFunction, ParseGoal parseGoal); + LazyScript* lazyOuterFunction); ~ParserBase(); const char* getFilename() const { return tokenStream.getFilename(); } @@ -1072,7 +1070,7 @@ FOR_EACH_PARSENODE_SUBCLASS(DECLARE_TYPE) public: Parser(ExclusiveContext* cx, LifoAlloc& alloc, const ReadOnlyCompileOptions& options, const char16_t* chars, size_t length, bool foldConstants, UsedNameTracker& usedNames, - Parser* syntaxParser, LazyScript* lazyOuterFunction, ParseGoal parseGoal); + Parser* syntaxParser, LazyScript* lazyOuterFunction); ~Parser(); friend class AutoAwaitIsKeyword; diff --git a/js/src/frontend/SharedContext.h b/js/src/frontend/SharedContext.h index 29a8cbd18f..a241907482 100644 --- a/js/src/frontend/SharedContext.h +++ b/js/src/frontend/SharedContext.h @@ -249,6 +249,9 @@ class SharedContext bool inWith_; bool needsThisTDZChecks_; + // Script is being parsed with a goal of Module. + bool hasModuleGoal_ : 1; + void computeAllowSyntax(Scope* scope); void computeInWith(Scope* scope); void computeThisBinding(Scope* scope); @@ -267,7 +270,8 @@ class SharedContext allowSuperCall_(false), allowArguments_(true), inWith_(false), - needsThisTDZChecks_(false) + needsThisTDZChecks_(false), + hasModuleGoal_(false) { } // If this is the outermost SharedContext, the Scope that encloses @@ -287,6 +291,7 @@ class SharedContext ThisBinding thisBinding() const { return thisBinding_; } + bool hasModuleGoal() const { return hasModuleGoal_; } bool allowNewTarget() const { return allowNewTarget_; } bool allowSuperProperty() const { return allowSuperProperty_; } bool allowSuperCall() const { return allowSuperCall_; } @@ -303,6 +308,7 @@ class SharedContext void setBindingsAccessedDynamically() { anyCxFlags.bindingsAccessedDynamically = true; } void setHasDebuggerStatement() { anyCxFlags.hasDebuggerStatement = true; } void setHasDirectEval() { anyCxFlags.hasDirectEval = true; } + void setHasModuleGoal() { hasModuleGoal_ = true; } inline bool allBindingsClosedOver(); diff --git a/js/src/jsapi.cpp b/js/src/jsapi.cpp index c0fa85bc68..50e3442ae8 100644 --- a/js/src/jsapi.cpp +++ b/js/src/jsapi.cpp @@ -4265,8 +4265,7 @@ JS_BufferIsCompilableUnit(JSContext* cx, HandleObject obj, const char* utf8, siz frontend::Parser parser(cx, cx->tempLifoAlloc(), options, chars, length, /* foldConstants = */ true, - usedNames, nullptr, nullptr, - frontend::ParseGoal::Script); + usedNames, nullptr, nullptr); JS::WarningReporter older = JS::SetWarningReporter(cx, nullptr); if (!parser.checkOptions() || !parser.parse()) { // We ran into an error. If it was because we ran out of source, we diff --git a/js/src/jsscript.cpp b/js/src/jsscript.cpp index a3f5f07068..49a8a3ad04 100644 --- a/js/src/jsscript.cpp +++ b/js/src/jsscript.cpp @@ -2926,6 +2926,12 @@ JSScript::fullyInitFromEmitter(ExclusiveContext* cx, HandleScript script, Byteco script->bodyScopeIndex_ = bce->bodyScopeIndex; script->hasNonSyntacticScope_ = bce->outermostScope()->hasOnChain(ScopeKind::NonSyntactic); + if(bce->sc->hasModuleGoal()) { + LazyScript* lazy = script->maybeLazyScript(); + if(lazy) + lazy->setHasModuleGoal(); + } + if (bce->sc->isFunctionBox()) initFromFunctionBox(cx, script, bce->sc->asFunctionBox()); else if (bce->sc->isModuleContext()) @@ -4231,8 +4237,7 @@ LazyScript::Create(ExclusiveContext* cx, HandleFunction fun, Handle> innerFunctions, JSVersion version, uint32_t begin, uint32_t end, - uint32_t toStringStart, uint32_t lineno, uint32_t column, - frontend::ParseGoal parseGoal) + uint32_t toStringStart, uint32_t lineno, uint32_t column) { union { PackedView p; @@ -4255,7 +4260,6 @@ LazyScript::Create(ExclusiveContext* cx, HandleFunction fun, p.isLikelyConstructorWrapper = false; p.isDerivedClassConstructor = false; p.needsHomeObject = false; - p.parseGoal = uint32_t(parseGoal); LazyScript* res = LazyScript::CreateRaw(cx, fun, packedFields, begin, end, toStringStart, lineno, column); diff --git a/js/src/jsscript.h b/js/src/jsscript.h index 5d6c09dba6..78afa2eec2 100644 --- a/js/src/jsscript.h +++ b/js/src/jsscript.h @@ -2108,7 +2108,7 @@ class LazyScript : public gc::TenuredCell uint32_t isFieldInitializer : 1; uint32_t needsHomeObject : 1; uint32_t hasRest : 1; - uint32_t parseGoal : 1; + uint32_t hasModuleGoal : 1; }; union { @@ -2150,8 +2150,7 @@ class LazyScript : public gc::TenuredCell const frontend::AtomVector& closedOverBindings, Handle> innerFunctions, JSVersion version, uint32_t begin, uint32_t end, - uint32_t toStringStart, uint32_t lineno, uint32_t column, - frontend::ParseGoal parseGoal); + uint32_t toStringStart, uint32_t lineno, uint32_t column); // Create a LazyScript and initialize the closedOverBindings and the // innerFunctions with dummy values to be replaced in a later initialization @@ -2262,8 +2261,20 @@ class LazyScript : public gc::TenuredCell p_.isExprBody = true; } - frontend::ParseGoal parseGoal() const { - return frontend::ParseGoal(p_.parseGoal); + // This was added in Issue #2236 to compensate for the lack of + // Mozilla's ImmutableFlags feature, if ImmutableFlags ever gets + // ported remove the next 2 methods. + bool hasModuleGoal() const { + return p_.hasModuleGoal; + } + + void setHasModuleGoal() { + p_.hasModuleGoal = true; + } + + js::frontend::ParseGoal parseGoal() const { + return hasModuleGoal() ? js::frontend::ParseGoal::Module + : js::frontend::ParseGoal::Script; } bool strict() const { diff --git a/js/src/shell/js.cpp b/js/src/shell/js.cpp index 356ad0a78c..bab5cbb0b5 100644 --- a/js/src/shell/js.cpp +++ b/js/src/shell/js.cpp @@ -4342,8 +4342,7 @@ Parse(JSContext* cx, unsigned argc, Value* vp) if (!usedNames.init()) return false; Parser parser(cx, cx->tempLifoAlloc(), options, chars, length, - /* foldConstants = */ true, usedNames, nullptr, nullptr, - ParseGoal::Script); + /* foldConstants = */ true, usedNames, nullptr, nullptr); if (!parser.checkOptions()) return false; @@ -4394,8 +4393,7 @@ SyntaxParse(JSContext* cx, unsigned argc, Value* vp) return false; Parser parser(cx, cx->tempLifoAlloc(), options, chars, length, false, - usedNames, nullptr, nullptr, - ParseGoal::Script); + usedNames, nullptr, nullptr); if (!parser.checkOptions()) return false; diff --git a/js/src/vm/Debugger.cpp b/js/src/vm/Debugger.cpp index 5b7af64872..f844d1d482 100644 --- a/js/src/vm/Debugger.cpp +++ b/js/src/vm/Debugger.cpp @@ -5084,8 +5084,7 @@ Debugger::isCompilableUnit(JSContext* cx, unsigned argc, Value* vp) frontend::Parser parser(cx, cx->tempLifoAlloc(), options, chars.twoByteChars(), length, /* foldConstants = */ true, - usedNames, nullptr, nullptr, - frontend::ParseGoal::Script); + usedNames, nullptr, nullptr); JS::WarningReporter older = JS::SetWarningReporter(cx, nullptr); if (!parser.checkOptions() || !parser.parse()) { // We ran into an error. If it was because we ran out of memory we report From fae36a95ecc27402a447f685f1d717138239876b Mon Sep 17 00:00:00 2001 From: Brian Smith Date: Mon, 8 May 2023 20:18:12 -0500 Subject: [PATCH 6/6] No Issue - Updates to Mac packaging for notarization. Add Mac entitlements. Switch to using "create" instead of "makehybrid" when creating the disk image. This fixes bogus extended attributes which interfere with the code signature. Finally add any -bin or dylibs in the Resources folder since --deep skips that folder. --- python/mozbuild/mozpack/dmg.py | 28 +++++++++++------ security/mac/developer.entitlements.xml | 38 ++++++++++++++++++++++++ security/mac/production.entitlements.xml | 23 ++++++++++++++ 3 files changed, 80 insertions(+), 9 deletions(-) create mode 100644 security/mac/developer.entitlements.xml create mode 100644 security/mac/production.entitlements.xml diff --git a/python/mozbuild/mozpack/dmg.py b/python/mozbuild/mozpack/dmg.py index ade25aeac3..b231f731b8 100644 --- a/python/mozbuild/mozpack/dmg.py +++ b/python/mozbuild/mozpack/dmg.py @@ -5,6 +5,7 @@ import errno import mozfile import os +import fnmatch import platform import shutil import subprocess @@ -46,11 +47,11 @@ def create_dmg_from_staged(stagedir, output_dmg, tmpdir, volume_name): if not is_linux: # Running on OS X hybrid = os.path.join(tmpdir, 'hybrid.dmg') - subprocess.check_call(['hdiutil', 'makehybrid', '-hfs', - '-hfs-volume-name', volume_name, - '-hfs-openfolder', stagedir, - '-ov', stagedir, - '-o', hybrid]) + subprocess.check_call(['hdiutil', 'create', + '-fs', 'HFS+', + '-volname', volume_name, + '-srcfolder', stagedir, + '-ov', hybrid]) subprocess.check_call(['hdiutil', 'convert', '-format', 'UDBZ', '-imagekey', 'bzip2-level=9', '-ov', hybrid, '-o', output_dmg]) @@ -70,8 +71,8 @@ def create_dmg_from_staged(stagedir, output_dmg, tmpdir, volume_name): uncompressed, output_dmg ], - # dmg is seriously chatty - stdout=open(os.devnull, 'wb')) + # dmg is seriously chatty + stdout=open(os.devnull, 'wb')) def check_tools(*tools): ''' @@ -87,7 +88,6 @@ def check_tools(*tools): if not os.access(path, os.X_OK): raise Exception('Required tool "%s" at path "%s" is not executable' % (tool, path)) - def create_dmg(source_directory, output_dmg, volume_name, extra_files): ''' Create a DMG disk image at the path output_dmg from source_directory. @@ -122,6 +122,16 @@ def create_dmg(source_directory, output_dmg, volume_name, extra_files): if not is_linux: identity = buildconfig.substs['MOZ_MACBUNDLE_IDENTITY'] if identity != '': + dylibs = [] appbundle = os.path.join(stagedir, buildconfig.substs['MOZ_MACBUNDLE_NAME']) - subprocess.check_call(['codesign', '--deep', '-s', identity, appbundle]) + # If the -bin file is in Resources add it to the dylibs as well + resourcebin = os.path.join(appbundle, 'Contents/Resources/' + buildconfig.substs['MOZ_APP_NAME'] + '-bin') + if os.path.isfile(resourcebin): + dylibs.append(resourcebin) + # Create a list of dylibs in Contents/Resources that won't get signed by --deep + for root, dirnames, filenames in os.walk('Contents/Resources/'): + for filename in fnmatch.filter(filenames, '*.dylib'): + dylibs.append(os.path.join(root, filename)) + entitlement = os.path.abspath(os.path.join(os.getcwd(), '../../platform/security/mac/production.entitlements.xml')) + subprocess.check_call(['codesign', '--deep', '--timestamp', '--options', 'runtime', '--entitlements', entitlement, '-s', identity] + dylibs + [appbundle]) create_dmg_from_staged(stagedir, output_dmg, tmpdir, volume_name) diff --git a/security/mac/developer.entitlements.xml b/security/mac/developer.entitlements.xml new file mode 100644 index 0000000000..1560ab9c62 --- /dev/null +++ b/security/mac/developer.entitlements.xml @@ -0,0 +1,38 @@ + + + + + + + com.apple.security.cs.allow-unsigned-executable-memory + + + com.apple.security.cs.disable-library-validation + + + com.apple.security.cs.allow-dyld-environment-variables + + + com.apple.security.get-task-allow + + + com.apple.security.device.audio-input + + + com.apple.security.device.camera + + + com.apple.security.personal-information.location + + diff --git a/security/mac/production.entitlements.xml b/security/mac/production.entitlements.xml new file mode 100644 index 0000000000..6c2d751728 --- /dev/null +++ b/security/mac/production.entitlements.xml @@ -0,0 +1,23 @@ + + + + + + + com.apple.security.cs.allow-unsigned-executable-memory + + + com.apple.security.cs.disable-library-validation + + + com.apple.security.device.audio-input + + + com.apple.security.device.camera + + + com.apple.security.personal-information.location + +