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

Unified Diff: src/preparser.cc

Issue 196133017: Experimental parser: merge r19949 (Closed) Base URL: https://v8.googlecode.com/svn/branches/experimental/parser
Patch Set: Created 6 years, 9 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
« no previous file with comments | « src/preparser.h ('k') | src/profile-generator-inl.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/preparser.cc
diff --git a/src/preparser.cc b/src/preparser.cc
index a5de23ebeede10d2b59726f32d0294f6403555f1..a64a3592b00838441753a742480dc7914c123f9e 100644
--- a/src/preparser.cc
+++ b/src/preparser.cc
@@ -55,6 +55,18 @@ int isfinite(double value);
namespace v8 {
namespace internal {
+
+void PreParserTraits::CheckStrictModeLValue(PreParserExpression expression,
+ bool* ok) {
+ if (expression.IsIdentifier() &&
+ expression.AsIdentifier().IsEvalOrArguments()) {
+ pre_parser_->ReportMessage("strict_eval_arguments",
+ Vector<const char*>::empty());
+ *ok = false;
+ }
+}
+
+
void PreParserTraits::ReportMessageAt(Scanner::Location location,
const char* message,
Vector<const char*> args) {
@@ -91,16 +103,11 @@ PreParserIdentifier PreParserTraits::GetSymbol(Scanner* scanner) {
} else if (scanner->current_token() == Token::YIELD) {
return PreParserIdentifier::Yield();
}
- if (scanner->is_literal_ascii()) {
- // Detect strict-mode poison words.
- if (scanner->literal_length() == 4 &&
- !strncmp(scanner->literal_ascii_string().start(), "eval", 4)) {
- return PreParserIdentifier::Eval();
- }
- if (scanner->literal_length() == 9 &&
- !strncmp(scanner->literal_ascii_string().start(), "arguments", 9)) {
- return PreParserIdentifier::Arguments();
- }
+ if (scanner->UnescapedLiteralMatches("eval", 4)) {
+ return PreParserIdentifier::Eval();
+ }
+ if (scanner->UnescapedLiteralMatches("arguments", 9)) {
+ return PreParserIdentifier::Arguments();
}
return PreParserIdentifier::Default();
}
@@ -108,43 +115,46 @@ PreParserIdentifier PreParserTraits::GetSymbol(Scanner* scanner) {
PreParserExpression PreParserTraits::ExpressionFromString(
int pos, Scanner* scanner, PreParserFactory* factory) {
- const int kUseStrictLength = 10;
- const char* kUseStrictChars = "use strict";
pre_parser_->LogSymbol();
- if (scanner->is_literal_ascii() &&
- scanner->literal_length() == kUseStrictLength &&
- !scanner->literal_contains_escapes() &&
- !strncmp(scanner->literal_ascii_string().start(), kUseStrictChars,
- kUseStrictLength)) {
+ if (scanner->UnescapedLiteralMatches("use strict", 10)) {
return PreParserExpression::UseStrictStringLiteral();
}
return PreParserExpression::StringLiteral();
}
-PreParserExpression PreParserTraits::ParseObjectLiteral(bool* ok) {
- return pre_parser_->ParseObjectLiteral(ok);
+PreParserExpression PreParserTraits::ParseV8Intrinsic(bool* ok) {
+ return pre_parser_->ParseV8Intrinsic(ok);
}
-PreParserExpression PreParserTraits::ParseAssignmentExpression(bool accept_IN,
- bool* ok) {
- return pre_parser_->ParseAssignmentExpression(accept_IN, ok);
+PreParserExpression PreParserTraits::ParseFunctionLiteral(
+ PreParserIdentifier name,
+ Scanner::Location function_name_location,
+ bool name_is_strict_reserved,
+ bool is_generator,
+ int function_token_position,
+ FunctionLiteral::FunctionType type,
+ bool* ok) {
+ return pre_parser_->ParseFunctionLiteral(
+ name, function_name_location, name_is_strict_reserved, is_generator,
+ function_token_position, type, ok);
}
-PreParserExpression PreParserTraits::ParseV8Intrinsic(bool* ok) {
- return pre_parser_->ParseV8Intrinsic(ok);
+PreParserExpression PreParserTraits::ParseConditionalExpression(bool accept_IN,
+ bool* ok) {
+ return pre_parser_->ParseConditionalExpression(accept_IN, ok);
}
PreParser::PreParseResult PreParser::PreParseLazyFunction(
- LanguageMode mode, bool is_generator, ParserRecorder* log) {
+ StrictMode strict_mode, bool is_generator, ParserRecorder* log) {
log_ = log;
// Lazy functions always have trivial outer scopes (no with/catch scopes).
PreParserScope top_scope(scope_, GLOBAL_SCOPE);
FunctionState top_state(&function_state_, &scope_, &top_scope);
- scope_->SetLanguageMode(mode);
+ scope_->SetStrictMode(strict_mode);
PreParserScope function_scope(scope_, FUNCTION_SCOPE);
FunctionState function_state(&function_state_, &scope_, &function_scope);
function_state.set_is_generator(is_generator);
@@ -157,7 +167,7 @@ PreParser::PreParseResult PreParser::PreParseLazyFunction(
ReportUnexpectedToken(scanner()->current_token());
} else {
ASSERT_EQ(Token::RBRACE, scanner()->peek());
- if (!scope_->is_classic_mode()) {
+ if (scope_->strict_mode() == STRICT) {
int end_pos = scanner()->location().end_pos;
CheckOctalLiteral(start_position, end_pos, &ok);
}
@@ -224,8 +234,7 @@ PreParser::SourceElements PreParser::ParseSourceElements(int end_token,
Statement statement = ParseSourceElement(CHECK_OK);
if (directive_prologue) {
if (statement.IsUseStrictLiteral()) {
- scope_->SetLanguageMode(allow_harmony_scoping() ?
- EXTENDED_MODE : STRICT_MODE);
+ scope_->SetStrictMode(STRICT);
} else if (!statement.IsStringLiteral()) {
directive_prologue = false;
}
@@ -319,7 +328,7 @@ PreParser::Statement PreParser::ParseStatement(bool* ok) {
Scanner::Location start_location = scanner()->peek_location();
Statement statement = ParseFunctionDeclaration(CHECK_OK);
Scanner::Location end_location = scanner()->location();
- if (!scope_->is_classic_mode()) {
+ if (strict_mode() == STRICT) {
PreParserTraits::ReportMessageAt(start_location.beg_pos,
end_location.end_pos,
"strict_function",
@@ -347,7 +356,7 @@ PreParser::Statement PreParser::ParseFunctionDeclaration(bool* ok) {
// 'function' '*' Identifier '(' FormalParameterListopt ')'
// '{' FunctionBody '}'
Expect(Token::FUNCTION, CHECK_OK);
-
+ int pos = position();
bool is_generator = allow_generators() && Check(Token::MUL);
bool is_strict_reserved = false;
Identifier name = ParseIdentifierOrStrictReservedWord(
@@ -356,6 +365,8 @@ PreParser::Statement PreParser::ParseFunctionDeclaration(bool* ok) {
scanner()->location(),
is_strict_reserved,
is_generator,
+ pos,
+ FunctionLiteral::DECLARATION,
CHECK_OK);
return Statement::FunctionDeclaration();
}
@@ -370,7 +381,7 @@ PreParser::Statement PreParser::ParseBlock(bool* ok) {
//
Expect(Token::LBRACE, CHECK_OK);
while (peek() != Token::RBRACE) {
- if (scope_->is_extended_mode()) {
+ if (FLAG_harmony_scoping && strict_mode() == STRICT) {
ParseSourceElement(CHECK_OK);
} else {
ParseStatement(CHECK_OK);
@@ -430,28 +441,24 @@ PreParser::Statement PreParser::ParseVariableDeclarations(
// * It is a Syntax Error if the code that matches this production is not
// contained in extended code.
//
- // However disallowing const in classic mode will break compatibility with
+ // However disallowing const in sloppy mode will break compatibility with
// existing pages. Therefore we keep allowing const with the old
- // non-harmony semantics in classic mode.
+ // non-harmony semantics in sloppy mode.
Consume(Token::CONST);
- switch (scope_->language_mode()) {
- case CLASSIC_MODE:
- break;
- case STRICT_MODE: {
- Scanner::Location location = scanner()->peek_location();
- ReportMessageAt(location, "strict_const");
- *ok = false;
- return Statement::Default();
- }
- case EXTENDED_MODE:
- if (var_context != kSourceElement &&
- var_context != kForStatement) {
+ if (strict_mode() == STRICT) {
+ if (FLAG_harmony_scoping) {
+ if (var_context != kSourceElement && var_context != kForStatement) {
ReportMessageAt(scanner()->peek_location(), "unprotected_const");
*ok = false;
return Statement::Default();
}
require_initializer = true;
- break;
+ } else {
+ Scanner::Location location = scanner()->peek_location();
+ ReportMessageAt(location, "strict_const");
+ *ok = false;
+ return Statement::Default();
+ }
}
} else if (peek() == Token::LET) {
// ES6 Draft Rev4 section 12.2.1:
@@ -460,7 +467,9 @@ PreParser::Statement PreParser::ParseVariableDeclarations(
//
// * It is a Syntax Error if the code that matches this production is not
// contained in extended code.
- if (!scope_->is_extended_mode()) {
+ //
+ // TODO(rossberg): make 'let' a legal identifier in sloppy mode.
+ if (!FLAG_harmony_scoping || strict_mode() == SLOPPY) {
ReportMessageAt(scanner()->peek_location(), "illegal_let");
*ok = false;
return Statement::Default();
@@ -513,7 +522,7 @@ PreParser::Statement PreParser::ParseExpressionOrLabelledStatement(bool* ok) {
// Expression is a single identifier, and not, e.g., a parenthesized
// identifier.
ASSERT(!expr.AsIdentifier().IsFutureReserved());
- ASSERT(scope_->is_classic_mode() ||
+ ASSERT(strict_mode() == SLOPPY ||
(!expr.AsIdentifier().IsFutureStrictReserved() &&
!expr.AsIdentifier().IsYield()));
Consume(Token::COLON);
@@ -611,7 +620,7 @@ PreParser::Statement PreParser::ParseWithStatement(bool* ok) {
// WithStatement ::
// 'with' '(' Expression ')' Statement
Expect(Token::WITH, CHECK_OK);
- if (!scope_->is_classic_mode()) {
+ if (strict_mode() == STRICT) {
ReportMessageAt(scanner()->location(), "strict_mode_with");
*ok = false;
return Statement::Default();
@@ -830,60 +839,6 @@ PreParser::Statement PreParser::ParseDebuggerStatement(bool* ok) {
#undef DUMMY
-// Precedence = 2
-PreParser::Expression PreParser::ParseAssignmentExpression(bool accept_IN,
- bool* ok) {
- // AssignmentExpression ::
- // ConditionalExpression
- // YieldExpression
- // LeftHandSideExpression AssignmentOperator AssignmentExpression
-
- if (function_state_->is_generator() && peek() == Token::YIELD) {
- return ParseYieldExpression(ok);
- }
-
- Scanner::Location before = scanner()->peek_location();
- Expression expression = ParseConditionalExpression(accept_IN, CHECK_OK);
-
- if (!Token::IsAssignmentOp(peek())) {
- // Parsed conditional expression only (no assignment).
- return expression;
- }
-
- if (!scope_->is_classic_mode() &&
- expression.IsIdentifier() &&
- expression.AsIdentifier().IsEvalOrArguments()) {
- Scanner::Location after = scanner()->location();
- PreParserTraits::ReportMessageAt(before.beg_pos, after.end_pos,
- "strict_eval_arguments", NULL);
- *ok = false;
- return Expression::Default();
- }
-
- Token::Value op = Next(); // Get assignment operator.
- ParseAssignmentExpression(accept_IN, CHECK_OK);
-
- if ((op == Token::ASSIGN) && expression.IsThisProperty()) {
- function_state_->AddProperty();
- }
-
- return Expression::Default();
-}
-
-
-// Precedence = 3
-PreParser::Expression PreParser::ParseYieldExpression(bool* ok) {
- // YieldExpression ::
- // 'yield' '*'? AssignmentExpression
- Consume(Token::YIELD);
- Check(Token::MUL);
-
- ParseAssignmentExpression(false, CHECK_OK);
-
- return Expression::Default();
-}
-
-
// Precedence = 3
PreParser::Expression PreParser::ParseConditionalExpression(bool accept_IN,
bool* ok) {
@@ -942,15 +897,9 @@ PreParser::Expression PreParser::ParseUnaryExpression(bool* ok) {
return Expression::Default();
} else if (Token::IsCountOp(op)) {
op = Next();
- Scanner::Location before = scanner()->peek_location();
Expression expression = ParseUnaryExpression(CHECK_OK);
- if (!scope_->is_classic_mode() &&
- expression.IsIdentifier() &&
- expression.AsIdentifier().IsEvalOrArguments()) {
- Scanner::Location after = scanner()->location();
- PreParserTraits::ReportMessageAt(before.beg_pos, after.end_pos,
- "strict_eval_arguments", NULL);
- *ok = false;
+ if (strict_mode() == STRICT) {
+ CheckStrictModeLValue(expression, CHECK_OK);
}
return Expression::Default();
} else {
@@ -963,18 +912,11 @@ PreParser::Expression PreParser::ParsePostfixExpression(bool* ok) {
// PostfixExpression ::
// LeftHandSideExpression ('++' | '--')?
- Scanner::Location before = scanner()->peek_location();
Expression expression = ParseLeftHandSideExpression(CHECK_OK);
if (!scanner()->HasAnyLineTerminatorBeforeNext() &&
Token::IsCountOp(peek())) {
- if (!scope_->is_classic_mode() &&
- expression.IsIdentifier() &&
- expression.AsIdentifier().IsEvalOrArguments()) {
- Scanner::Location after = scanner()->location();
- PreParserTraits::ReportMessageAt(before.beg_pos, after.end_pos,
- "strict_eval_arguments", NULL);
- *ok = false;
- return Expression::Default();
+ if (strict_mode() == STRICT) {
+ CheckStrictModeLValue(expression, CHECK_OK);
}
Next();
return Expression::Default();
@@ -1063,20 +1005,25 @@ PreParser::Expression PreParser::ParseMemberExpression(bool* ok) {
Expression result = Expression::Default();
if (peek() == Token::FUNCTION) {
Consume(Token::FUNCTION);
-
+ int function_token_position = position();
bool is_generator = allow_generators() && Check(Token::MUL);
Identifier name = Identifier::Default();
bool is_strict_reserved_name = false;
Scanner::Location function_name_location = Scanner::Location::invalid();
+ FunctionLiteral::FunctionType function_type =
+ FunctionLiteral::ANONYMOUS_EXPRESSION;
if (peek_any_identifier()) {
name = ParseIdentifierOrStrictReservedWord(&is_strict_reserved_name,
CHECK_OK);
function_name_location = scanner()->location();
+ function_type = FunctionLiteral::NAMED_EXPRESSION;
}
result = ParseFunctionLiteral(name,
function_name_location,
is_strict_reserved_name,
is_generator,
+ function_token_position,
+ function_type,
CHECK_OK);
} else {
result = ParsePrimaryExpression(CHECK_OK);
@@ -1122,116 +1069,13 @@ PreParser::Expression PreParser::ParseMemberExpressionContinuation(
}
-PreParser::Expression PreParser::ParseObjectLiteral(bool* ok) {
- // ObjectLiteral ::
- // '{' (
- // ((IdentifierName | String | Number) ':' AssignmentExpression)
- // | (('get' | 'set') (IdentifierName | String | Number) FunctionLiteral)
- // )*[','] '}'
-
- ObjectLiteralChecker checker(this, scope_->language_mode());
-
- Expect(Token::LBRACE, CHECK_OK);
- while (peek() != Token::RBRACE) {
- Token::Value next = peek();
- switch (next) {
- case Token::IDENTIFIER:
- case Token::FUTURE_RESERVED_WORD:
- case Token::FUTURE_STRICT_RESERVED_WORD: {
- bool is_getter = false;
- bool is_setter = false;
- ParseIdentifierNameOrGetOrSet(&is_getter, &is_setter, CHECK_OK);
- if ((is_getter || is_setter) && peek() != Token::COLON) {
- Token::Value name = Next();
- bool is_keyword = Token::IsKeyword(name);
- if (name != Token::IDENTIFIER &&
- name != Token::FUTURE_RESERVED_WORD &&
- name != Token::FUTURE_STRICT_RESERVED_WORD &&
- name != Token::NUMBER &&
- name != Token::STRING &&
- !is_keyword) {
- *ok = false;
- return Expression::Default();
- }
- if (!is_keyword) {
- LogSymbol();
- }
- PropertyKind type = is_getter ? kGetterProperty : kSetterProperty;
- checker.CheckProperty(name, type, CHECK_OK);
- ParseFunctionLiteral(Identifier::Default(),
- scanner()->location(),
- false, // reserved words are allowed here
- false, // not a generator
- CHECK_OK);
- if (peek() != Token::RBRACE) {
- Expect(Token::COMMA, CHECK_OK);
- }
- continue; // restart the while
- }
- checker.CheckProperty(next, kValueProperty, CHECK_OK);
- break;
- }
- case Token::STRING:
- Consume(next);
- checker.CheckProperty(next, kValueProperty, CHECK_OK);
- LogSymbol();
- break;
- case Token::NUMBER:
- Consume(next);
- checker.CheckProperty(next, kValueProperty, CHECK_OK);
- break;
- default:
- if (Token::IsKeyword(next)) {
- Consume(next);
- checker.CheckProperty(next, kValueProperty, CHECK_OK);
- LogSymbol();
- } else {
- // Unexpected token.
- *ok = false;
- return Expression::Default();
- }
- }
-
- Expect(Token::COLON, CHECK_OK);
- ParseAssignmentExpression(true, CHECK_OK);
-
- // TODO(1240767): Consider allowing trailing comma.
- if (peek() != Token::RBRACE) Expect(Token::COMMA, CHECK_OK);
- }
- Expect(Token::RBRACE, CHECK_OK);
-
- function_state_->NextMaterializedLiteralIndex();
- return Expression::Default();
-}
-
-
-PreParser::Arguments PreParser::ParseArguments(bool* ok) {
- // Arguments ::
- // '(' (AssignmentExpression)*[','] ')'
-
- Expect(Token::LPAREN, ok);
- if (!*ok) return -1;
- bool done = (peek() == Token::RPAREN);
- int argc = 0;
- while (!done) {
- ParseAssignmentExpression(true, ok);
- if (!*ok) return -1;
- argc++;
- done = (peek() == Token::RPAREN);
- if (!done) {
- Expect(Token::COMMA, ok);
- if (!*ok) return -1;
- }
- }
- Expect(Token::RPAREN, ok);
- return argc;
-}
-
PreParser::Expression PreParser::ParseFunctionLiteral(
Identifier function_name,
Scanner::Location function_name_location,
bool name_is_strict_reserved,
bool is_generator,
+ int function_token_pos,
+ FunctionLiteral::FunctionType function_type,
bool* ok) {
// Function ::
// '(' FormalParameterList? ')' '{' FunctionBody '}'
@@ -1265,14 +1109,7 @@ PreParser::Expression PreParser::ParseFunctionLiteral(
reserved_error_loc = scanner()->location();
}
- int prev_value;
- if (scanner()->is_literal_ascii()) {
- prev_value =
- duplicate_finder.AddAsciiSymbol(scanner()->literal_ascii_string(), 1);
- } else {
- prev_value =
- duplicate_finder.AddUtf16Symbol(scanner()->literal_utf16_string(), 1);
- }
+ int prev_value = scanner()->FindSymbol(&duplicate_finder, 1);
if (!dupe_error_loc.IsValid() && prev_value != 0) {
dupe_error_loc = scanner()->location();
@@ -1302,7 +1139,7 @@ PreParser::Expression PreParser::ParseFunctionLiteral(
// Validate strict mode. We can do this only after parsing the function,
// since the function can declare itself strict.
- if (!scope_->is_classic_mode()) {
+ if (strict_mode() == STRICT) {
if (function_name.IsEvalOrArguments()) {
ReportMessageAt(function_name_location, "strict_eval_arguments");
*ok = false;
@@ -1340,9 +1177,10 @@ PreParser::Expression PreParser::ParseFunctionLiteral(
void PreParser::ParseLazyFunctionLiteralBody(bool* ok) {
int body_start = position();
- log_->PauseRecording();
+ bool is_logging = log_->ShouldLogSymbols();
+ if (is_logging) log_->PauseRecording();
ParseSourceElements(Token::RBRACE, ok);
- log_->ResumeRecording();
+ if (is_logging) log_->ResumeRecording();
if (!*ok) return;
// Position right after terminal '}'.
@@ -1351,7 +1189,7 @@ void PreParser::ParseLazyFunctionLiteralBody(bool* ok) {
log_->LogFunction(body_start, body_end,
function_state_->materialized_literal_count(),
function_state_->expected_property_count(),
- scope_->language_mode());
+ strict_mode());
}
@@ -1374,11 +1212,8 @@ PreParser::Expression PreParser::ParseV8Intrinsic(bool* ok) {
void PreParser::LogSymbol() {
- int identifier_pos = position();
- if (scanner()->is_literal_ascii()) {
- log_->LogAsciiSymbol(identifier_pos, scanner()->literal_ascii_string());
- } else {
- log_->LogUtf16Symbol(identifier_pos, scanner()->literal_utf16_string());
+ if (log_->ShouldLogSymbols()) {
+ scanner()->LogSymbol(log_, position());
}
}
« no previous file with comments | « src/preparser.h ('k') | src/profile-generator-inl.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698