summaryrefslogtreecommitdiff
path: root/deps/v8/src/preparser.cc
diff options
context:
space:
mode:
Diffstat (limited to 'deps/v8/src/preparser.cc')
-rw-r--r--deps/v8/src/preparser.cc56
1 files changed, 41 insertions, 15 deletions
diff --git a/deps/v8/src/preparser.cc b/deps/v8/src/preparser.cc
index c741b4655..1a3dd737c 100644
--- a/deps/v8/src/preparser.cc
+++ b/deps/v8/src/preparser.cc
@@ -56,8 +56,6 @@ namespace preparser {
// That means that contextual checks (like a label being declared where
// it is used) are generally omitted.
-namespace i = ::v8::internal;
-
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
@@ -114,6 +112,16 @@ void PreParser::CheckOctalLiteral(int beg_pos, int end_pos, bool* ok) {
#undef DUMMY
+PreParser::Statement PreParser::ParseSourceElement(bool* ok) {
+ switch (peek()) {
+ case i::Token::LET:
+ return ParseVariableStatement(kSourceElement, ok);
+ default:
+ return ParseStatement(ok);
+ }
+}
+
+
PreParser::SourceElements PreParser::ParseSourceElements(int end_token,
bool* ok) {
// SourceElements ::
@@ -121,7 +129,7 @@ PreParser::SourceElements PreParser::ParseSourceElements(int end_token,
bool allow_directive_prologue = true;
while (peek() != end_token) {
- Statement statement = ParseStatement(CHECK_OK);
+ Statement statement = ParseSourceElement(CHECK_OK);
if (allow_directive_prologue) {
if (statement.IsUseStrictLiteral()) {
set_strict_mode();
@@ -174,7 +182,7 @@ PreParser::Statement PreParser::ParseStatement(bool* ok) {
case i::Token::CONST:
case i::Token::VAR:
- return ParseVariableStatement(ok);
+ return ParseVariableStatement(kStatement, ok);
case i::Token::SEMICOLON:
Next();
@@ -260,7 +268,7 @@ PreParser::Statement PreParser::ParseBlock(bool* ok) {
Expect(i::Token::LBRACE, CHECK_OK);
while (peek() != i::Token::RBRACE) {
i::Scanner::Location start_location = scanner_->peek_location();
- Statement statement = ParseStatement(CHECK_OK);
+ Statement statement = ParseSourceElement(CHECK_OK);
i::Scanner::Location end_location = scanner_->location();
if (strict_mode() && statement.IsFunctionDeclaration()) {
ReportMessageAt(start_location.beg_pos, end_location.end_pos,
@@ -274,11 +282,15 @@ PreParser::Statement PreParser::ParseBlock(bool* ok) {
}
-PreParser::Statement PreParser::ParseVariableStatement(bool* ok) {
+PreParser::Statement PreParser::ParseVariableStatement(
+ VariableDeclarationContext var_context,
+ bool* ok) {
// VariableStatement ::
// VariableDeclarations ';'
- Statement result = ParseVariableDeclarations(true, NULL, CHECK_OK);
+ Statement result = ParseVariableDeclarations(var_context,
+ NULL,
+ CHECK_OK);
ExpectSemicolon(CHECK_OK);
return result;
}
@@ -289,9 +301,10 @@ PreParser::Statement PreParser::ParseVariableStatement(bool* ok) {
// *var is untouched; in particular, it is the caller's responsibility
// to initialize it properly. This mechanism is also used for the parsing
// of 'for-in' loops.
-PreParser::Statement PreParser::ParseVariableDeclarations(bool accept_IN,
- int* num_decl,
- bool* ok) {
+PreParser::Statement PreParser::ParseVariableDeclarations(
+ VariableDeclarationContext var_context,
+ int* num_decl,
+ bool* ok) {
// VariableDeclarations ::
// ('var' | 'const') (Identifier ('=' AssignmentExpression)?)+[',']
@@ -306,13 +319,25 @@ PreParser::Statement PreParser::ParseVariableDeclarations(bool accept_IN,
return Statement::Default();
}
Consume(i::Token::CONST);
+ } else if (peek() == i::Token::LET) {
+ if (var_context != kSourceElement &&
+ var_context != kForStatement) {
+ i::Scanner::Location location = scanner_->peek_location();
+ ReportMessageAt(location.beg_pos, location.end_pos,
+ "unprotected_let", NULL);
+ *ok = false;
+ return Statement::Default();
+ }
+ Consume(i::Token::LET);
} else {
*ok = false;
return Statement::Default();
}
- // The scope of a variable/const declared anywhere inside a function
- // is the entire function (ECMA-262, 3rd, 10.1.3, and 12.2). .
+ // The scope of a var/const declared variable anywhere inside a function
+ // is the entire function (ECMA-262, 3rd, 10.1.3, and 12.2). The scope
+ // of a let declared variable is the scope of the immediately enclosing
+ // block.
int nvars = 0; // the number of variables declared
do {
// Parse variable name.
@@ -328,7 +353,7 @@ PreParser::Statement PreParser::ParseVariableDeclarations(bool accept_IN,
nvars++;
if (peek() == i::Token::ASSIGN) {
Expect(i::Token::ASSIGN, CHECK_OK);
- ParseAssignmentExpression(accept_IN, CHECK_OK);
+ ParseAssignmentExpression(var_context != kForStatement, CHECK_OK);
}
} while (peek() == i::Token::COMMA);
@@ -537,9 +562,10 @@ PreParser::Statement PreParser::ParseForStatement(bool* ok) {
Expect(i::Token::FOR, CHECK_OK);
Expect(i::Token::LPAREN, CHECK_OK);
if (peek() != i::Token::SEMICOLON) {
- if (peek() == i::Token::VAR || peek() == i::Token::CONST) {
+ if (peek() == i::Token::VAR || peek() == i::Token::CONST ||
+ peek() == i::Token::LET) {
int decl_count;
- ParseVariableDeclarations(false, &decl_count, CHECK_OK);
+ ParseVariableDeclarations(kForStatement, &decl_count, CHECK_OK);
if (peek() == i::Token::IN && decl_count == 1) {
Expect(i::Token::IN, CHECK_OK);
ParseExpression(true, CHECK_OK);