Introduce ParserBase for common code between parser and pre-parser.
R=ulan@chromium.org Review URL: https://codereview.chromium.org/27182002 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@17202 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
parent
71ba8c5fb4
commit
caf2884222
@ -536,7 +536,8 @@ Parser::FunctionState::~FunctionState() {
|
||||
// Implementation of Parser
|
||||
|
||||
Parser::Parser(CompilationInfo* info)
|
||||
: isolate_(info->isolate()),
|
||||
: ParserBase(&scanner_, info->isolate()->stack_guard()->real_climit()),
|
||||
isolate_(info->isolate()),
|
||||
symbol_cache_(0, info->zone()),
|
||||
script_(info->script()),
|
||||
scanner_(isolate_->unicode_cache()),
|
||||
@ -548,11 +549,6 @@ Parser::Parser(CompilationInfo* info)
|
||||
extension_(info->extension()),
|
||||
pre_parse_data_(NULL),
|
||||
fni_(NULL),
|
||||
allow_natives_syntax_(false),
|
||||
allow_lazy_(false),
|
||||
allow_generators_(false),
|
||||
allow_for_of_(false),
|
||||
stack_overflow_(false),
|
||||
parenthesized_function_(false),
|
||||
zone_(info->zone()),
|
||||
info_(info) {
|
||||
@ -690,7 +686,7 @@ FunctionLiteral* Parser::DoParseProgram(CompilationInfo* info,
|
||||
result->set_ast_properties(factory()->visitor()->ast_properties());
|
||||
result->set_dont_optimize_reason(
|
||||
factory()->visitor()->dont_optimize_reason());
|
||||
} else if (stack_overflow_) {
|
||||
} else if (stack_overflow()) {
|
||||
isolate()->StackOverflow();
|
||||
}
|
||||
}
|
||||
@ -787,7 +783,7 @@ FunctionLiteral* Parser::ParseLazy(Utf16CharacterStream* source) {
|
||||
ASSERT(target_stack_ == NULL);
|
||||
|
||||
if (result == NULL) {
|
||||
if (stack_overflow_) isolate()->StackOverflow();
|
||||
if (stack_overflow()) isolate()->StackOverflow();
|
||||
} else {
|
||||
Handle<String> inferred_name(shared_info->inferred_name());
|
||||
result->set_inferred_name(inferred_name);
|
||||
@ -3484,7 +3480,7 @@ void Parser::ReportUnexpectedToken(Token::Value token) {
|
||||
// We don't report stack overflows here, to avoid increasing the
|
||||
// stack depth even further. Instead we report it after parsing is
|
||||
// over, in ParseProgram/ParseJson.
|
||||
if (token == Token::ILLEGAL && stack_overflow_) return;
|
||||
if (token == Token::ILLEGAL && stack_overflow()) return;
|
||||
// Four of the tokens are treated specially
|
||||
switch (token) {
|
||||
case Token::EOS:
|
||||
@ -4378,7 +4374,7 @@ FunctionLiteral* Parser::ParseFunctionLiteral(
|
||||
PreParser::PreParseResult result = LazyParseFunctionLiteral(&logger);
|
||||
if (result == PreParser::kPreParseStackOverflow) {
|
||||
// Propagate stack overflow.
|
||||
stack_overflow_ = true;
|
||||
set_stack_overflow();
|
||||
*ok = false;
|
||||
return NULL;
|
||||
}
|
||||
@ -4613,7 +4609,7 @@ Expression* Parser::ParseV8Intrinsic(bool* ok) {
|
||||
}
|
||||
|
||||
|
||||
bool Parser::peek_any_identifier() {
|
||||
bool ParserBase::peek_any_identifier() {
|
||||
Token::Value next = peek();
|
||||
return next == Token::IDENTIFIER ||
|
||||
next == Token::FUTURE_RESERVED_WORD ||
|
||||
@ -4622,32 +4618,6 @@ bool Parser::peek_any_identifier() {
|
||||
}
|
||||
|
||||
|
||||
void Parser::Consume(Token::Value token) {
|
||||
Token::Value next = Next();
|
||||
USE(next);
|
||||
USE(token);
|
||||
ASSERT(next == token);
|
||||
}
|
||||
|
||||
|
||||
void Parser::Expect(Token::Value token, bool* ok) {
|
||||
Token::Value next = Next();
|
||||
if (next == token) return;
|
||||
ReportUnexpectedToken(next);
|
||||
*ok = false;
|
||||
}
|
||||
|
||||
|
||||
bool Parser::Check(Token::Value token) {
|
||||
Token::Value next = peek();
|
||||
if (next == token) {
|
||||
Consume(next);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
bool Parser::CheckContextualKeyword(Vector<const char> keyword) {
|
||||
if (peek() == Token::IDENTIFIER &&
|
||||
scanner().is_next_contextual_keyword(keyword)) {
|
||||
@ -4658,7 +4628,7 @@ bool Parser::CheckContextualKeyword(Vector<const char> keyword) {
|
||||
}
|
||||
|
||||
|
||||
void Parser::ExpectSemicolon(bool* ok) {
|
||||
void ParserBase::ExpectSemicolon(bool* ok) {
|
||||
// Check for automatic semicolon insertion according to
|
||||
// the rules given in ECMA-262, section 7.9, page 21.
|
||||
Token::Value tok = peek();
|
||||
@ -4666,7 +4636,7 @@ void Parser::ExpectSemicolon(bool* ok) {
|
||||
Next();
|
||||
return;
|
||||
}
|
||||
if (scanner().HasAnyLineTerminatorBeforeNext() ||
|
||||
if (scanner()->HasAnyLineTerminatorBeforeNext() ||
|
||||
tok == Token::RBRACE ||
|
||||
tok == Token::EOS) {
|
||||
return;
|
||||
|
56
src/parser.h
56
src/parser.h
@ -425,7 +425,7 @@ class RegExpParser BASE_EMBEDDED {
|
||||
// Forward declaration.
|
||||
class SingletonLogger;
|
||||
|
||||
class Parser BASE_EMBEDDED {
|
||||
class Parser : public ParserBase {
|
||||
public:
|
||||
explicit Parser(CompilationInfo* info);
|
||||
~Parser() {
|
||||
@ -433,28 +433,6 @@ class Parser BASE_EMBEDDED {
|
||||
reusable_preparser_ = NULL;
|
||||
}
|
||||
|
||||
bool allow_natives_syntax() const { return allow_natives_syntax_; }
|
||||
bool allow_lazy() const { return allow_lazy_; }
|
||||
bool allow_modules() { return scanner().HarmonyModules(); }
|
||||
bool allow_harmony_scoping() { return scanner().HarmonyScoping(); }
|
||||
bool allow_generators() const { return allow_generators_; }
|
||||
bool allow_for_of() const { return allow_for_of_; }
|
||||
bool allow_harmony_numeric_literals() {
|
||||
return scanner().HarmonyNumericLiterals();
|
||||
}
|
||||
|
||||
void set_allow_natives_syntax(bool allow) { allow_natives_syntax_ = allow; }
|
||||
void set_allow_lazy(bool allow) { allow_lazy_ = allow; }
|
||||
void set_allow_modules(bool allow) { scanner().SetHarmonyModules(allow); }
|
||||
void set_allow_harmony_scoping(bool allow) {
|
||||
scanner().SetHarmonyScoping(allow);
|
||||
}
|
||||
void set_allow_generators(bool allow) { allow_generators_ = allow; }
|
||||
void set_allow_for_of(bool allow) { allow_for_of_ = allow; }
|
||||
void set_allow_harmony_numeric_literals(bool allow) {
|
||||
scanner().SetHarmonyNumericLiterals(allow);
|
||||
}
|
||||
|
||||
// Parses the source code represented by the compilation info and sets its
|
||||
// function literal. Returns false (and deallocates any allocated AST
|
||||
// nodes) if parsing failed.
|
||||
@ -712,37 +690,10 @@ class Parser BASE_EMBEDDED {
|
||||
// Magical syntax support.
|
||||
Expression* ParseV8Intrinsic(bool* ok);
|
||||
|
||||
INLINE(Token::Value peek()) {
|
||||
if (stack_overflow_) return Token::ILLEGAL;
|
||||
return scanner().peek();
|
||||
}
|
||||
|
||||
INLINE(Token::Value Next()) {
|
||||
// BUG 1215673: Find a thread safe way to set a stack limit in
|
||||
// pre-parse mode. Otherwise, we cannot safely pre-parse from other
|
||||
// threads.
|
||||
if (stack_overflow_) {
|
||||
return Token::ILLEGAL;
|
||||
}
|
||||
if (StackLimitCheck(isolate()).HasOverflowed()) {
|
||||
// Any further calls to Next or peek will return the illegal token.
|
||||
// The current call must return the next token, which might already
|
||||
// have been peek'ed.
|
||||
stack_overflow_ = true;
|
||||
}
|
||||
return scanner().Next();
|
||||
}
|
||||
|
||||
bool is_generator() const { return current_function_state_->is_generator(); }
|
||||
|
||||
bool CheckInOrOf(bool accept_OF, ForEachStatement::VisitMode* visit_mode);
|
||||
|
||||
bool peek_any_identifier();
|
||||
|
||||
INLINE(void Consume(Token::Value token));
|
||||
void Expect(Token::Value token, bool* ok);
|
||||
bool Check(Token::Value token);
|
||||
void ExpectSemicolon(bool* ok);
|
||||
bool CheckContextualKeyword(Vector<const char> keyword);
|
||||
void ExpectContextualKeyword(Vector<const char> keyword, bool* ok);
|
||||
|
||||
@ -865,11 +816,6 @@ class Parser BASE_EMBEDDED {
|
||||
FuncNameInferrer* fni_;
|
||||
|
||||
Mode mode_;
|
||||
bool allow_natives_syntax_;
|
||||
bool allow_lazy_;
|
||||
bool allow_generators_;
|
||||
bool allow_for_of_;
|
||||
bool stack_overflow_;
|
||||
// If true, the next (and immediately following) function literal is
|
||||
// preceded by a parenthesis.
|
||||
// Heuristically that means that the function will be called immediately,
|
||||
|
179
src/preparser.cc
179
src/preparser.cc
@ -63,17 +63,17 @@ PreParser::PreParseResult PreParser::PreParseLazyFunction(
|
||||
set_language_mode(mode);
|
||||
Scope function_scope(&scope_, kFunctionScope);
|
||||
function_scope.set_is_generator(is_generator);
|
||||
ASSERT_EQ(i::Token::LBRACE, scanner_->current_token());
|
||||
ASSERT_EQ(i::Token::LBRACE, scanner()->current_token());
|
||||
bool ok = true;
|
||||
int start_position = scanner_->peek_location().beg_pos;
|
||||
int start_position = scanner()->peek_location().beg_pos;
|
||||
ParseLazyFunctionLiteralBody(&ok);
|
||||
if (stack_overflow_) return kPreParseStackOverflow;
|
||||
if (stack_overflow()) return kPreParseStackOverflow;
|
||||
if (!ok) {
|
||||
ReportUnexpectedToken(scanner_->current_token());
|
||||
ReportUnexpectedToken(scanner()->current_token());
|
||||
} else {
|
||||
ASSERT_EQ(i::Token::RBRACE, scanner_->peek());
|
||||
ASSERT_EQ(i::Token::RBRACE, scanner()->peek());
|
||||
if (!is_classic_mode()) {
|
||||
int end_pos = scanner_->location().end_pos;
|
||||
int end_pos = scanner()->location().end_pos;
|
||||
CheckOctalLiteral(start_position, end_pos, &ok);
|
||||
if (ok) {
|
||||
CheckDelayedStrictModeViolation(start_position, end_pos, &ok);
|
||||
@ -101,10 +101,10 @@ void PreParser::ReportUnexpectedToken(i::Token::Value token) {
|
||||
// We don't report stack overflows here, to avoid increasing the
|
||||
// stack depth even further. Instead we report it after parsing is
|
||||
// over, in ParseProgram.
|
||||
if (token == i::Token::ILLEGAL && stack_overflow_) {
|
||||
if (token == i::Token::ILLEGAL && stack_overflow()) {
|
||||
return;
|
||||
}
|
||||
i::Scanner::Location source_location = scanner_->location();
|
||||
i::Scanner::Location source_location = scanner()->location();
|
||||
|
||||
// Four of the tokens are treated specially
|
||||
switch (token) {
|
||||
@ -132,10 +132,10 @@ void PreParser::ReportUnexpectedToken(i::Token::Value token) {
|
||||
// Checks whether octal literal last seen is between beg_pos and end_pos.
|
||||
// If so, reports an error.
|
||||
void PreParser::CheckOctalLiteral(int beg_pos, int end_pos, bool* ok) {
|
||||
i::Scanner::Location octal = scanner_->octal_position();
|
||||
i::Scanner::Location octal = scanner()->octal_position();
|
||||
if (beg_pos <= octal.beg_pos && octal.end_pos <= end_pos) {
|
||||
ReportMessageAt(octal, "strict_octal_literal", NULL);
|
||||
scanner_->clear_octal_position();
|
||||
scanner()->clear_octal_position();
|
||||
*ok = false;
|
||||
}
|
||||
}
|
||||
@ -274,9 +274,9 @@ PreParser::Statement PreParser::ParseStatement(bool* ok) {
|
||||
return ParseTryStatement(ok);
|
||||
|
||||
case i::Token::FUNCTION: {
|
||||
i::Scanner::Location start_location = scanner_->peek_location();
|
||||
i::Scanner::Location start_location = scanner()->peek_location();
|
||||
Statement statement = ParseFunctionDeclaration(CHECK_OK);
|
||||
i::Scanner::Location end_location = scanner_->location();
|
||||
i::Scanner::Location end_location = scanner()->location();
|
||||
if (!is_classic_mode()) {
|
||||
ReportMessageAt(start_location.beg_pos, end_location.end_pos,
|
||||
"strict_function", NULL);
|
||||
@ -304,9 +304,9 @@ PreParser::Statement PreParser::ParseFunctionDeclaration(bool* ok) {
|
||||
// '{' FunctionBody '}'
|
||||
Expect(i::Token::FUNCTION, CHECK_OK);
|
||||
|
||||
bool is_generator = allow_generators_ && Check(i::Token::MUL);
|
||||
bool is_generator = allow_generators() && Check(i::Token::MUL);
|
||||
Identifier identifier = ParseIdentifier(CHECK_OK);
|
||||
i::Scanner::Location location = scanner_->location();
|
||||
i::Scanner::Location location = scanner()->location();
|
||||
|
||||
Expression function_value = ParseFunctionLiteral(is_generator, CHECK_OK);
|
||||
|
||||
@ -402,7 +402,7 @@ PreParser::Statement PreParser::ParseVariableDeclarations(
|
||||
case i::CLASSIC_MODE:
|
||||
break;
|
||||
case i::STRICT_MODE: {
|
||||
i::Scanner::Location location = scanner_->peek_location();
|
||||
i::Scanner::Location location = scanner()->peek_location();
|
||||
ReportMessageAt(location, "strict_const", NULL);
|
||||
*ok = false;
|
||||
return Statement::Default();
|
||||
@ -410,7 +410,7 @@ PreParser::Statement PreParser::ParseVariableDeclarations(
|
||||
case i::EXTENDED_MODE:
|
||||
if (var_context != kSourceElement &&
|
||||
var_context != kForStatement) {
|
||||
i::Scanner::Location location = scanner_->peek_location();
|
||||
i::Scanner::Location location = scanner()->peek_location();
|
||||
ReportMessageAt(location.beg_pos, location.end_pos,
|
||||
"unprotected_const", NULL);
|
||||
*ok = false;
|
||||
@ -427,7 +427,7 @@ PreParser::Statement PreParser::ParseVariableDeclarations(
|
||||
// * It is a Syntax Error if the code that matches this production is not
|
||||
// contained in extended code.
|
||||
if (!is_extended_mode()) {
|
||||
i::Scanner::Location location = scanner_->peek_location();
|
||||
i::Scanner::Location location = scanner()->peek_location();
|
||||
ReportMessageAt(location.beg_pos, location.end_pos,
|
||||
"illegal_let", NULL);
|
||||
*ok = false;
|
||||
@ -436,7 +436,7 @@ PreParser::Statement PreParser::ParseVariableDeclarations(
|
||||
Consume(i::Token::LET);
|
||||
if (var_context != kSourceElement &&
|
||||
var_context != kForStatement) {
|
||||
i::Scanner::Location location = scanner_->peek_location();
|
||||
i::Scanner::Location location = scanner()->peek_location();
|
||||
ReportMessageAt(location.beg_pos, location.end_pos,
|
||||
"unprotected_let", NULL);
|
||||
*ok = false;
|
||||
@ -457,7 +457,7 @@ PreParser::Statement PreParser::ParseVariableDeclarations(
|
||||
if (nvars > 0) Consume(i::Token::COMMA);
|
||||
Identifier identifier = ParseIdentifier(CHECK_OK);
|
||||
if (!is_classic_mode() && !identifier.IsValidStrictVariable()) {
|
||||
StrictModeIdentifierViolation(scanner_->location(),
|
||||
StrictModeIdentifierViolation(scanner()->location(),
|
||||
"strict_var_name",
|
||||
identifier,
|
||||
ok);
|
||||
@ -524,7 +524,7 @@ PreParser::Statement PreParser::ParseContinueStatement(bool* ok) {
|
||||
|
||||
Expect(i::Token::CONTINUE, CHECK_OK);
|
||||
i::Token::Value tok = peek();
|
||||
if (!scanner_->HasAnyLineTerminatorBeforeNext() &&
|
||||
if (!scanner()->HasAnyLineTerminatorBeforeNext() &&
|
||||
tok != i::Token::SEMICOLON &&
|
||||
tok != i::Token::RBRACE &&
|
||||
tok != i::Token::EOS) {
|
||||
@ -541,7 +541,7 @@ PreParser::Statement PreParser::ParseBreakStatement(bool* ok) {
|
||||
|
||||
Expect(i::Token::BREAK, CHECK_OK);
|
||||
i::Token::Value tok = peek();
|
||||
if (!scanner_->HasAnyLineTerminatorBeforeNext() &&
|
||||
if (!scanner()->HasAnyLineTerminatorBeforeNext() &&
|
||||
tok != i::Token::SEMICOLON &&
|
||||
tok != i::Token::RBRACE &&
|
||||
tok != i::Token::EOS) {
|
||||
@ -567,7 +567,7 @@ PreParser::Statement PreParser::ParseReturnStatement(bool* ok) {
|
||||
// This is not handled during preparsing.
|
||||
|
||||
i::Token::Value tok = peek();
|
||||
if (!scanner_->HasAnyLineTerminatorBeforeNext() &&
|
||||
if (!scanner()->HasAnyLineTerminatorBeforeNext() &&
|
||||
tok != i::Token::SEMICOLON &&
|
||||
tok != i::Token::RBRACE &&
|
||||
tok != i::Token::EOS) {
|
||||
@ -583,7 +583,7 @@ PreParser::Statement PreParser::ParseWithStatement(bool* ok) {
|
||||
// 'with' '(' Expression ')' Statement
|
||||
Expect(i::Token::WITH, CHECK_OK);
|
||||
if (!is_classic_mode()) {
|
||||
i::Scanner::Location location = scanner_->location();
|
||||
i::Scanner::Location location = scanner()->location();
|
||||
ReportMessageAt(location, "strict_mode_with", NULL);
|
||||
*ok = false;
|
||||
return Statement::Default();
|
||||
@ -661,7 +661,7 @@ PreParser::Statement PreParser::ParseWhileStatement(bool* ok) {
|
||||
bool PreParser::CheckInOrOf(bool accept_OF) {
|
||||
if (peek() == i::Token::IN ||
|
||||
(allow_for_of() && accept_OF && peek() == i::Token::IDENTIFIER &&
|
||||
scanner_->is_next_contextual_keyword(v8::internal::CStrVector("of")))) {
|
||||
scanner()->is_next_contextual_keyword(v8::internal::CStrVector("of")))) {
|
||||
Next();
|
||||
return true;
|
||||
}
|
||||
@ -728,8 +728,8 @@ PreParser::Statement PreParser::ParseThrowStatement(bool* ok) {
|
||||
// 'throw' [no line terminator] Expression ';'
|
||||
|
||||
Expect(i::Token::THROW, CHECK_OK);
|
||||
if (scanner_->HasAnyLineTerminatorBeforeNext()) {
|
||||
i::Scanner::Location pos = scanner_->location();
|
||||
if (scanner()->HasAnyLineTerminatorBeforeNext()) {
|
||||
i::Scanner::Location pos = scanner()->location();
|
||||
ReportMessageAt(pos, "newline_after_throw", NULL);
|
||||
*ok = false;
|
||||
return Statement::Default();
|
||||
@ -765,7 +765,7 @@ PreParser::Statement PreParser::ParseTryStatement(bool* ok) {
|
||||
Expect(i::Token::LPAREN, CHECK_OK);
|
||||
Identifier id = ParseIdentifier(CHECK_OK);
|
||||
if (!is_classic_mode() && !id.IsValidStrictVariable()) {
|
||||
StrictModeIdentifierViolation(scanner_->location(),
|
||||
StrictModeIdentifierViolation(scanner()->location(),
|
||||
"strict_catch_variable",
|
||||
id,
|
||||
ok);
|
||||
@ -838,7 +838,7 @@ PreParser::Expression PreParser::ParseAssignmentExpression(bool accept_IN,
|
||||
return ParseYieldExpression(ok);
|
||||
}
|
||||
|
||||
i::Scanner::Location before = scanner_->peek_location();
|
||||
i::Scanner::Location before = scanner()->peek_location();
|
||||
Expression expression = ParseConditionalExpression(accept_IN, CHECK_OK);
|
||||
|
||||
if (!i::Token::IsAssignmentOp(peek())) {
|
||||
@ -849,7 +849,7 @@ PreParser::Expression PreParser::ParseAssignmentExpression(bool accept_IN,
|
||||
if (!is_classic_mode() &&
|
||||
expression.IsIdentifier() &&
|
||||
expression.AsIdentifier().IsEvalOrArguments()) {
|
||||
i::Scanner::Location after = scanner_->location();
|
||||
i::Scanner::Location after = scanner()->location();
|
||||
ReportMessageAt(before.beg_pos, after.end_pos,
|
||||
"strict_lhs_assignment", NULL);
|
||||
*ok = false;
|
||||
@ -946,12 +946,12 @@ PreParser::Expression PreParser::ParseUnaryExpression(bool* ok) {
|
||||
return Expression::Default();
|
||||
} else if (i::Token::IsCountOp(op)) {
|
||||
op = Next();
|
||||
i::Scanner::Location before = scanner_->peek_location();
|
||||
i::Scanner::Location before = scanner()->peek_location();
|
||||
Expression expression = ParseUnaryExpression(CHECK_OK);
|
||||
if (!is_classic_mode() &&
|
||||
expression.IsIdentifier() &&
|
||||
expression.AsIdentifier().IsEvalOrArguments()) {
|
||||
i::Scanner::Location after = scanner_->location();
|
||||
i::Scanner::Location after = scanner()->location();
|
||||
ReportMessageAt(before.beg_pos, after.end_pos,
|
||||
"strict_lhs_prefix", NULL);
|
||||
*ok = false;
|
||||
@ -967,14 +967,14 @@ PreParser::Expression PreParser::ParsePostfixExpression(bool* ok) {
|
||||
// PostfixExpression ::
|
||||
// LeftHandSideExpression ('++' | '--')?
|
||||
|
||||
i::Scanner::Location before = scanner_->peek_location();
|
||||
i::Scanner::Location before = scanner()->peek_location();
|
||||
Expression expression = ParseLeftHandSideExpression(CHECK_OK);
|
||||
if (!scanner_->HasAnyLineTerminatorBeforeNext() &&
|
||||
if (!scanner()->HasAnyLineTerminatorBeforeNext() &&
|
||||
i::Token::IsCountOp(peek())) {
|
||||
if (!is_classic_mode() &&
|
||||
expression.IsIdentifier() &&
|
||||
expression.AsIdentifier().IsEvalOrArguments()) {
|
||||
i::Scanner::Location after = scanner_->location();
|
||||
i::Scanner::Location after = scanner()->location();
|
||||
ReportMessageAt(before.beg_pos, after.end_pos,
|
||||
"strict_lhs_postfix", NULL);
|
||||
*ok = false;
|
||||
@ -1074,14 +1074,14 @@ PreParser::Expression PreParser::ParseMemberWithNewPrefixesExpression(
|
||||
if (peek() == i::Token::FUNCTION) {
|
||||
Consume(i::Token::FUNCTION);
|
||||
|
||||
bool is_generator = allow_generators_ && Check(i::Token::MUL);
|
||||
bool is_generator = allow_generators() && Check(i::Token::MUL);
|
||||
Identifier identifier = Identifier::Default();
|
||||
if (peek_any_identifier()) {
|
||||
identifier = ParseIdentifier(CHECK_OK);
|
||||
}
|
||||
result = ParseFunctionLiteral(is_generator, CHECK_OK);
|
||||
if (result.IsStrictFunction() && !identifier.IsValidStrictVariable()) {
|
||||
StrictModeIdentifierViolation(scanner_->location(),
|
||||
StrictModeIdentifierViolation(scanner()->location(),
|
||||
"strict_function_name",
|
||||
identifier,
|
||||
ok);
|
||||
@ -1238,7 +1238,7 @@ PreParser::Expression PreParser::ParseObjectLiteral(bool* ok) {
|
||||
// | (('get' | 'set') (IdentifierName | String | Number) FunctionLiteral)
|
||||
// )*[','] '}'
|
||||
|
||||
i::ObjectLiteralChecker<PreParser> checker(this, scanner_, language_mode());
|
||||
i::ObjectLiteralChecker<PreParser> checker(this, scanner(), language_mode());
|
||||
|
||||
Expect(i::Token::LBRACE, CHECK_OK);
|
||||
while (peek() != i::Token::RBRACE) {
|
||||
@ -1312,18 +1312,18 @@ PreParser::Expression PreParser::ParseObjectLiteral(bool* ok) {
|
||||
|
||||
PreParser::Expression PreParser::ParseRegExpLiteral(bool seen_equal,
|
||||
bool* ok) {
|
||||
if (!scanner_->ScanRegExpPattern(seen_equal)) {
|
||||
if (!scanner()->ScanRegExpPattern(seen_equal)) {
|
||||
Next();
|
||||
ReportMessageAt(scanner_->location(), "unterminated_regexp", NULL);
|
||||
ReportMessageAt(scanner()->location(), "unterminated_regexp", NULL);
|
||||
*ok = false;
|
||||
return Expression::Default();
|
||||
}
|
||||
|
||||
scope_->NextMaterializedLiteralIndex();
|
||||
|
||||
if (!scanner_->ScanRegExpFlags()) {
|
||||
if (!scanner()->ScanRegExpFlags()) {
|
||||
Next();
|
||||
ReportMessageAt(scanner_->location(), "invalid_regexp_flags", NULL);
|
||||
ReportMessageAt(scanner()->location(), "invalid_regexp_flags", NULL);
|
||||
*ok = false;
|
||||
return Expression::Default();
|
||||
}
|
||||
@ -1368,28 +1368,28 @@ PreParser::Expression PreParser::ParseFunctionLiteral(bool is_generator,
|
||||
// FormalParameterList ::
|
||||
// '(' (Identifier)*[','] ')'
|
||||
Expect(i::Token::LPAREN, CHECK_OK);
|
||||
int start_position = scanner_->location().beg_pos;
|
||||
int start_position = scanner()->location().beg_pos;
|
||||
bool done = (peek() == i::Token::RPAREN);
|
||||
i::DuplicateFinder duplicate_finder(scanner_->unicode_cache());
|
||||
i::DuplicateFinder duplicate_finder(scanner()->unicode_cache());
|
||||
while (!done) {
|
||||
Identifier id = ParseIdentifier(CHECK_OK);
|
||||
if (!id.IsValidStrictVariable()) {
|
||||
StrictModeIdentifierViolation(scanner_->location(),
|
||||
StrictModeIdentifierViolation(scanner()->location(),
|
||||
"strict_param_name",
|
||||
id,
|
||||
CHECK_OK);
|
||||
}
|
||||
int prev_value;
|
||||
if (scanner_->is_literal_ascii()) {
|
||||
if (scanner()->is_literal_ascii()) {
|
||||
prev_value =
|
||||
duplicate_finder.AddAsciiSymbol(scanner_->literal_ascii_string(), 1);
|
||||
duplicate_finder.AddAsciiSymbol(scanner()->literal_ascii_string(), 1);
|
||||
} else {
|
||||
prev_value =
|
||||
duplicate_finder.AddUtf16Symbol(scanner_->literal_utf16_string(), 1);
|
||||
duplicate_finder.AddUtf16Symbol(scanner()->literal_utf16_string(), 1);
|
||||
}
|
||||
|
||||
if (prev_value != 0) {
|
||||
SetStrictModeViolation(scanner_->location(),
|
||||
SetStrictModeViolation(scanner()->location(),
|
||||
"strict_param_dupe",
|
||||
CHECK_OK);
|
||||
}
|
||||
@ -1404,7 +1404,7 @@ PreParser::Expression PreParser::ParseFunctionLiteral(bool is_generator,
|
||||
// Currently only happens to top-level functions.
|
||||
// Optimistically assume that all top-level functions are lazily compiled.
|
||||
bool is_lazily_compiled = (outer_scope_type == kTopLevelScope &&
|
||||
!inside_with && allow_lazy_ &&
|
||||
!inside_with && allow_lazy() &&
|
||||
!parenthesized_function_);
|
||||
parenthesized_function_ = false;
|
||||
|
||||
@ -1417,7 +1417,7 @@ PreParser::Expression PreParser::ParseFunctionLiteral(bool is_generator,
|
||||
Expect(i::Token::RBRACE, CHECK_OK);
|
||||
|
||||
if (!is_classic_mode()) {
|
||||
int end_position = scanner_->location().end_pos;
|
||||
int end_position = scanner()->location().end_pos;
|
||||
CheckOctalLiteral(start_position, end_position, CHECK_OK);
|
||||
CheckDelayedStrictModeViolation(start_position, end_position, CHECK_OK);
|
||||
return Expression::StrictFunction();
|
||||
@ -1428,15 +1428,15 @@ PreParser::Expression PreParser::ParseFunctionLiteral(bool is_generator,
|
||||
|
||||
|
||||
void PreParser::ParseLazyFunctionLiteralBody(bool* ok) {
|
||||
int body_start = scanner_->location().beg_pos;
|
||||
int body_start = scanner()->location().beg_pos;
|
||||
log_->PauseRecording();
|
||||
ParseSourceElements(i::Token::RBRACE, ok);
|
||||
log_->ResumeRecording();
|
||||
if (!*ok) return;
|
||||
|
||||
// Position right after terminal '}'.
|
||||
ASSERT_EQ(i::Token::RBRACE, scanner_->peek());
|
||||
int body_end = scanner_->peek_location().end_pos;
|
||||
ASSERT_EQ(i::Token::RBRACE, scanner()->peek());
|
||||
int body_end = scanner()->peek_location().end_pos;
|
||||
log_->LogFunction(body_start, body_end,
|
||||
scope_->materialized_literal_count(),
|
||||
scope_->expected_properties(),
|
||||
@ -1448,7 +1448,7 @@ PreParser::Expression PreParser::ParseV8Intrinsic(bool* ok) {
|
||||
// CallRuntime ::
|
||||
// '%' Identifier Arguments
|
||||
Expect(i::Token::MOD, CHECK_OK);
|
||||
if (!allow_natives_syntax_) {
|
||||
if (!allow_natives_syntax()) {
|
||||
*ok = false;
|
||||
return Expression::Default();
|
||||
}
|
||||
@ -1461,29 +1461,12 @@ PreParser::Expression PreParser::ParseV8Intrinsic(bool* ok) {
|
||||
#undef CHECK_OK
|
||||
|
||||
|
||||
void PreParser::ExpectSemicolon(bool* ok) {
|
||||
// Check for automatic semicolon insertion according to
|
||||
// the rules given in ECMA-262, section 7.9, page 21.
|
||||
i::Token::Value tok = peek();
|
||||
if (tok == i::Token::SEMICOLON) {
|
||||
Next();
|
||||
return;
|
||||
}
|
||||
if (scanner_->HasAnyLineTerminatorBeforeNext() ||
|
||||
tok == i::Token::RBRACE ||
|
||||
tok == i::Token::EOS) {
|
||||
return;
|
||||
}
|
||||
Expect(i::Token::SEMICOLON, ok);
|
||||
}
|
||||
|
||||
|
||||
void PreParser::LogSymbol() {
|
||||
int identifier_pos = scanner_->location().beg_pos;
|
||||
if (scanner_->is_literal_ascii()) {
|
||||
log_->LogAsciiSymbol(identifier_pos, scanner_->literal_ascii_string());
|
||||
int identifier_pos = scanner()->location().beg_pos;
|
||||
if (scanner()->is_literal_ascii()) {
|
||||
log_->LogAsciiSymbol(identifier_pos, scanner()->literal_ascii_string());
|
||||
} else {
|
||||
log_->LogUtf16Symbol(identifier_pos, scanner_->literal_utf16_string());
|
||||
log_->LogUtf16Symbol(identifier_pos, scanner()->literal_utf16_string());
|
||||
}
|
||||
}
|
||||
|
||||
@ -1492,10 +1475,10 @@ PreParser::Expression PreParser::GetStringSymbol() {
|
||||
const int kUseStrictLength = 10;
|
||||
const char* kUseStrictChars = "use strict";
|
||||
LogSymbol();
|
||||
if (scanner_->is_literal_ascii() &&
|
||||
scanner_->literal_length() == kUseStrictLength &&
|
||||
!scanner_->literal_contains_escapes() &&
|
||||
!strncmp(scanner_->literal_ascii_string().start(), kUseStrictChars,
|
||||
if (scanner()->is_literal_ascii() &&
|
||||
scanner()->literal_length() == kUseStrictLength &&
|
||||
!scanner()->literal_contains_escapes() &&
|
||||
!strncmp(scanner()->literal_ascii_string().start(), kUseStrictChars,
|
||||
kUseStrictLength)) {
|
||||
return Expression::UseStrictStringLiteral();
|
||||
}
|
||||
@ -1505,22 +1488,22 @@ PreParser::Expression PreParser::GetStringSymbol() {
|
||||
|
||||
PreParser::Identifier PreParser::GetIdentifierSymbol() {
|
||||
LogSymbol();
|
||||
if (scanner_->current_token() == i::Token::FUTURE_RESERVED_WORD) {
|
||||
if (scanner()->current_token() == i::Token::FUTURE_RESERVED_WORD) {
|
||||
return Identifier::FutureReserved();
|
||||
} else if (scanner_->current_token() ==
|
||||
} else if (scanner()->current_token() ==
|
||||
i::Token::FUTURE_STRICT_RESERVED_WORD) {
|
||||
return Identifier::FutureStrictReserved();
|
||||
} else if (scanner_->current_token() == i::Token::YIELD) {
|
||||
} else if (scanner()->current_token() == i::Token::YIELD) {
|
||||
return Identifier::Yield();
|
||||
}
|
||||
if (scanner_->is_literal_ascii()) {
|
||||
if (scanner()->is_literal_ascii()) {
|
||||
// Detect strict-mode poison words.
|
||||
if (scanner_->literal_length() == 4 &&
|
||||
!strncmp(scanner_->literal_ascii_string().start(), "eval", 4)) {
|
||||
if (scanner()->literal_length() == 4 &&
|
||||
!strncmp(scanner()->literal_ascii_string().start(), "eval", 4)) {
|
||||
return Identifier::Eval();
|
||||
}
|
||||
if (scanner_->literal_length() == 9 &&
|
||||
!strncmp(scanner_->literal_ascii_string().start(), "arguments", 9)) {
|
||||
if (scanner()->literal_length() == 9 &&
|
||||
!strncmp(scanner()->literal_ascii_string().start(), "arguments", 9)) {
|
||||
return Identifier::Arguments();
|
||||
}
|
||||
}
|
||||
@ -1532,7 +1515,7 @@ PreParser::Identifier PreParser::ParseIdentifier(bool* ok) {
|
||||
i::Token::Value next = Next();
|
||||
switch (next) {
|
||||
case i::Token::FUTURE_RESERVED_WORD: {
|
||||
i::Scanner::Location location = scanner_->location();
|
||||
i::Scanner::Location location = scanner()->location();
|
||||
ReportMessageAt(location.beg_pos, location.end_pos,
|
||||
"reserved_word", NULL);
|
||||
*ok = false;
|
||||
@ -1541,14 +1524,14 @@ PreParser::Identifier PreParser::ParseIdentifier(bool* ok) {
|
||||
case i::Token::YIELD:
|
||||
if (scope_->is_generator()) {
|
||||
// 'yield' in a generator is only valid as part of a YieldExpression.
|
||||
ReportMessageAt(scanner_->location(), "unexpected_token", "yield");
|
||||
ReportMessageAt(scanner()->location(), "unexpected_token", "yield");
|
||||
*ok = false;
|
||||
return Identifier::Yield();
|
||||
}
|
||||
// FALLTHROUGH
|
||||
case i::Token::FUTURE_STRICT_RESERVED_WORD:
|
||||
if (!is_classic_mode()) {
|
||||
i::Scanner::Location location = scanner_->location();
|
||||
i::Scanner::Location location = scanner()->location();
|
||||
ReportMessageAt(location.beg_pos, location.end_pos,
|
||||
"strict_reserved_word", NULL);
|
||||
*ok = false;
|
||||
@ -1619,7 +1602,7 @@ void PreParser::StrictModeIdentifierViolation(i::Scanner::Location location,
|
||||
PreParser::Identifier PreParser::ParseIdentifierName(bool* ok) {
|
||||
i::Token::Value next = Next();
|
||||
if (i::Token::IsKeyword(next)) {
|
||||
int pos = scanner_->location().beg_pos;
|
||||
int pos = scanner()->location().beg_pos;
|
||||
const char* keyword = i::Token::String(next);
|
||||
log_->LogAsciiSymbol(pos, i::Vector<const char>(keyword,
|
||||
i::StrLength(keyword)));
|
||||
@ -1644,9 +1627,9 @@ PreParser::Identifier PreParser::ParseIdentifierNameOrGetOrSet(bool* is_get,
|
||||
bool* ok) {
|
||||
Identifier result = ParseIdentifierName(ok);
|
||||
if (!*ok) return Identifier::Default();
|
||||
if (scanner_->is_literal_ascii() &&
|
||||
scanner_->literal_length() == 3) {
|
||||
const char* token = scanner_->literal_ascii_string().start();
|
||||
if (scanner()->is_literal_ascii() &&
|
||||
scanner()->literal_length() == 3) {
|
||||
const char* token = scanner()->literal_ascii_string().start();
|
||||
*is_get = strncmp(token, "get", 3) == 0;
|
||||
*is_set = !*is_get && strncmp(token, "set", 3) == 0;
|
||||
}
|
||||
@ -1654,12 +1637,4 @@ PreParser::Identifier PreParser::ParseIdentifierNameOrGetOrSet(bool* is_get,
|
||||
}
|
||||
|
||||
|
||||
bool PreParser::peek_any_identifier() {
|
||||
i::Token::Value next = peek();
|
||||
return next == i::Token::IDENTIFIER ||
|
||||
next == i::Token::FUTURE_RESERVED_WORD ||
|
||||
next == i::Token::FUTURE_STRICT_RESERVED_WORD ||
|
||||
next == i::Token::YIELD;
|
||||
}
|
||||
|
||||
} } // v8::internal
|
||||
|
192
src/preparser.h
192
src/preparser.h
@ -125,6 +125,112 @@ void ObjectLiteralChecker<P>::CheckProperty(Token::Value property,
|
||||
}
|
||||
|
||||
|
||||
// Common base class shared between parser and pre-parser.
|
||||
class ParserBase {
|
||||
public:
|
||||
ParserBase(Scanner* scanner, uintptr_t stack_limit)
|
||||
: scanner_(scanner),
|
||||
stack_limit_(stack_limit),
|
||||
stack_overflow_(false),
|
||||
allow_lazy_(false),
|
||||
allow_natives_syntax_(false),
|
||||
allow_generators_(false),
|
||||
allow_for_of_(false) { }
|
||||
// TODO(mstarzinger): Only virtual until message reporting has been unified.
|
||||
virtual ~ParserBase() { }
|
||||
|
||||
// Getters that indicate whether certain syntactical constructs are
|
||||
// allowed to be parsed by this instance of the parser.
|
||||
bool allow_lazy() const { return allow_lazy_; }
|
||||
bool allow_natives_syntax() const { return allow_natives_syntax_; }
|
||||
bool allow_generators() const { return allow_generators_; }
|
||||
bool allow_for_of() const { return allow_for_of_; }
|
||||
bool allow_modules() const { return scanner()->HarmonyModules(); }
|
||||
bool allow_harmony_scoping() const { return scanner()->HarmonyScoping(); }
|
||||
bool allow_harmony_numeric_literals() const {
|
||||
return scanner()->HarmonyNumericLiterals();
|
||||
}
|
||||
|
||||
// Setters that determine whether certain syntactical constructs are
|
||||
// allowed to be parsed by this instance of the parser.
|
||||
void set_allow_lazy(bool allow) { allow_lazy_ = allow; }
|
||||
void set_allow_natives_syntax(bool allow) { allow_natives_syntax_ = allow; }
|
||||
void set_allow_generators(bool allow) { allow_generators_ = allow; }
|
||||
void set_allow_for_of(bool allow) { allow_for_of_ = allow; }
|
||||
void set_allow_modules(bool allow) { scanner()->SetHarmonyModules(allow); }
|
||||
void set_allow_harmony_scoping(bool allow) {
|
||||
scanner()->SetHarmonyScoping(allow);
|
||||
}
|
||||
void set_allow_harmony_numeric_literals(bool allow) {
|
||||
scanner()->SetHarmonyNumericLiterals(allow);
|
||||
}
|
||||
|
||||
protected:
|
||||
Scanner* scanner() const { return scanner_; }
|
||||
bool stack_overflow() const { return stack_overflow_; }
|
||||
void set_stack_overflow() { stack_overflow_ = true; }
|
||||
|
||||
INLINE(Token::Value peek()) {
|
||||
if (stack_overflow_) return Token::ILLEGAL;
|
||||
return scanner()->peek();
|
||||
}
|
||||
|
||||
INLINE(Token::Value Next()) {
|
||||
if (stack_overflow_) return Token::ILLEGAL;
|
||||
{
|
||||
int marker;
|
||||
if (reinterpret_cast<uintptr_t>(&marker) < stack_limit_) {
|
||||
// Any further calls to Next or peek will return the illegal token.
|
||||
// The current call must return the next token, which might already
|
||||
// have been peek'ed.
|
||||
stack_overflow_ = true;
|
||||
}
|
||||
}
|
||||
return scanner()->Next();
|
||||
}
|
||||
|
||||
void Consume(Token::Value token) {
|
||||
Token::Value next = Next();
|
||||
USE(next);
|
||||
USE(token);
|
||||
ASSERT(next == token);
|
||||
}
|
||||
|
||||
bool Check(Token::Value token) {
|
||||
Token::Value next = peek();
|
||||
if (next == token) {
|
||||
Consume(next);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void Expect(Token::Value token, bool* ok) {
|
||||
Token::Value next = Next();
|
||||
if (next != token) {
|
||||
ReportUnexpectedToken(next);
|
||||
*ok = false;
|
||||
}
|
||||
}
|
||||
|
||||
bool peek_any_identifier();
|
||||
void ExpectSemicolon(bool* ok);
|
||||
|
||||
// Report syntax errors.
|
||||
virtual void ReportUnexpectedToken(Token::Value token) = 0;
|
||||
|
||||
private:
|
||||
Scanner* scanner_;
|
||||
uintptr_t stack_limit_;
|
||||
bool stack_overflow_;
|
||||
|
||||
bool allow_lazy_;
|
||||
bool allow_natives_syntax_;
|
||||
bool allow_generators_;
|
||||
bool allow_for_of_;
|
||||
};
|
||||
|
||||
|
||||
// Preparsing checks a JavaScript program and emits preparse-data that helps
|
||||
// a later parsing to be faster.
|
||||
// See preparse-data-format.h for the data format.
|
||||
@ -141,7 +247,7 @@ void ObjectLiteralChecker<P>::CheckProperty(Token::Value property,
|
||||
typedef uint8_t byte;
|
||||
namespace i = v8::internal;
|
||||
|
||||
class PreParser {
|
||||
class PreParser : public ParserBase {
|
||||
public:
|
||||
enum PreParseResult {
|
||||
kPreParseStackOverflow,
|
||||
@ -152,43 +258,15 @@ class PreParser {
|
||||
PreParser(i::Scanner* scanner,
|
||||
i::ParserRecorder* log,
|
||||
uintptr_t stack_limit)
|
||||
: scanner_(scanner),
|
||||
: ParserBase(scanner, stack_limit),
|
||||
log_(log),
|
||||
scope_(NULL),
|
||||
stack_limit_(stack_limit),
|
||||
strict_mode_violation_location_(i::Scanner::Location::invalid()),
|
||||
strict_mode_violation_type_(NULL),
|
||||
stack_overflow_(false),
|
||||
allow_lazy_(false),
|
||||
allow_natives_syntax_(false),
|
||||
allow_generators_(false),
|
||||
allow_for_of_(false),
|
||||
parenthesized_function_(false) { }
|
||||
|
||||
~PreParser() {}
|
||||
|
||||
bool allow_natives_syntax() const { return allow_natives_syntax_; }
|
||||
bool allow_lazy() const { return allow_lazy_; }
|
||||
bool allow_modules() const { return scanner_->HarmonyModules(); }
|
||||
bool allow_harmony_scoping() const { return scanner_->HarmonyScoping(); }
|
||||
bool allow_generators() const { return allow_generators_; }
|
||||
bool allow_for_of() const { return allow_for_of_; }
|
||||
bool allow_harmony_numeric_literals() const {
|
||||
return scanner_->HarmonyNumericLiterals();
|
||||
}
|
||||
|
||||
void set_allow_natives_syntax(bool allow) { allow_natives_syntax_ = allow; }
|
||||
void set_allow_lazy(bool allow) { allow_lazy_ = allow; }
|
||||
void set_allow_modules(bool allow) { scanner_->SetHarmonyModules(allow); }
|
||||
void set_allow_harmony_scoping(bool allow) {
|
||||
scanner_->SetHarmonyScoping(allow);
|
||||
}
|
||||
void set_allow_generators(bool allow) { allow_generators_ = allow; }
|
||||
void set_allow_for_of(bool allow) { allow_for_of_ = allow; }
|
||||
void set_allow_harmony_numeric_literals(bool allow) {
|
||||
scanner_->SetHarmonyNumericLiterals(allow);
|
||||
}
|
||||
|
||||
// Pre-parse the program from the character stream; returns true on
|
||||
// success (even if parsing failed, the pre-parse data successfully
|
||||
// captured the syntax error), and false if a stack-overflow happened
|
||||
@ -196,13 +274,13 @@ class PreParser {
|
||||
PreParseResult PreParseProgram() {
|
||||
Scope top_scope(&scope_, kTopLevelScope);
|
||||
bool ok = true;
|
||||
int start_position = scanner_->peek_location().beg_pos;
|
||||
int start_position = scanner()->peek_location().beg_pos;
|
||||
ParseSourceElements(i::Token::EOS, &ok);
|
||||
if (stack_overflow_) return kPreParseStackOverflow;
|
||||
if (stack_overflow()) return kPreParseStackOverflow;
|
||||
if (!ok) {
|
||||
ReportUnexpectedToken(scanner_->current_token());
|
||||
ReportUnexpectedToken(scanner()->current_token());
|
||||
} else if (!scope_->is_classic_mode()) {
|
||||
CheckOctalLiteral(start_position, scanner_->location().end_pos, &ok);
|
||||
CheckOctalLiteral(start_position, scanner()->location().end_pos, &ok);
|
||||
}
|
||||
return kPreParseSuccess;
|
||||
}
|
||||
@ -604,27 +682,6 @@ class PreParser {
|
||||
// Log the currently parsed string literal.
|
||||
Expression GetStringSymbol();
|
||||
|
||||
i::Token::Value peek() {
|
||||
if (stack_overflow_) return i::Token::ILLEGAL;
|
||||
return scanner_->peek();
|
||||
}
|
||||
|
||||
i::Token::Value Next() {
|
||||
if (stack_overflow_) return i::Token::ILLEGAL;
|
||||
{
|
||||
int marker;
|
||||
if (reinterpret_cast<uintptr_t>(&marker) < stack_limit_) {
|
||||
// Further calls to peek/Next will return illegal token.
|
||||
// The current one will still be returned. It might already
|
||||
// have been seen using peek.
|
||||
stack_overflow_ = true;
|
||||
}
|
||||
}
|
||||
return scanner_->Next();
|
||||
}
|
||||
|
||||
bool peek_any_identifier();
|
||||
|
||||
void set_language_mode(i::LanguageMode language_mode) {
|
||||
scope_->set_language_mode(language_mode);
|
||||
}
|
||||
@ -639,24 +696,6 @@ class PreParser {
|
||||
|
||||
i::LanguageMode language_mode() { return scope_->language_mode(); }
|
||||
|
||||
void Consume(i::Token::Value token) { Next(); }
|
||||
|
||||
void Expect(i::Token::Value token, bool* ok) {
|
||||
if (Next() != token) {
|
||||
*ok = false;
|
||||
}
|
||||
}
|
||||
|
||||
bool Check(i::Token::Value token) {
|
||||
i::Token::Value next = peek();
|
||||
if (next == token) {
|
||||
Consume(next);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
void ExpectSemicolon(bool* ok);
|
||||
|
||||
bool CheckInOrOf(bool accept_OF);
|
||||
|
||||
static int Precedence(i::Token::Value tok, bool accept_IN);
|
||||
@ -672,17 +711,10 @@ class PreParser {
|
||||
Identifier identifier,
|
||||
bool* ok);
|
||||
|
||||
i::Scanner* scanner_;
|
||||
i::ParserRecorder* log_;
|
||||
Scope* scope_;
|
||||
uintptr_t stack_limit_;
|
||||
i::Scanner::Location strict_mode_violation_location_;
|
||||
const char* strict_mode_violation_type_;
|
||||
bool stack_overflow_;
|
||||
bool allow_lazy_;
|
||||
bool allow_natives_syntax_;
|
||||
bool allow_generators_;
|
||||
bool allow_for_of_;
|
||||
bool parenthesized_function_;
|
||||
|
||||
friend class i::ObjectLiteralChecker<PreParser>;
|
||||
|
Loading…
Reference in New Issue
Block a user