Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(866)

Unified Diff: src/parser.cc

Issue 149913006: Traitify ParserBase and move functions there. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: . Created 6 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: src/parser.cc
diff --git a/src/parser.cc b/src/parser.cc
index 5e7680e6c19df12853d7ee850fc9bf65010f41fc..c8ce895b7e49eac51507b1ba758f80f5fa61af12 100644
--- a/src/parser.cc
+++ b/src/parser.cc
@@ -533,8 +533,78 @@ Parser::FunctionState::~FunctionState() {
// ----------------------------------------------------------------------------
// Implementation of Parser
+bool ParserTraits::is_classic_mode() const {
+ return parser_->top_scope_->is_classic_mode();
+}
+
+
+bool ParserTraits::is_generator() const {
+ return parser_->current_function_state_->is_generator();
+}
+
+
+bool ParserTraits::IsEvalOrArguments(Handle<String> identifier) const {
+ return identifier.is_identical_to(
+ parser_->isolate()->factory()->eval_string()) ||
+ identifier.is_identical_to(
+ parser_->isolate()->factory()->arguments_string());
+}
+
+
+void ParserTraits::ReportMessageAt(Scanner::Location source_location,
+ const char* message,
+ Vector<const char*> args) {
+ MessageLocation location(parser_->script_,
+ source_location.beg_pos,
+ source_location.end_pos);
+ Factory* factory = parser_->isolate()->factory();
+ Handle<FixedArray> elements = factory->NewFixedArray(args.length());
+ for (int i = 0; i < args.length(); i++) {
+ Handle<String> arg_string = factory->NewStringFromUtf8(CStrVector(args[i]));
+ elements->set(i, *arg_string);
+ }
+ Handle<JSArray> array = factory->NewJSArrayWithElements(elements);
+ Handle<Object> result = factory->NewSyntaxError(message, array);
+ parser_->isolate()->Throw(*result, &location);
+}
+
+
+void ParserTraits::ReportMessage(const char* message,
+ Vector<Handle<String> > args) {
+ Scanner::Location source_location = parser_->scanner().location();
+ ReportMessageAt(source_location, message, args);
+}
+
+
+void ParserTraits::ReportMessageAt(Scanner::Location source_location,
+ const char* message,
+ Vector<Handle<String> > args) {
+ MessageLocation location(parser_->script_,
+ source_location.beg_pos,
+ source_location.end_pos);
+ Factory* factory = parser_->isolate()->factory();
+ Handle<FixedArray> elements = factory->NewFixedArray(args.length());
+ for (int i = 0; i < args.length(); i++) {
+ elements->set(i, *args[i]);
+ }
+ Handle<JSArray> array = factory->NewJSArrayWithElements(elements);
+ Handle<Object> result = factory->NewSyntaxError(message, array);
+ parser_->isolate()->Throw(*result, &location);
+}
+
+
+Handle<String> ParserTraits::GetSymbol() {
+ int symbol_id = -1;
+ if (parser_->pre_parse_data() != NULL) {
+ symbol_id = parser_->pre_parse_data()->GetSymbolIdentifier();
+ }
+ return parser_->LookupSymbol(symbol_id);
+}
+
+
Parser::Parser(CompilationInfo* info)
- : ParserBase(&scanner_, info->isolate()->stack_guard()->real_climit()),
+ : ParserBase(&scanner_, info->isolate()->stack_guard()->real_climit(),
+ new ParserTraits(this)),
Michael Starzinger 2014/02/10 13:28:03 If we make the ParserBase inherit from ParserTrait
marja 2014/02/10 15:02:07 Done.
isolate_(info->isolate()),
symbol_cache_(0, info->zone()),
script_(info->script()),
@@ -793,62 +863,6 @@ FunctionLiteral* Parser::ParseLazy(Utf16CharacterStream* source) {
}
-Handle<String> Parser::GetSymbol() {
- int symbol_id = -1;
- if (pre_parse_data() != NULL) {
- symbol_id = pre_parse_data()->GetSymbolIdentifier();
- }
- return LookupSymbol(symbol_id);
-}
-
-
-void Parser::ReportMessage(const char* message, Vector<const char*> args) {
- Scanner::Location source_location = scanner().location();
- ReportMessageAt(source_location, message, args);
-}
-
-
-void Parser::ReportMessage(const char* message, Vector<Handle<String> > args) {
- Scanner::Location source_location = scanner().location();
- ReportMessageAt(source_location, message, args);
-}
-
-
-void Parser::ReportMessageAt(Scanner::Location source_location,
- const char* message,
- Vector<const char*> args) {
- MessageLocation location(script_,
- source_location.beg_pos,
- source_location.end_pos);
- Factory* factory = isolate()->factory();
- Handle<FixedArray> elements = factory->NewFixedArray(args.length());
- for (int i = 0; i < args.length(); i++) {
- Handle<String> arg_string = factory->NewStringFromUtf8(CStrVector(args[i]));
- elements->set(i, *arg_string);
- }
- Handle<JSArray> array = factory->NewJSArrayWithElements(elements);
- Handle<Object> result = factory->NewSyntaxError(message, array);
- isolate()->Throw(*result, &location);
-}
-
-
-void Parser::ReportMessageAt(Scanner::Location source_location,
- const char* message,
- Vector<Handle<String> > args) {
- MessageLocation location(script_,
- source_location.beg_pos,
- source_location.end_pos);
- Factory* factory = isolate()->factory();
- Handle<FixedArray> elements = factory->NewFixedArray(args.length());
- for (int i = 0; i < args.length(); i++) {
- elements->set(i, *args[i]);
- }
- Handle<JSArray> array = factory->NewJSArrayWithElements(elements);
- Handle<Object> result = factory->NewSyntaxError(message, array);
- isolate()->Throw(*result, &location);
-}
-
-
void* Parser::ParseSourceElements(ZoneList<Statement*>* processor,
int end_token,
bool is_eval,
@@ -1081,8 +1095,8 @@ Module* Parser::ParseModuleLiteral(bool* ok) {
!it.done(); it.Advance()) {
if (scope->LocalLookup(it.name()) == NULL) {
Handle<String> name(it.name());
- ReportMessage("module_export_undefined",
- Vector<Handle<String> >(&name, 1));
+ traits_->ReportMessage("module_export_undefined",
Michael Starzinger 2014/02/10 13:28:03 Likewise calling ReportMessage() wouldn't need an
marja 2014/02/10 15:02:07 Done.
+ Vector<Handle<String> >(&name, 1));
*ok = false;
return NULL;
}
@@ -1121,7 +1135,8 @@ Module* Parser::ParseModulePath(bool* ok) {
member->interface()->Print();
}
#endif
- ReportMessage("invalid_module_path", Vector<Handle<String> >(&name, 1));
+ traits_->ReportMessage("invalid_module_path",
+ Vector<Handle<String> >(&name, 1));
return NULL;
}
result = member;
@@ -1155,7 +1170,7 @@ Module* Parser::ParseModuleUrl(bool* ok) {
int pos = peek_position();
Expect(Token::STRING, CHECK_OK);
- Handle<String> symbol = GetSymbol();
+ Handle<String> symbol = traits_->GetSymbol();
// TODO(ES6): Request JS resource from environment...
@@ -1231,7 +1246,8 @@ Block* Parser::ParseImportDeclaration(bool* ok) {
module->interface()->Print();
}
#endif
- ReportMessage("invalid_module_path", Vector<Handle<String> >(&name, 1));
+ traits_->ReportMessage("invalid_module_path",
+ Vector<Handle<String> >(&name, 1));
return NULL;
}
VariableProxy* proxy = NewUnresolved(names[i], LET, interface);
@@ -1619,7 +1635,8 @@ void Parser::Declare(Declaration* declaration, bool resolve, bool* ok) {
var->interface()->Print();
}
#endif
- ReportMessage("module_type_error", Vector<Handle<String> >(&name, 1));
+ traits_->ReportMessage("module_type_error",
+ Vector<Handle<String> >(&name, 1));
}
}
}
@@ -1777,12 +1794,6 @@ Block* Parser::ParseVariableStatement(VariableDeclarationContext var_context,
}
-bool Parser::IsEvalOrArguments(Handle<String> string) {
- return string.is_identical_to(isolate()->factory()->eval_string()) ||
- string.is_identical_to(isolate()->factory()->arguments_string());
-}
-
-
// If the variable declaration declares exactly one non-const
// variable, then *out is set to that variable. In all other cases,
// *out is untouched; in particular, it is the caller's responsibility
@@ -2232,7 +2243,7 @@ Statement* Parser::ParseContinueStatement(bool* ok) {
message = "unknown_label";
args = Vector<Handle<String> >(&label, 1);
}
- ReportMessageAt(scanner().location(), message, args);
+ traits_->ReportMessageAt(scanner().location(), message, args);
*ok = false;
return NULL;
}
@@ -2270,7 +2281,7 @@ Statement* Parser::ParseBreakStatement(ZoneStringList* labels, bool* ok) {
message = "unknown_label";
args = Vector<Handle<String> >(&label, 1);
}
- ReportMessageAt(scanner().location(), message, args);
+ traits_->ReportMessageAt(scanner().location(), message, args);
*ok = false;
return NULL;
}
@@ -2301,7 +2312,7 @@ Statement* Parser::ParseReturnStatement(bool* ok) {
return_value = ParseExpression(true, CHECK_OK);
}
ExpectSemicolon(CHECK_OK);
- if (is_generator()) {
+ if (traits_->is_generator()) {
Expression* generator = factory()->NewVariableProxy(
current_function_state_->generator_object_variable());
Expression* yield = factory()->NewYield(
@@ -2902,7 +2913,7 @@ Expression* Parser::ParseAssignmentExpression(bool accept_IN, bool* ok) {
// YieldExpression
// LeftHandSideExpression AssignmentOperator AssignmentExpression
- if (peek() == Token::YIELD && is_generator()) {
+ if (peek() == Token::YIELD && traits_->is_generator()) {
return ParseYieldExpression(ok);
}
@@ -3013,14 +3024,6 @@ Expression* Parser::ParseConditionalExpression(bool accept_IN, bool* ok) {
}
-int ParserBase::Precedence(Token::Value tok, bool accept_IN) {
- if (tok == Token::IN && !accept_IN)
- return 0; // 0 precedence will terminate binary expression parsing
-
- return Token::Precedence(tok);
-}
-
-
// Precedence >= 4
Expression* Parser::ParseBinaryExpression(int prec, bool accept_IN, bool* ok) {
ASSERT(prec >= 4);
@@ -3543,7 +3546,7 @@ Expression* Parser::ParsePrimaryExpression(bool* ok) {
case Token::STRING: {
Consume(Token::STRING);
- Handle<String> symbol = GetSymbol();
+ Handle<String> symbol = traits_->GetSymbol();
result = factory()->NewLiteral(symbol, pos);
if (fni_ != NULL) fni_->PushLiteralName(symbol);
break;
@@ -3721,7 +3724,7 @@ Expression* Parser::ParseObjectLiteral(bool* ok) {
checker.CheckProperty(next, type, CHECK_OK);
Handle<String> name = is_keyword
? isolate_->factory()->InternalizeUtf8String(Token::String(next))
- : GetSymbol();
+ : traits_->GetSymbol();
FunctionLiteral* value =
ParseFunctionLiteral(name,
scanner().location(),
@@ -3753,7 +3756,7 @@ Expression* Parser::ParseObjectLiteral(bool* ok) {
}
case Token::STRING: {
Consume(Token::STRING);
- Handle<String> string = GetSymbol();
+ Handle<String> string = traits_->GetSymbol();
if (fni_ != NULL) fni_->PushLiteralName(string);
uint32_t index;
if (!string.is_null() && string->AsArrayIndex(&index)) {
@@ -3776,7 +3779,7 @@ Expression* Parser::ParseObjectLiteral(bool* ok) {
default:
if (Token::IsKeyword(next)) {
Consume(next);
- Handle<String> string = GetSymbol();
+ Handle<String> string = traits_->GetSymbol();
key = factory()->NewLiteral(string, next_pos);
} else {
// Unexpected token.
@@ -4081,7 +4084,8 @@ FunctionLiteral* Parser::ParseFunctionLiteral(
ParseIdentifierOrStrictReservedWord(&is_strict_reserved, CHECK_OK);
// Store locations for possible future error reports.
- if (!eval_args_error_log.IsValid() && IsEvalOrArguments(param_name)) {
+ if (!eval_args_error_log.IsValid() &&
+ traits_->IsEvalOrArguments(param_name)) {
eval_args_error_log = scanner().location();
}
if (!reserved_loc.IsValid() && is_strict_reserved) {
@@ -4261,7 +4265,7 @@ FunctionLiteral* Parser::ParseFunctionLiteral(
// Validate strict mode. We can do this only after parsing the function,
// since the function can declare itself strict.
if (!top_scope_->is_classic_mode()) {
- if (IsEvalOrArguments(function_name)) {
+ if (traits_->IsEvalOrArguments(function_name)) {
ReportMessageAt(function_name_location,
"strict_eval_arguments",
Vector<const char*>::empty());
@@ -4344,10 +4348,8 @@ PreParser::PreParseResult Parser::LazyParseFunctionLiteral(
reusable_preparser_->set_allow_harmony_numeric_literals(
allow_harmony_numeric_literals());
}
- PreParser::PreParseResult result =
- reusable_preparser_->PreParseLazyFunction(top_scope_->language_mode(),
- is_generator(),
- logger);
+ PreParser::PreParseResult result = reusable_preparser_->PreParseLazyFunction(
+ top_scope_->language_mode(), traits_->is_generator(), logger);
return result;
}
@@ -4397,7 +4399,7 @@ Expression* Parser::ParseV8Intrinsic(bool* ok) {
// Check that the function is defined if it's an inline runtime call.
if (function == NULL && name->Get(0) == '_') {
- ReportMessage("not_defined", Vector<Handle<String> >(&name, 1));
+ traits_->ReportMessage("not_defined", Vector<Handle<String> >(&name, 1));
*ok = false;
return NULL;
}
@@ -4407,88 +4409,6 @@ Expression* Parser::ParseV8Intrinsic(bool* ok) {
}
-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;
-}
-
-
-bool ParserBase::CheckContextualKeyword(Vector<const char> keyword) {
- if (peek() == Token::IDENTIFIER &&
- scanner()->is_next_contextual_keyword(keyword)) {
- Consume(Token::IDENTIFIER);
- return true;
- }
- return false;
-}
-
-
-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();
- if (tok == Token::SEMICOLON) {
- Next();
- return;
- }
- if (scanner()->HasAnyLineTerminatorBeforeNext() ||
- tok == Token::RBRACE ||
- tok == Token::EOS) {
- return;
- }
- Expect(Token::SEMICOLON, ok);
-}
-
-
-void ParserBase::ExpectContextualKeyword(Vector<const char> keyword, bool* ok) {
- Expect(Token::IDENTIFIER, ok);
- if (!*ok) return;
- if (!scanner()->is_literal_contextual_keyword(keyword)) {
- ReportUnexpectedToken(scanner()->current_token());
- *ok = false;
- }
-}
-
-
-void ParserBase::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.
- if (token == Token::ILLEGAL && stack_overflow()) {
- return;
- }
- Scanner::Location source_location = scanner()->location();
-
- // Four of the tokens are treated specially
- switch (token) {
- case Token::EOS:
- return ReportMessageAt(source_location, "unexpected_eos");
- case Token::NUMBER:
- return ReportMessageAt(source_location, "unexpected_token_number");
- case Token::STRING:
- return ReportMessageAt(source_location, "unexpected_token_string");
- case Token::IDENTIFIER:
- return ReportMessageAt(source_location,
- "unexpected_token_identifier");
- case Token::FUTURE_RESERVED_WORD:
- return ReportMessageAt(source_location, "unexpected_reserved");
- case Token::YIELD:
- case Token::FUTURE_STRICT_RESERVED_WORD:
- return ReportMessageAt(source_location,
- is_classic_mode() ? "unexpected_token_identifier"
- : "unexpected_strict_reserved");
- default:
- const char* name = Token::String(token);
- ASSERT(name != NULL);
- ReportMessageAt(
- source_location, "unexpected_token", Vector<const char*>(&name, 1));
- }
-}
-
-
Literal* Parser::GetLiteralUndefined(int position) {
return factory()->NewLiteral(
isolate()->factory()->undefined_value(), position);
@@ -4501,68 +4421,6 @@ Literal* Parser::GetLiteralTheHole(int position) {
}
-// Parses an identifier that is valid for the current scope, in particular it
-// fails on strict mode future reserved keywords in a strict scope. If
-// allow_eval_or_arguments is kAllowEvalOrArguments, we allow "eval" or
-// "arguments" as identifier even in strict mode (this is needed in cases like
-// "var foo = eval;").
-Handle<String> Parser::ParseIdentifier(
- AllowEvalOrArgumentsAsIdentifier allow_eval_or_arguments,
- bool* ok) {
- Token::Value next = Next();
- if (next == Token::IDENTIFIER) {
- Handle<String> name = GetSymbol();
- if (allow_eval_or_arguments == kDontAllowEvalOrArguments &&
- !top_scope_->is_classic_mode() && IsEvalOrArguments(name)) {
- ReportMessage("strict_eval_arguments", Vector<const char*>::empty());
- *ok = false;
- }
- return name;
- } else if (top_scope_->is_classic_mode() &&
- (next == Token::FUTURE_STRICT_RESERVED_WORD ||
- (next == Token::YIELD && !is_generator()))) {
- return GetSymbol();
- } else {
- ReportUnexpectedToken(next);
- *ok = false;
- return Handle<String>();
- }
-}
-
-
-// Parses and identifier or a strict mode future reserved word, and indicate
-// whether it is strict mode future reserved.
-Handle<String> Parser::ParseIdentifierOrStrictReservedWord(
- bool* is_strict_reserved, bool* ok) {
- Token::Value next = Next();
- if (next == Token::IDENTIFIER) {
- *is_strict_reserved = false;
- } else if (next == Token::FUTURE_STRICT_RESERVED_WORD ||
- (next == Token::YIELD && !is_generator())) {
- *is_strict_reserved = true;
- } else {
- ReportUnexpectedToken(next);
- *ok = false;
- return Handle<String>();
- }
- return GetSymbol();
-}
-
-
-Handle<String> Parser::ParseIdentifierName(bool* ok) {
- Token::Value next = Next();
- if (next != Token::IDENTIFIER &&
- next != Token::FUTURE_RESERVED_WORD &&
- next != Token::FUTURE_STRICT_RESERVED_WORD &&
- !Token::IsKeyword(next)) {
- ReportUnexpectedToken(next);
- *ok = false;
- return Handle<String>();
- }
- return GetSymbol();
-}
-
-
void Parser::MarkAsLValue(Expression* expression) {
VariableProxy* proxy = expression != NULL
? expression->AsVariableProxy()
@@ -4581,25 +4439,14 @@ void Parser::CheckStrictModeLValue(Expression* expression,
? expression->AsVariableProxy()
: NULL;
- if (lhs != NULL && !lhs->is_this() && IsEvalOrArguments(lhs->name())) {
+ if (lhs != NULL && !lhs->is_this() &&
+ traits_->IsEvalOrArguments(lhs->name())) {
ReportMessage("strict_eval_arguments", Vector<const char*>::empty());
*ok = false;
}
}
-// Checks whether an octal literal was last seen between beg_pos and end_pos.
-// If so, reports an error. Only called for strict mode.
-void ParserBase::CheckOctalLiteral(int beg_pos, int end_pos, bool* ok) {
- Scanner::Location octal = scanner()->octal_position();
- if (octal.IsValid() && beg_pos <= octal.beg_pos && octal.end_pos <= end_pos) {
- ReportMessageAt(octal, "strict_octal_literal");
- scanner()->clear_octal_position();
- *ok = false;
- }
-}
-
-
void Parser::CheckConflictingVarDeclarations(Scope* scope, bool* ok) {
Declaration* decl = scope->CheckConflictingVarDeclarations();
if (decl != NULL) {
@@ -4619,22 +4466,6 @@ void Parser::CheckConflictingVarDeclarations(Scope* scope, bool* ok) {
}
-// This function reads an identifier name and determines whether or not it
-// is 'get' or 'set'.
-Handle<String> Parser::ParseIdentifierNameOrGetOrSet(bool* is_get,
- bool* is_set,
- bool* ok) {
- Handle<String> result = ParseIdentifierName(ok);
- if (!*ok) return Handle<String>();
- 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;
-}
-
-
// ----------------------------------------------------------------------------
// Parser support

Powered by Google App Engine
This is Rietveld 408576698