Bug 1427610 - Implement import.meta in the JS frontent r=jorendorff

This commit is contained in:
Jon Coppeard 2018-05-23 08:47:28 +01:00
Родитель 7dcc1b6880
Коммит a2f88658e9
22 изменённых файлов: 264 добавлений и 49 удалений

Просмотреть файл

@ -33,12 +33,6 @@ using JS::AutoValueArray;
using mozilla::DebugOnly;
using mozilla::Forward;
enum class ParseTarget
{
Script,
Module
};
enum ASTType {
AST_ERROR = -1,
#define ASTDEF(ast, str, method) ast,
@ -2928,21 +2922,30 @@ ASTSerializer::expression(ParseNode* pn, MutableHandleValue dst)
return classDefinition(pn, true, dst);
case ParseNodeKind::NewTarget:
case ParseNodeKind::ImportMeta:
{
MOZ_ASSERT(pn->pn_left->isKind(ParseNodeKind::PosHolder));
MOZ_ASSERT(pn->pn_pos.encloses(pn->pn_left->pn_pos));
MOZ_ASSERT(pn->pn_right->isKind(ParseNodeKind::PosHolder));
MOZ_ASSERT(pn->pn_pos.encloses(pn->pn_right->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, &pn->pn_left->pn_pos, &newIdent) &&
identifier(targetStr, &pn->pn_right->pn_pos, &targetIdent) &&
builder.metaProperty(newIdent, targetIdent, &pn->pn_pos, dst);
if (pn->getKind() == ParseNodeKind::NewTarget) {
firstStr = cx->names().new_;
secondStr = cx->names().target;
} else {
firstStr = cx->names().import;
secondStr = cx->names().meta;
}
return identifier(firstStr, &pn->pn_left->pn_pos, &firstIdent) &&
identifier(secondStr, &pn->pn_right->pn_pos, &secondIdent) &&
builder.metaProperty(firstIdent, secondIdent, &pn->pn_pos, dst);
}
case ParseNodeKind::SetThis:
@ -3354,7 +3357,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));
@ -3442,9 +3445,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;
@ -3467,7 +3470,7 @@ reflect_parse(JSContext* cx, uint32_t argc, Value* vp)
CompileOptions options(cx);
options.setFileAndLine(filename, lineno);
options.setCanLazilyParse(false);
options.allowHTMLComments = target == ParseTarget::Script;
options.allowHTMLComments = target == ParseGoal::Script;
mozilla::Range<const char16_t> chars = linearChars.twoByteRange();
UsedNameTracker usedNames(cx);
if (!usedNames.init())
@ -3481,14 +3484,14 @@ reflect_parse(JSContext* cx, uint32_t argc, Value* vp)
Parser<FullParseHandler, char16_t> parser(cx, cx->tempLifoAlloc(), options,
chars.begin().get(), chars.length(),
/* foldConstants = */ false, usedNames, nullptr,
nullptr, sourceObject);
nullptr, sourceObject, 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;

Просмотреть файл

@ -59,8 +59,9 @@ class MOZ_STACK_CLASS BytecodeCompiler
bool checkLength();
bool createScriptSource(const Maybe<uint32_t>& parameterListEnd);
bool canLazilyParse();
bool createParser();
bool createSourceAndParser(const Maybe<uint32_t>& parameterListEnd = Nothing());
bool createParser(ParseGoal goal);
bool createSourceAndParser(ParseGoal goal,
const 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
@ -215,7 +216,7 @@ BytecodeCompiler::canLazilyParse()
}
bool
BytecodeCompiler::createParser()
BytecodeCompiler::createParser(ParseGoal goal)
{
usedNames.emplace(cx);
if (!usedNames->init())
@ -224,23 +225,24 @@ BytecodeCompiler::createParser()
if (canLazilyParse()) {
syntaxParser.emplace(cx, alloc, options, sourceBuffer.get(), sourceBuffer.length(),
/* foldConstants = */ false, *usedNames, nullptr, nullptr,
sourceObject);
sourceObject, goal);
if (!syntaxParser->checkOptions())
return false;
}
parser.emplace(cx, alloc, options, sourceBuffer.get(), sourceBuffer.length(),
/* foldConstants = */ true, *usedNames, syntaxParser.ptrOr(nullptr), nullptr,
sourceObject);
sourceObject, goal);
parser->ss = scriptSource;
return parser->checkOptions();
}
bool
BytecodeCompiler::createSourceAndParser(const Maybe<uint32_t>& parameterListEnd /* = Nothing() */)
BytecodeCompiler::createSourceAndParser(ParseGoal goal,
const Maybe<uint32_t>& parameterListEnd /* = Nothing() */)
{
return createScriptSource(parameterListEnd) &&
createParser();
createParser(goal);
}
bool
@ -314,7 +316,7 @@ BytecodeCompiler::deoptimizeArgumentsInEnclosingScripts(JSContext* cx, HandleObj
JSScript*
BytecodeCompiler::compileScript(HandleObject environment, SharedContext* sc)
{
if (!createSourceAndParser())
if (!createSourceAndParser(ParseGoal::Script))
return nullptr;
TokenStreamPosition startPosition(keepAtoms, parser->tokenStream);
@ -390,7 +392,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;
TokenStreamPosition startPosition(keepAtoms, parser->tokenStream);
@ -780,7 +782,7 @@ frontend::CompileLazyFunction(JSContext* cx, Handle<LazyScript*> lazy, const cha
RootedScriptSourceObject sourceObject(cx, &lazy->sourceObject());
Parser<FullParseHandler, char16_t> parser(cx, cx->tempLifoAlloc(), options, chars, length,
/* foldConstants = */ true, usedNames, nullptr,
lazy, sourceObject);
lazy, sourceObject, lazy->parseGoal());
if (!parser.checkOptions())
return false;

Просмотреть файл

@ -3303,6 +3303,7 @@ BytecodeEmitter::checkSideEffects(ParseNode* pn, bool* answer)
// Trivial binary nodes with more token pos holders.
case ParseNodeKind::NewTarget:
case ParseNodeKind::ImportMeta:
MOZ_ASSERT(pn->isArity(PN_BINARY));
MOZ_ASSERT(pn->pn_left->isKind(ParseNodeKind::PosHolder));
MOZ_ASSERT(pn->pn_right->isKind(ParseNodeKind::PosHolder));
@ -11146,6 +11147,10 @@ BytecodeEmitter::emitTree(ParseNode* pn, ValueUsage valueUsage /* = ValueUsage::
return false;
break;
case ParseNodeKind::ImportMeta:
MOZ_CRASH("NYI");
break;
case ParseNodeKind::SetThis:
if (!emitSetThis(pn))
return false;

Просмотреть файл

@ -375,6 +375,7 @@ ContainsHoistedDeclaration(JSContext* cx, ParseNode* node, bool* result)
case ParseNodeKind::ClassMethodList:
case ParseNodeKind::ClassNames:
case ParseNodeKind::NewTarget:
case ParseNodeKind::ImportMeta:
case ParseNodeKind::PosHolder:
case ParseNodeKind::SuperCall:
case ParseNodeKind::SuperBase:
@ -1725,6 +1726,7 @@ Fold(JSContext* cx, ParseNode** pnp, PerHandlerParser<FullParseHandler>& parser)
Fold(cx, &pn->pn_right, parser);
case ParseNodeKind::NewTarget:
case ParseNodeKind::ImportMeta:
MOZ_ASSERT(pn->isArity(PN_BINARY));
MOZ_ASSERT(pn->pn_left->isKind(ParseNodeKind::PosHolder));
MOZ_ASSERT(pn->pn_right->isKind(ParseNodeKind::PosHolder));

Просмотреть файл

@ -560,6 +560,10 @@ class FullParseHandler
return new_<NullaryNode>(ParseNodeKind::ExportBatchSpec, JSOP_NOP, pos);
}
ParseNode* newImportMeta(ParseNode* importHolder, ParseNode* metaHolder) {
return new_<BinaryNode>(ParseNodeKind::ImportMeta, JSOP_NOP, importHolder, metaHolder);
}
ParseNode* newExprStatement(ParseNode* expr, uint32_t end) {
MOZ_ASSERT(expr->pn_pos.end <= end);
return new_<UnaryNode>(ParseNodeKind::ExpressionStatement,

Просмотреть файл

@ -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

Просмотреть файл

@ -417,6 +417,7 @@ class NameResolver
break;
case ParseNodeKind::NewTarget:
case ParseNodeKind::ImportMeta:
MOZ_ASSERT(cur->isArity(PN_BINARY));
MOZ_ASSERT(cur->pn_left->isKind(ParseNodeKind::PosHolder));
MOZ_ASSERT(cur->pn_right->isKind(ParseNodeKind::PosHolder));

Просмотреть файл

@ -132,6 +132,7 @@ class ObjectBox;
F(SuperBase) \
F(SuperCall) \
F(SetThis) \
F(ImportMeta) \
\
/* Unary operators. */ \
F(TypeOfName) \

Просмотреть файл

@ -800,7 +800,8 @@ ParserBase::ParserBase(JSContext* cx, LifoAlloc& alloc,
const ReadOnlyCompileOptions& options,
bool foldConstants,
UsedNameTracker& usedNames,
ScriptSourceObject* sourceObject)
ScriptSourceObject* sourceObject,
ParseGoal parseGoal)
: AutoGCRooter(cx, AutoGCRooter::Tag::Parser),
context(cx),
alloc(alloc),
@ -816,7 +817,8 @@ ParserBase::ParserBase(JSContext* cx, LifoAlloc& alloc,
checkOptionsCalled(false),
#endif
isUnexpectedEOF_(false),
awaitHandling_(AwaitIsName)
awaitHandling_(AwaitIsName),
parseGoal_(uint8_t(parseGoal))
{
cx->frontendCollectionPool().addActiveCompilation();
tempPoolMark = alloc.mark();
@ -853,8 +855,9 @@ PerHandlerParser<ParseHandler>::PerHandlerParser(JSContext* cx, LifoAlloc& alloc
const ReadOnlyCompileOptions& options,
bool foldConstants, UsedNameTracker& usedNames,
LazyScript* lazyOuterFunction,
ScriptSourceObject* sourceObject)
: ParserBase(cx, alloc, options, foldConstants, usedNames, sourceObject),
ScriptSourceObject* sourceObject,
ParseGoal parseGoal)
: ParserBase(cx, alloc, options, foldConstants, usedNames, sourceObject, parseGoal),
handler(cx, alloc, lazyOuterFunction)
{
@ -868,8 +871,9 @@ GeneralParser<ParseHandler, CharT>::GeneralParser(JSContext* cx, LifoAlloc& allo
UsedNameTracker& usedNames,
SyntaxParser* syntaxParser,
LazyScript* lazyOuterFunction,
ScriptSourceObject* sourceObject)
: Base(cx, alloc, options, foldConstants, usedNames, lazyOuterFunction, sourceObject),
ScriptSourceObject* sourceObject,
ParseGoal parseGoal)
: Base(cx, alloc, options, foldConstants, usedNames, lazyOuterFunction, sourceObject, parseGoal),
tokenStream(cx, options, chars, length)
{
// The Mozilla specific JSOPTION_EXTRA_WARNINGS option adds extra warnings
@ -2551,7 +2555,8 @@ PerHandlerParser<SyntaxParseHandler>::finishFunction(bool isStandaloneFunction /
pc->innerFunctionsForLazy,
funbox->bufStart, funbox->bufEnd,
funbox->toStringStart,
funbox->startLine, funbox->startColumn);
funbox->startLine, funbox->startColumn,
parseGoal());
if (!lazy)
return false;
@ -5351,6 +5356,22 @@ GeneralParser<ParseHandler, CharT>::importDeclaration()
return asFinalParser()->importDeclaration();
}
template <class ParseHandler, typename CharT>
inline typename ParseHandler::Node
GeneralParser<ParseHandler, CharT>::importDeclarationOrImportMeta(YieldHandling yieldHandling)
{
MOZ_ASSERT(anyChars.isCurrentTokenType(TokenKind::Import));
TokenKind tt;
if (!tokenStream.peekToken(&tt))
return null();
if (tt == TokenKind::Dot)
return expressionStatement(yieldHandling);
return importDeclaration();
}
template<typename CharT>
bool
Parser<FullParseHandler, CharT>::checkExportedName(JSAtom* exportName)
@ -7699,7 +7720,7 @@ GeneralParser<ParseHandler, CharT>::statement(YieldHandling yieldHandling)
// ImportDeclaration (only inside modules)
case TokenKind::Import:
return importDeclaration();
return importDeclarationOrImportMeta(yieldHandling);
// ExportDeclaration (only inside modules)
case TokenKind::Export:
@ -7892,7 +7913,7 @@ GeneralParser<ParseHandler, CharT>::statementListItem(YieldHandling yieldHandlin
// ImportDeclaration (only inside modules)
case TokenKind::Import:
return importDeclaration();
return importDeclarationOrImportMeta(yieldHandling);
// ExportDeclaration (only inside modules)
case TokenKind::Export:
@ -8714,6 +8735,10 @@ GeneralParser<ParseHandler, CharT>::memberExpr(YieldHandling yieldHandling,
lhs = handler.newSuperBase(thisName, pos());
if (!lhs)
return null();
} else if (tt == TokenKind::Import) {
lhs = importMeta();
if (!lhs)
return null();
} else {
lhs = primaryExpr(yieldHandling, tripledotHandling, tt, possibleError, invoked);
if (!lhs)
@ -9890,6 +9915,45 @@ GeneralParser<ParseHandler, CharT>::tryNewTarget(Node &newTarget)
return !!newTarget;
}
template <class ParseHandler, typename CharT>
typename ParseHandler::Node
GeneralParser<ParseHandler, CharT>::importMeta()
{
MOZ_ASSERT(anyChars.isCurrentTokenType(TokenKind::Import));
uint32_t begin = pos().begin;
if (parseGoal() != ParseGoal::Module) {
errorAt(begin, JSMSG_IMPORT_OUTSIDE_MODULE);
return null();
}
Node importHolder = handler.newPosHolder(pos());
if (!importHolder)
return null();
TokenKind next;
if (!tokenStream.getToken(&next))
return null();
if (next != TokenKind::Dot) {
error(JSMSG_UNEXPECTED_TOKEN, "dot", TokenKindToDesc(next));
return null();
}
if (!tokenStream.getToken(&next))
return null();
if (next != TokenKind::Meta) {
error(JSMSG_UNEXPECTED_TOKEN, "meta", TokenKindToDesc(next));
return null();
}
Node metaHolder = handler.newPosHolder(pos());
if (!metaHolder)
return null();
return handler.newImportMeta(importHolder, metaHolder);
}
template <class ParseHandler, typename CharT>
typename ParseHandler::Node
GeneralParser<ParseHandler, CharT>::primaryExpr(YieldHandling yieldHandling,

Просмотреть файл

@ -295,16 +295,22 @@ class MOZ_STACK_CLASS ParserBase
/* AwaitHandling */ uint8_t awaitHandling_:2;
/* ParseGoal */ uint8_t parseGoal_:1;
public:
bool awaitIsKeyword() const {
return awaitHandling_ != AwaitIsName;
}
ParseGoal parseGoal() const {
return ParseGoal(parseGoal_);
}
template<class, typename> friend class AutoAwaitIsKeyword;
ParserBase(JSContext* cx, LifoAlloc& alloc, const ReadOnlyCompileOptions& options,
bool foldConstants, UsedNameTracker& usedNames,
ScriptSourceObject* sourceObject);
ScriptSourceObject* sourceObject, ParseGoal parseGoal);
~ParserBase();
bool checkOptions();
@ -469,7 +475,8 @@ class MOZ_STACK_CLASS PerHandlerParser
PerHandlerParser(JSContext* cx, LifoAlloc& alloc, const ReadOnlyCompileOptions& options,
bool foldConstants, UsedNameTracker& usedNames,
LazyScript* lazyOuterFunction,
ScriptSourceObject* sourceObject);
ScriptSourceObject* sourceObject,
ParseGoal parseGoal);
static Node null() { return ParseHandler::null(); }
@ -662,6 +669,7 @@ class MOZ_STACK_CLASS GeneralParser
using Base::alloc;
using Base::awaitIsKeyword;
using Base::parseGoal;
#if DEBUG
using Base::checkOptionsCalled;
#endif
@ -872,7 +880,8 @@ class MOZ_STACK_CLASS GeneralParser
const CharT* chars, size_t length, bool foldConstants,
UsedNameTracker& usedNames, SyntaxParser* syntaxParser,
LazyScript* lazyOuterFunction,
ScriptSourceObject* sourceObject);
ScriptSourceObject* sourceObject,
ParseGoal parseGoal);
inline void setAwaitHandling(AwaitHandling awaitHandling);
@ -1013,6 +1022,7 @@ class MOZ_STACK_CLASS GeneralParser
Node lexicalDeclaration(YieldHandling yieldHandling, DeclarationKind kind);
inline Node importDeclaration();
Node importDeclarationOrImportMeta(YieldHandling yieldHandling);
Node exportFrom(uint32_t begin, Node specList);
Node exportBatch(uint32_t begin);
@ -1112,6 +1122,8 @@ class MOZ_STACK_CLASS GeneralParser
bool tryNewTarget(Node& newTarget);
Node importMeta();
Node methodDefinition(uint32_t toStringStart, PropertyType propType, HandleAtom funName);
/*

Просмотреть файл

@ -66,6 +66,7 @@
macro(from, from, TokenKind::From) \
macro(get, get, TokenKind::Get) \
macro(let, let, TokenKind::Let) \
macro(meta, meta, TokenKind::Meta) \
macro(of, of, TokenKind::Of) \
macro(set, set, TokenKind::Set) \
macro(static, static_, TokenKind::Static) \

Просмотреть файл

@ -297,6 +297,9 @@ class SyntaxParseHandler
Node newExportBatchSpec(const TokenPos& pos) {
return NodeGeneric;
}
Node newImportMeta(Node importHolder, Node metaHolder) {
return NodeGeneric;
}
Node newSetThis(Node thisName, Node value) { return value; }

Просмотреть файл

@ -127,6 +127,7 @@
macro(From, "'from'") \
macro(Get, "'get'") \
macro(Let, "'let'") \
macro(Meta, "'meta'") \
macro(Of, "'of'") \
macro(Set, "'set'") \
macro(Static, "'static'") \

Просмотреть файл

@ -0,0 +1,97 @@
load(libdir + "match.js");
load(libdir + "asserts.js");
var { Pattern, MatchError } = Match;
program = (elts) => Pattern({
type: "Program",
body: elts
});
expressionStatement = (expression) => Pattern({
type: "ExpressionStatement",
expression: expression
});
assignmentExpression = (left, operator, right) => Pattern({
type: "AssignmentExpression",
operator: operator,
left: left,
right: right
});
ident = (name) => Pattern({
type: "Identifier",
name: name
});
metaProperty = (meta, property) => Pattern({
type: "MetaProperty",
meta: meta,
property: property
});
memberExpression = (object, property) => Pattern({
type: "MemberExpression",
object: object,
property: property
});
function parseAsModule(source)
{
return Reflect.parse(source, {target: "module"});
}
program([
expressionStatement(
metaProperty(
ident("import"),
ident("meta")
)
)
]).assert(parseAsModule("import.meta;"));
program([
expressionStatement(
assignmentExpression(
ident("x"),
"=",
metaProperty(
ident("import"),
ident("meta")
)
)
)
]).assert(parseAsModule("x = import.meta;"));
program([
expressionStatement(
assignmentExpression(
memberExpression(
metaProperty(
ident("import"),
ident("meta")
),
ident("foo")
),
"=",
ident("x"),
)
)
]).assert(parseAsModule("import.meta.foo = x;"));
function assertModuleParseThrowsSyntaxError(source)
{
assertThrowsInstanceOf(() => parseAsModule(source), SyntaxError);
}
function assertModuleParseThrowsReferenceError(source)
{
assertThrowsInstanceOf(() => parseAsModule(source), ReferenceError);
}
assertModuleParseThrowsSyntaxError("import");
assertModuleParseThrowsSyntaxError("import.");
assertModuleParseThrowsSyntaxError("import.met");
assertModuleParseThrowsSyntaxError("import.metaa");
assertModuleParseThrowsSyntaxError("x = import");
assertModuleParseThrowsSyntaxError("x = import.");
assertModuleParseThrowsSyntaxError("x = import.met");
assertModuleParseThrowsSyntaxError("x = import.metaa");
assertModuleParseThrowsReferenceError("import.meta = x");

Просмотреть файл

@ -261,6 +261,7 @@ MSG_DEF(JSMSG_GARBAGE_AFTER_INPUT, 2, JSEXN_SYNTAXERR, "unexpected garbage a
MSG_DEF(JSMSG_IDSTART_AFTER_NUMBER, 0, JSEXN_SYNTAXERR, "identifier starts immediately after numeric literal")
MSG_DEF(JSMSG_BAD_ESCAPE, 0, JSEXN_SYNTAXERR, "invalid escape sequence")
MSG_DEF(JSMSG_ILLEGAL_CHARACTER, 0, JSEXN_SYNTAXERR, "illegal character")
MSG_DEF(JSMSG_IMPORT_OUTSIDE_MODULE, 0, JSEXN_SYNTAXERR, "the import keyword 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")

Просмотреть файл

@ -177,7 +177,7 @@ runTestFromPath(JSContext* cx, const char* path)
js::frontend::Parser<js::frontend::FullParseHandler, char16_t> txtParser(
cx, allocScope.alloc(), txtOptions, txtSource.begin(), txtSource.length(),
/* foldConstants = */ false, txtUsedNames, nullptr,
nullptr, sourceObject);
nullptr, sourceObject, frontend::ParseGoal::Script);
if (!txtParser.checkOptions())
MOZ_CRASH("Bad options");

Просмотреть файл

@ -4479,7 +4479,8 @@ JS_BufferIsCompilableUnit(JSContext* cx, HandleObject obj, const char* utf8, siz
options, chars, length,
/* foldConstants = */ true,
usedNames, nullptr, nullptr,
sourceObject);
sourceObject,
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

Просмотреть файл

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

Просмотреть файл

@ -230,6 +230,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") \

Просмотреть файл

@ -5061,7 +5061,8 @@ Debugger::isCompilableUnit(JSContext* cx, unsigned argc, Value* vp)
length,
/* foldConstants = */ true,
usedNames, nullptr, nullptr,
sourceObject);
sourceObject,
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

Просмотреть файл

@ -4302,7 +4302,8 @@ LazyScript::Create(JSContext* cx, HandleFunction fun,
const frontend::AtomVector& closedOverBindings,
Handle<GCVector<JSFunction*, 8>> innerFunctions,
uint32_t sourceStart, uint32_t sourceEnd,
uint32_t toStringStart, uint32_t lineno, uint32_t column)
uint32_t toStringStart, uint32_t lineno, uint32_t column,
frontend::ParseGoal parseGoal)
{
union {
PackedView p;
@ -4323,6 +4324,7 @@ LazyScript::Create(JSContext* cx, HandleFunction fun,
p.isLikelyConstructorWrapper = false;
p.isDerivedClassConstructor = false;
p.needsHomeObject = false;
p.parseGoal = uint32_t(parseGoal);
LazyScript* res = LazyScript::CreateRaw(cx, fun, sourceObject, packedFields,
sourceStart, sourceEnd,

Просмотреть файл

@ -2187,6 +2187,7 @@ class LazyScript : public gc::TenuredCell
uint32_t isDerivedClassConstructor : 1;
uint32_t needsHomeObject : 1;
uint32_t hasRest : 1;
uint32_t parseGoal : 1;
};
union {
@ -2229,7 +2230,8 @@ class LazyScript : public gc::TenuredCell
const frontend::AtomVector& closedOverBindings,
Handle<GCVector<JSFunction*, 8>> innerFunctions,
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
@ -2326,6 +2328,10 @@ class LazyScript : public gc::TenuredCell
p_.hasRest = true;
}
frontend::ParseGoal parseGoal() const {
return frontend::ParseGoal(p_.parseGoal);
}
bool strict() const {
return p_.strict;
}