Revision: 17202
Author: [email protected]
Date: Mon Oct 14 16:46:51 2013 UTC
Log: Introduce ParserBase for common code between parser and
pre-parser.
[email protected]
Review URL: https://codereview.chromium.org/27182002
http://code.google.com/p/v8/source/detail?r=17202
Modified:
/branches/bleeding_edge/src/parser.cc
/branches/bleeding_edge/src/parser.h
/branches/bleeding_edge/src/preparser.cc
/branches/bleeding_edge/src/preparser.h
=======================================
--- /branches/bleeding_edge/src/parser.cc Mon Oct 14 13:07:20 2013 UTC
+++ /branches/bleeding_edge/src/parser.cc Mon Oct 14 16:46:51 2013 UTC
@@ -536,7 +536,8 @@
// 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 @@
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 @@
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 @@
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 @@
// 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 @@
PreParser::PreParseResult result =
LazyParseFunctionLiteral(&logger);
if (result == PreParser::kPreParseStackOverflow) {
// Propagate stack overflow.
- stack_overflow_ = true;
+ set_stack_overflow();
*ok = false;
return NULL;
}
@@ -4613,39 +4609,13 @@
}
-bool Parser::peek_any_identifier() {
+bool ParserBase::peek_any_identifier() {
Token::Value next = peek();
return next == Token::IDENTIFIER ||
next == Token::FUTURE_RESERVED_WORD ||
next == Token::FUTURE_STRICT_RESERVED_WORD ||
next == Token::YIELD;
}
-
-
-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) {
@@ -4658,7 +4628,7 @@
}
-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 @@
Next();
return;
}
- if (scanner().HasAnyLineTerminatorBeforeNext() ||
+ if (scanner()->HasAnyLineTerminatorBeforeNext() ||
tok == Token::RBRACE ||
tok == Token::EOS) {
return;
=======================================
--- /branches/bleeding_edge/src/parser.h Mon Oct 14 13:07:20 2013 UTC
+++ /branches/bleeding_edge/src/parser.h Mon Oct 14 16:46:51 2013 UTC
@@ -425,35 +425,13 @@
// Forward declaration.
class SingletonLogger;
-class Parser BASE_EMBEDDED {
+class Parser : public ParserBase {
public:
explicit Parser(CompilationInfo* info);
~Parser() {
delete reusable_preparser_;
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
@@ -712,37 +690,10 @@
// 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 @@
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,
=======================================
--- /branches/bleeding_edge/src/preparser.cc Mon Oct 14 13:07:20 2013 UTC
+++ /branches/bleeding_edge/src/preparser.cc Mon Oct 14 16:46:51 2013 UTC
@@ -63,17 +63,17 @@
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 @@
// 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 @@
// 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 @@
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 @@
// '{' 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 @@
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 @@
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 @@
// * 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 @@
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 @@
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 @@
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 @@
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 @@
// 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 @@
// '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 @@
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 @@
// '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 @@
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 @@
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 @@
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 @@
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 @@
// 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 @@
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 @@
// | (('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::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 @@
// 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 @@
// 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 @@
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 @@
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 @@
// 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 @@
#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 @@
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::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 @@
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 @@
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 @@
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,22 +1627,14 @@
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;
}
return result;
}
-
-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
=======================================
--- /branches/bleeding_edge/src/preparser.h Mon Oct 14 13:07:20 2013 UTC
+++ /branches/bleeding_edge/src/preparser.h Mon Oct 14 16:46:51 2013 UTC
@@ -123,6 +123,112 @@
*ok = false;
}
}
+
+
+// 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
@@ -141,7 +247,7 @@
typedef uint8_t byte;
namespace i = v8::internal;
-class PreParser {
+class PreParser : public ParserBase {
public:
enum PreParseResult {
kPreParseStackOverflow,
@@ -152,42 +258,14 @@
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
@@ -196,13 +274,13 @@
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 @@
// 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);
}
@@ -638,24 +695,6 @@
}
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);
@@ -672,17 +711,10 @@
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>;
--
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev
---
You received this message because you are subscribed to the Google Groups "v8-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
For more options, visit https://groups.google.com/groups/opt_out.