mirror of
https://repo.dactyloidae.xyz/Dactyloidae/UXP.git
synced 2026-09-06 15:58:39 +09:00
Issue #1691 - Part 2: Implement call import and import meta in the parser. https://bugzilla.mozilla.org/show_bug.cgi?id=1427610 https://bugzilla.mozilla.org/show_bug.cgi?id=1484948
(cherry picked from commit 6be083187f49e444de1bb116bb5930b20125190b)
This commit is contained in:
parent
1a6b3a822c
commit
a8ab41b4c6
21 changed files with 238 additions and 46 deletions
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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()) {
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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>();
|
||||
|
|
|
|||
|
|
@ -121,6 +121,8 @@ class ObjectBox;
|
|||
F(SUPERBASE) \
|
||||
F(SUPERCALL) \
|
||||
F(SETTHIS) \
|
||||
F(IMPORT_META) \
|
||||
F(CALL_IMPORT) \
|
||||
\
|
||||
/* Unary operators. */ \
|
||||
F(TYPEOFNAME) \
|
||||
|
|
|
|||
|
|
@ -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 */)
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
||||
/*
|
||||
|
|
|
|||
|
|
@ -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) \
|
||||
|
|
|
|||
|
|
@ -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; }
|
||||
|
||||
|
|
|
|||
|
|
@ -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'") \
|
||||
|
|
|
|||
|
|
@ -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.")
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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")
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
|
|
@ -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") \
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue