(cherry picked from commit 6be083187f49e444de1bb116bb5930b20125190b)
This commit is contained in:
Brian Smith 2023-04-08 03:27:08 -05:00 committed by roytam1
commit a8ab41b4c6
21 changed files with 238 additions and 46 deletions

View file

@ -34,12 +34,6 @@ using mozilla::ArrayLength;
using mozilla::DebugOnly;
using mozilla::Forward;
enum class ParseTarget
{
Script,
Module
};
enum ASTType {
AST_ERROR = -1,
#define ASTDEF(ast, str, method) ast,
@ -623,6 +617,9 @@ class NodeBuilder
MOZ_MUST_USE bool metaProperty(HandleValue meta, HandleValue property, TokenPos* pos,
MutableHandleValue dst);
MOZ_MUST_USE bool callImportExpression(HandleValue ident, HandleValue arg, TokenPos* pos,
MutableHandleValue dst);
MOZ_MUST_USE bool super(TokenPos* pos, MutableHandleValue dst);
/*
@ -1758,6 +1755,20 @@ NodeBuilder::metaProperty(HandleValue meta, HandleValue property, TokenPos* pos,
dst);
}
bool
NodeBuilder::callImportExpression(HandleValue ident, HandleValue arg, TokenPos* pos,
MutableHandleValue dst)
{
RootedValue cb(cx, callbacks[AST_CALL_IMPORT]);
if (!cb.isNull())
return callback(cb, arg, pos, dst);
return newNode(AST_CALL_IMPORT, pos,
"ident", ident,
"arg", arg,
dst);
}
bool
NodeBuilder::super(TokenPos* pos, MutableHandleValue dst)
{
@ -3360,6 +3371,7 @@ ASTSerializer::expression(ParseNode* pn, MutableHandleValue dst)
return classDefinition(&pn->as<ClassNode>(), true, dst);
case PNK_NEWTARGET:
case PNK_IMPORT_META:
{
BinaryNode* node = &pn->as<BinaryNode>();
ParseNode* firstNode = node->left();
@ -3370,15 +3382,41 @@ ASTSerializer::expression(ParseNode* pn, MutableHandleValue dst)
MOZ_ASSERT(secondNode->isKind(PNK_POSHOLDER));
MOZ_ASSERT(node->pn_pos.encloses(secondNode->pn_pos));
RootedValue newIdent(cx);
RootedValue targetIdent(cx);
RootedValue firstIdent(cx);
RootedValue secondIdent(cx);
RootedAtom newStr(cx, cx->names().new_);
RootedAtom targetStr(cx, cx->names().target);
RootedAtom firstStr(cx);
RootedAtom secondStr(cx);
return identifier(newStr, &firstNode->pn_pos, &newIdent) &&
identifier(targetStr, &secondNode->pn_pos, &targetIdent) &&
builder.metaProperty(newIdent, targetIdent, &node->pn_pos, dst);
if (pn->getKind() == PNK_NEWTARGET) {
firstStr = cx->names().new_;
secondStr = cx->names().target;
} else {
firstStr = cx->names().import;
secondStr = cx->names().meta;
}
return identifier(firstStr, &firstNode->pn_pos, &firstIdent) &&
identifier(secondStr, &secondNode->pn_pos, &secondIdent) &&
builder.metaProperty(firstIdent, secondIdent, &pn->pn_pos, dst);
}
case PNK_CALL_IMPORT:
{
BinaryNode* node = &pn->as<BinaryNode>();
ParseNode* firstNode = node->left();
MOZ_ASSERT(firstNode->isKind(PNK_POSHOLDER));
MOZ_ASSERT(pn->pn_pos.encloses(firstNode->pn_pos));
ParseNode* secondNode = node->right();
MOZ_ASSERT(pn->pn_pos.encloses(secondNode->pn_pos));
RootedValue ident(cx);
RootedValue arg(cx);
HandlePropertyName name = cx->names().import;
return identifier(name, &firstNode->pn_pos, &ident) &&
expression(secondNode, &arg) &&
builder.callImportExpression(ident, arg, &pn->pn_pos, dst);
}
case PNK_SETTHIS: {
@ -3793,7 +3831,7 @@ reflect_parse(JSContext* cx, uint32_t argc, Value* vp)
uint32_t lineno = 1;
bool loc = true;
RootedObject builder(cx);
ParseTarget target = ParseTarget::Script;
ParseGoal target = ParseGoal::Script;
RootedValue arg(cx, args.get(1));
@ -3881,9 +3919,9 @@ reflect_parse(JSContext* cx, uint32_t argc, Value* vp)
return false;
if (isScript) {
target = ParseTarget::Script;
target = ParseGoal::Script;
} else if (isModule) {
target = ParseTarget::Module;
target = ParseGoal::Module;
} else {
JS_ReportErrorASCII(cx, "Bad target value, expected 'script' or 'module'");
return false;
@ -3912,14 +3950,14 @@ reflect_parse(JSContext* cx, uint32_t argc, Value* vp)
return false;
Parser<FullParseHandler> parser(cx, cx->tempLifoAlloc(), options, chars.begin().get(),
chars.length(), /* foldConstants = */ false, usedNames,
nullptr, nullptr);
nullptr, nullptr, target);
if (!parser.checkOptions())
return false;
serialize.setParser(&parser);
ParseNode* pn;
if (target == ParseTarget::Script) {
if (target == ParseGoal::Script) {
pn = parser.parse();
if (!pn)
return false;

View file

@ -74,8 +74,9 @@ class MOZ_STACK_CLASS BytecodeCompiler
bool createScriptSource(Maybe<uint32_t> parameterListEnd);
bool maybeCompressSource();
bool canLazilyParse();
bool createParser();
bool createSourceAndParser(Maybe<uint32_t> parameterListEnd = Nothing());
bool createParser(ParseGoal goal);
bool createSourceAndParser(ParseGoal goal,
Maybe<uint32_t> 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
@ -212,7 +213,7 @@ BytecodeCompiler::canLazilyParse()
}
bool
BytecodeCompiler::createParser()
BytecodeCompiler::createParser(ParseGoal goal)
{
usedNames.emplace(cx);
if (!usedNames->init())
@ -221,14 +222,14 @@ BytecodeCompiler::createParser()
if (canLazilyParse()) {
syntaxParser.emplace(cx, alloc, options, sourceBuffer.get(), sourceBuffer.length(),
/* foldConstants = */ false, *usedNames,
(Parser<SyntaxParseHandler>*) nullptr, (LazyScript*) nullptr);
(Parser<SyntaxParseHandler>*) nullptr, (LazyScript*) nullptr, goal);
if (!syntaxParser->checkOptions())
return false;
}
parser.emplace(cx, alloc, options, sourceBuffer.get(), sourceBuffer.length(),
/* foldConstants = */ true, *usedNames, syntaxParser.ptrOr(nullptr), nullptr);
/* foldConstants = */ true, *usedNames, syntaxParser.ptrOr(nullptr), nullptr, goal);
parser->sct = sourceCompressor;
parser->ss = scriptSource;
if (!parser->checkOptions())
@ -239,11 +240,12 @@ BytecodeCompiler::createParser()
}
bool
BytecodeCompiler::createSourceAndParser(Maybe<uint32_t> parameterListEnd /* = Nothing() */)
BytecodeCompiler::createSourceAndParser(ParseGoal goal,
Maybe<uint32_t> parameterListEnd /* = Nothing() */)
{
return createScriptSource(parameterListEnd) &&
maybeCompressSource() &&
createParser();
createParser(goal);
}
bool
@ -322,7 +324,7 @@ BytecodeCompiler::maybeCompleteCompressSource()
JSScript*
BytecodeCompiler::compileScript(HandleObject environment, SharedContext* sc)
{
if (!createSourceAndParser())
if (!createSourceAndParser(ParseGoal::Script))
return nullptr;
if (!createScript())
@ -392,7 +394,7 @@ BytecodeCompiler::compileEvalScript(HandleObject environment, HandleScope enclos
ModuleObject*
BytecodeCompiler::compileModule()
{
if (!createSourceAndParser())
if (!createSourceAndParser(ParseGoal::Module))
return nullptr;
Rooted<ModuleObject*> module(cx, ModuleObject::create(cx));
@ -449,7 +451,7 @@ BytecodeCompiler::compileStandaloneFunction(MutableHandleFunction fun,
MOZ_ASSERT(fun);
MOZ_ASSERT(fun->isTenured());
if (!createSourceAndParser(parameterListEnd))
if (!createSourceAndParser(ParseGoal::Script, parameterListEnd))
return false;
// Speculatively parse using the default directives implied by the context.
@ -649,7 +651,7 @@ frontend::CompileLazyFunction(JSContext* cx, Handle<LazyScript*> lazy, const cha
if (!usedNames.init())
return false;
Parser<FullParseHandler> parser(cx, cx->tempLifoAlloc(), options, chars, length,
/* foldConstants = */ true, usedNames, nullptr, lazy);
/* foldConstants = */ true, usedNames, nullptr, lazy, lazy->parseGoal());
if (!parser.checkOptions())
return false;

View file

@ -1090,6 +1090,7 @@ BytecodeEmitter::checkSideEffects(ParseNode* pn, bool* answer)
// Trivial binary nodes with more token pos holders.
case PNK_NEWTARGET:
case PNK_IMPORT_META:
MOZ_ASSERT(pn->as<BinaryNode>().left()->isKind(PNK_POSHOLDER));
MOZ_ASSERT(pn->as<BinaryNode>().right()->isKind(PNK_POSHOLDER));
*answer = false;
@ -1319,6 +1320,11 @@ BytecodeEmitter::checkSideEffects(ParseNode* pn, bool* answer)
*answer = true;
return true;
case PNK_CALL_IMPORT:
MOZ_ASSERT(pn->isArity(PN_BINARY));
*answer = true;
return true;
// Every part of a loop might be effect-free, but looping infinitely *is*
// an effect. (Language lawyer trivia: C++ says threads can be assumed
// to exit or have side effects, C++14 [intro.multithread]p27, so a C++
@ -9076,6 +9082,14 @@ BytecodeEmitter::emitTree(ParseNode* pn, ValueUsage valueUsage /* = ValueUsage::
return false;
break;
case PNK_IMPORT_META:
MOZ_CRASH("NYI");
break;
case PNK_CALL_IMPORT:
reportError(nullptr, JSMSG_NO_DYNAMIC_IMPORT);
return false;
case PNK_SETTHIS:
if (!emitSetThis(&pn->as<BinaryNode>()))
return false;

View file

@ -138,6 +138,7 @@ ContainsHoistedDeclaration(ExclusiveContext* cx, ParseNode* node, bool* result)
case PNK_EXPORT_SPEC:
case PNK_EXPORT:
case PNK_EXPORT_BATCH_SPEC:
case PNK_CALL_IMPORT:
*result = false;
return true;
@ -403,6 +404,7 @@ ContainsHoistedDeclaration(ExclusiveContext* cx, ParseNode* node, bool* result)
case PNK_CLASSMETHODLIST:
case PNK_CLASSNAMES:
case PNK_NEWTARGET:
case PNK_IMPORT_META:
case PNK_POSHOLDER:
case PNK_SUPERCALL:
case PNK_SUPERBASE:
@ -1900,7 +1902,8 @@ Fold(ExclusiveContext* cx, ParseNode** pnp, Parser<FullParseHandler>& parser, bo
Fold(cx, node->unsafeRightReference(), parser, inGenexpLambda);
}
case PNK_NEWTARGET:{
case PNK_NEWTARGET:
case PNK_IMPORT_META:{
#ifdef DEBUG
BinaryNode* node = &pn->as<BinaryNode>();
MOZ_ASSERT(node->left()->isKind(PNK_POSHOLDER));
@ -1909,6 +1912,13 @@ Fold(ExclusiveContext* cx, ParseNode** pnp, Parser<FullParseHandler>& parser, bo
return true;
}
case PNK_CALL_IMPORT: {
BinaryNode* node = &pn->as<BinaryNode>();
MOZ_ASSERT(pn->isArity(PN_BINARY));
MOZ_ASSERT(node->left()->isKind(PNK_POSHOLDER));
return Fold(cx, node->unsafeRightReference(), parser, inGenexpLambda);
}
case PNK_CLASSNAMES: {
ClassNames* names = &pn->as<ClassNames>();
if (names->outerBinding()) {

View file

@ -590,6 +590,14 @@ FOR_EACH_PARSENODE_SUBCLASS(DECLARE_AS)
return new_<BinaryNode>(PNK_EXPORT_DEFAULT, JSOP_NOP, pos, kid, maybeBinding);
}
BinaryNodeType newImportMeta(Node importHolder, Node metaHolder) {
return new_<BinaryNode>(PNK_IMPORT_META, JSOP_NOP, importHolder, metaHolder);
}
BinaryNodeType newCallImport(Node importHolder, Node singleArg) {
return new_<BinaryNode>(PNK_CALL_IMPORT, JSOP_NOP, importHolder, singleArg);
}
UnaryNodeType newExprStatement(Node expr, uint32_t end) {
MOZ_ASSERT(expr->pn_pos.end <= end);
return new_<UnaryNode>(PNK_SEMI, JSOP_NOP, TokenPos(expr->pn_pos.begin, end), expr);

View file

@ -64,6 +64,12 @@ class EnvironmentCoordinate
namespace frontend {
enum class ParseGoal : uint8_t
{
Script,
Module
};
// A detailed kind used for tracking declarations in the Parser. Used for
// specific early error semantics and better error messages.
enum class DeclarationKind : uint8_t

View file

@ -424,7 +424,8 @@ class NameResolver
MOZ_ASSERT(!cur->as<UnaryNode>().kid()->as<NameNode>().initializer());
break;
case PNK_NEWTARGET: {
case PNK_NEWTARGET:
case PNK_IMPORT_META: {
MOZ_ASSERT(cur->as<BinaryNode>().left()->isKind(PNK_POSHOLDER));
MOZ_ASSERT(cur->as<BinaryNode>().right()->isKind(PNK_POSHOLDER));
break;
@ -834,6 +835,14 @@ class NameResolver
break;
}
case PNK_CALL_IMPORT: {
BinaryNode* node = &cur->as<BinaryNode>();
MOZ_ASSERT(cur->isArity(PN_BINARY));
if (!resolve(node->right(), prefix))
return false;
break;
}
case PNK_DOT: {
// Super prop nodes do not have a meaningful LHS
PropertyAccess* prop = &cur->as<PropertyAccess>();

View file

@ -121,6 +121,8 @@ class ObjectBox;
F(SUPERBASE) \
F(SUPERCALL) \
F(SETTHIS) \
F(IMPORT_META) \
F(CALL_IMPORT) \
\
/* Unary operators. */ \
F(TYPEOFNAME) \

View file

@ -791,7 +791,8 @@ ParserBase::ParserBase(ExclusiveContext* cx, LifoAlloc& alloc,
bool foldConstants,
UsedNameTracker& usedNames,
Parser<SyntaxParseHandler>* syntaxParser,
LazyScript* lazyOuterFunction)
LazyScript* lazyOuterFunction,
ParseGoal parseGoal)
: context(cx),
alloc(alloc),
tokenStream(cx, options, chars, length, thisForCtor()),
@ -807,7 +808,8 @@ ParserBase::ParserBase(ExclusiveContext* cx, LifoAlloc& alloc,
#endif
abortedSyntaxParse(false),
isUnexpectedEOF_(false),
awaitIsKeyword_(false)
awaitIsKeyword_(false),
parseGoal_(uint8_t(parseGoal))
{
cx->perThreadData->frontendCollectionPool.addActiveCompilation();
tempPoolMark = alloc.mark();
@ -834,9 +836,10 @@ Parser<ParseHandler>::Parser(ExclusiveContext* cx, LifoAlloc& alloc,
bool foldConstants,
UsedNameTracker& usedNames,
Parser<SyntaxParseHandler>* syntaxParser,
LazyScript* lazyOuterFunction)
LazyScript* lazyOuterFunction,
ParseGoal parseGoal)
: ParserBase(cx, alloc, options, chars, length, foldConstants, usedNames, syntaxParser,
lazyOuterFunction),
lazyOuterFunction, parseGoal),
AutoGCRooter(cx, PARSER),
handler(cx, alloc, tokenStream, syntaxParser, lazyOuterFunction)
{
@ -2468,7 +2471,8 @@ Parser<SyntaxParseHandler>::finishFunction(bool isStandaloneFunction /* = false
pc->innerFunctionsForLazy, versionNumber(),
funbox->bufStart, funbox->bufEnd,
funbox->toStringStart,
funbox->startLine, funbox->startColumn);
funbox->startLine, funbox->startColumn,
parseGoal());
if (!lazy)
return false;
@ -5212,6 +5216,22 @@ Parser<SyntaxParseHandler>::importDeclaration()
return SyntaxParseHandler::NodeFailure;
}
template <class ParseHandler>
inline typename ParseHandler::Node
Parser<ParseHandler>::importDeclarationOrImportExpr(YieldHandling yieldHandling)
{
MOZ_ASSERT(anyChars.isCurrentTokenType(TOK_IMPORT));
TokenKind tt;
if (!tokenStream.peekToken(&tt))
return null();
if (tt == TOK_DOT || tt == TOK_LP)
return expressionStatement(yieldHandling);
return importDeclaration();
}
template<>
bool
Parser<FullParseHandler>::checkExportedName(JSAtom* exportName)
@ -7737,7 +7757,7 @@ Parser<ParseHandler>::statement(YieldHandling yieldHandling)
// ImportDeclaration (only inside modules)
case TOK_IMPORT:
return importDeclaration();
return importDeclarationOrImportExpr(yieldHandling);
// ExportDeclaration (only inside modules)
case TOK_EXPORT:
@ -7928,7 +7948,7 @@ Parser<ParseHandler>::statementListItem(YieldHandling yieldHandling,
// ImportDeclaration (only inside modules)
case TOK_IMPORT:
return importDeclaration();
return importDeclarationOrImportExpr(yieldHandling);
// ExportDeclaration (only inside modules)
case TOK_EXPORT:
@ -9284,6 +9304,10 @@ Parser<ParseHandler>::memberExpr(YieldHandling yieldHandling, TripledotHandling
lhs = handler.newSuperBase(thisName, pos());
if (!lhs)
return null();
} else if (tt == TOK_IMPORT) {
lhs = importExpr(yieldHandling);
if (!lhs)
return null();
} else {
lhs = primaryExpr(yieldHandling, tripledotHandling, tt, possibleError, invoked);
if (!lhs)
@ -10454,6 +10478,52 @@ Parser<ParseHandler>::tryNewTarget(BinaryNodeType* newTarget)
template <typename ParseHandler>
typename ParseHandler::Node
Parser<ParseHandler>::importExpr(YieldHandling yieldHandling)
{
MOZ_ASSERT(anyChars.isCurrentTokenType(TOK_IMPORT));
Node importHolder = handler.newPosHolder(pos());
if (!importHolder)
return null();
TokenKind next;
if (!tokenStream.getToken(&next))
return null();
if (next == TOK_DOT) {
if (!tokenStream.getToken(&next))
return null();
if (next != TOK_META) {
error(JSMSG_UNEXPECTED_TOKEN, "meta", TokenKindToDesc(next));
return null();
}
if (parseGoal() != ParseGoal::Module) {
errorAt(pos().begin, JSMSG_IMPORT_META_OUTSIDE_MODULE);
return null();
}
Node metaHolder = handler.newPosHolder(pos());
if (!metaHolder)
return null();
return handler.newImportMeta(importHolder, metaHolder);
} else if (next == TOK_LP) {
Node arg = assignExpr(InAllowed, yieldHandling, TripledotProhibited);
if (!arg)
return null();
MUST_MATCH_TOKEN_MOD(TOK_RP, TokenStream::Operand, JSMSG_PAREN_AFTER_ARGS);
return handler.newCallImport(importHolder, arg);
} else {
error(JSMSG_UNEXPECTED_TOKEN, TokenKindToDesc(next));
return null();
}
}
template <class ParseHandler>
typename ParseHandler::Node
Parser<ParseHandler>::primaryExpr(YieldHandling yieldHandling, TripledotHandling tripledotHandling,
TokenKind tt, PossibleError* possibleError,
InvokedPrediction invoked /* = PredictUninvoked */)

View file

@ -801,15 +801,21 @@ class ParserBase : public StrictModeGetter
bool awaitIsKeyword_:1;
uint8_t parseGoal_:1;
public:
bool awaitIsKeyword() const {
return awaitIsKeyword_;
}
ParseGoal parseGoal() const {
return ParseGoal(parseGoal_);
}
ParserBase(ExclusiveContext* cx, LifoAlloc& alloc, const ReadOnlyCompileOptions& options,
const char16_t* chars, size_t length, bool foldConstants,
UsedNameTracker& usedNames, Parser<SyntaxParseHandler>* syntaxParser,
LazyScript* lazyOuterFunction);
LazyScript* lazyOuterFunction, ParseGoal parseGoal);
~ParserBase();
const char* getFilename() const { return tokenStream.getFilename(); }
@ -1045,7 +1051,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<SyntaxParseHandler>* syntaxParser, LazyScript* lazyOuterFunction);
Parser<SyntaxParseHandler>* syntaxParser, LazyScript* lazyOuterFunction, ParseGoal parseGoal);
~Parser();
friend class AutoAwaitIsKeyword<ParseHandler>;
@ -1236,6 +1242,7 @@ FOR_EACH_PARSENODE_SUBCLASS(DECLARE_TYPE)
ListNodeType lexicalDeclaration(YieldHandling yieldHandling, DeclarationKind kind);
inline BinaryNodeType importDeclaration();
Node importDeclarationOrImportExpr(YieldHandling yieldHandling);
bool processExport(Node node);
bool processExportFrom(BinaryNodeType node);
@ -1346,6 +1353,8 @@ FOR_EACH_PARSENODE_SUBCLASS(DECLARE_TYPE)
bool tryNewTarget(BinaryNodeType* newTarget);
bool checkAndMarkSuperScope();
Node importExpr(YieldHandling yieldHandling);
FunctionNodeType methodDefinition(uint32_t toStringStart, PropertyType propType, HandleAtom funName);
/*

View file

@ -66,6 +66,7 @@
macro(from, from, TOK_FROM) \
macro(get, get, TOK_GET) \
macro(let, let, TOK_LET) \
macro(meta, meta, TOK_META) \
macro(of, of, TOK_OF) \
macro(set, set, TOK_SET) \
macro(static, static_, TOK_STATIC) \

View file

@ -354,6 +354,12 @@ FOR_EACH_PARSENODE_SUBCLASS(DECLARE_AS)
BinaryNodeType newExportDefaultDeclaration(Node kid, Node maybeBinding, const TokenPos& pos) {
return NodeGeneric;
}
Node newImportMeta(Node importHolder, Node metaHolder) {
return NodeGeneric;
}
Node newCallImport(Node importHolder, Node singleArg) {
return NodeGeneric;
}
BinaryNodeType newSetThis(Node thisName, Node value) { return value; }

View file

@ -125,6 +125,7 @@
macro(FROM, "'from'") \
macro(GET, "'get'") \
macro(LET, "'let'") \
macro(META, "'meta'") \
macro(OF, "'of'") \
macro(SET, "'set'") \
macro(STATIC, "'static'") \

View file

@ -265,6 +265,7 @@ MSG_DEF(JSMSG_FROM_AFTER_EXPORT_STAR, 0, JSEXN_SYNTAXERR, "missing keyword 'fro
MSG_DEF(JSMSG_GARBAGE_AFTER_INPUT, 2, JSEXN_SYNTAXERR, "unexpected garbage after {0}, starting with {1}")
MSG_DEF(JSMSG_IDSTART_AFTER_NUMBER, 0, JSEXN_SYNTAXERR, "identifier starts immediately after numeric literal")
MSG_DEF(JSMSG_ILLEGAL_CHARACTER, 0, JSEXN_SYNTAXERR, "illegal character")
MSG_DEF(JSMSG_IMPORT_META_OUTSIDE_MODULE, 0, JSEXN_SYNTAXERR, "import.meta may only appear in a module")
MSG_DEF(JSMSG_IMPORT_DECL_AT_TOP_LEVEL, 0, JSEXN_SYNTAXERR, "import declarations may only appear at top level of a module")
MSG_DEF(JSMSG_OF_AFTER_FOR_LOOP_DECL, 0, JSEXN_SYNTAXERR, "a declaration in the head of a for-of loop can't have an initializer")
MSG_DEF(JSMSG_IN_AFTER_LEXICAL_FOR_DECL,0,JSEXN_SYNTAXERR, "a lexical declaration in the head of a for-in loop can't have an initializer")
@ -590,6 +591,7 @@ MSG_DEF(JSMSG_AMBIGUOUS_IMPORT, 0, JSEXN_SYNTAXERR, "ambiguous import")
MSG_DEF(JSMSG_MISSING_NAMESPACE_EXPORT, 0, JSEXN_SYNTAXERR, "export not found for namespace")
MSG_DEF(JSMSG_MISSING_EXPORT, 1, JSEXN_SYNTAXERR, "local binding for export '{0}' not found")
MSG_DEF(JSMSG_BAD_MODULE_STATUS, 0, JSEXN_INTERNALERR, "module record has unexpected status")
MSG_DEF(JSMSG_NO_DYNAMIC_IMPORT, 0, JSEXN_SYNTAXERR, "dynamic module import is not implemented")
// Promise
MSG_DEF(JSMSG_CANNOT_RESOLVE_PROMISE_WITH_ITSELF, 0, JSEXN_TYPEERR, "A promise cannot be resolved with itself.")

View file

@ -4240,7 +4240,8 @@ JS_BufferIsCompilableUnit(JSContext* cx, HandleObject obj, const char* utf8, siz
frontend::Parser<frontend::FullParseHandler> parser(cx, cx->tempLifoAlloc(),
options, chars, length,
/* foldConstants = */ true,
usedNames, nullptr, nullptr);
usedNames, nullptr, nullptr,
frontend::ParseGoal::Script);
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

View file

@ -44,6 +44,7 @@ ASTDEF(AST_YIELD_EXPR, "YieldExpression", "yieldExpres
ASTDEF(AST_CLASS_EXPR, "ClassExpression", "classExpression")
ASTDEF(AST_METAPROPERTY, "MetaProperty", "metaProperty")
ASTDEF(AST_SUPER, "Super", "super")
ASTDEF(AST_CALL_IMPORT, "CallImport", "callImport")
ASTDEF(AST_EMPTY_STMT, "EmptyStatement", "emptyStatement")
ASTDEF(AST_BLOCK_STMT, "BlockStatement", "blockStatement")

View file

@ -4089,7 +4089,8 @@ LazyScript::Create(ExclusiveContext* cx, HandleFunction fun,
Handle<GCVector<JSFunction*, 8>> innerFunctions,
JSVersion version,
uint32_t begin, uint32_t end,
uint32_t toStringStart, uint32_t lineno, uint32_t column)
uint32_t toStringStart, uint32_t lineno, uint32_t column,
frontend::ParseGoal parseGoal)
{
union {
PackedView p;
@ -4112,6 +4113,7 @@ 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);

View file

@ -2019,6 +2019,7 @@ class LazyScript : public gc::TenuredCell
uint32_t isDerivedClassConstructor : 1;
uint32_t needsHomeObject : 1;
uint32_t hasRest : 1;
uint32_t parseGoal : 1;
};
union {
@ -2058,7 +2059,8 @@ class LazyScript : public gc::TenuredCell
const frontend::AtomVector& closedOverBindings,
Handle<GCVector<JSFunction*, 8>> innerFunctions,
JSVersion version, uint32_t begin, uint32_t end,
uint32_t toStringStart, uint32_t lineno, uint32_t column);
uint32_t toStringStart, uint32_t lineno, uint32_t column,
frontend::ParseGoal parseGoal);
// Create a LazyScript and initialize the closedOverBindings and the
// innerFunctions with dummy values to be replaced in a later initialization
@ -2169,6 +2171,10 @@ class LazyScript : public gc::TenuredCell
p_.isExprBody = true;
}
frontend::ParseGoal parseGoal() const {
return frontend::ParseGoal(p_.parseGoal);
}
bool strict() const {
return p_.strict;
}

View file

@ -4146,7 +4146,8 @@ Parse(JSContext* cx, unsigned argc, Value* vp)
if (!usedNames.init())
return false;
Parser<FullParseHandler> parser(cx, cx->tempLifoAlloc(), options, chars, length,
/* foldConstants = */ true, usedNames, nullptr, nullptr);
/* foldConstants = */ true, usedNames, nullptr, nullptr,
ParseGoal::Script);
if (!parser.checkOptions())
return false;
@ -4197,7 +4198,8 @@ SyntaxParse(JSContext* cx, unsigned argc, Value* vp)
return false;
Parser<frontend::SyntaxParseHandler> parser(cx, cx->tempLifoAlloc(),
options, chars, length, false,
usedNames, nullptr, nullptr);
usedNames, nullptr, nullptr,
ParseGoal::Script);
if (!parser.checkOptions())
return false;

View file

@ -226,6 +226,7 @@
macro(maximumFractionDigits, maximumFractionDigits, "maximumFractionDigits") \
macro(maximumSignificantDigits, maximumSignificantDigits, "maximumSignificantDigits") \
macro(message, message, "message") \
macro(meta, meta, "meta") \
macro(minDays, minDays, "minDays") \
macro(minimumFractionDigits, minimumFractionDigits, "minimumFractionDigits") \
macro(minimumIntegerDigits, minimumIntegerDigits, "minimumIntegerDigits") \

View file

@ -5084,7 +5084,8 @@ Debugger::isCompilableUnit(JSContext* cx, unsigned argc, Value* vp)
frontend::Parser<frontend::FullParseHandler> parser(cx, cx->tempLifoAlloc(),
options, chars.twoByteChars(),
length, /* foldConstants = */ true,
usedNames, nullptr, nullptr);
usedNames, nullptr, nullptr,
frontend::ParseGoal::Script);
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