Index: src/preparser.cc |
diff --git a/src/preparser.cc b/src/preparser.cc |
index fec1567c0ec6d46cfb0182010f297b05a1570ad3..5bd9906f73b2644a366c9ee4adc2a2fd3c266f8e 100644 |
--- a/src/preparser.cc |
+++ b/src/preparser.cc |
@@ -34,6 +34,7 @@ |
#include "list.h" |
#include "scanner-base.h" |
+#include "preparse-data-format.h" |
#include "preparse-data.h" |
#include "preparser.h" |
@@ -94,13 +95,33 @@ 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(); |
+ if (beg_pos <= octal.beg_pos && octal.end_pos <= end_pos) { |
+ ReportMessageAt(octal.beg_pos, octal.end_pos, "strict_octal_literal", NULL); |
+ scanner_->clear_octal_position(); |
+ *ok = false; |
+ } |
+} |
+ |
+ |
PreParser::SourceElements PreParser::ParseSourceElements(int end_token, |
bool* ok) { |
// SourceElements :: |
// (Statement)* <end_token> |
+ bool allow_directive_prologue = true; |
while (peek() != end_token) { |
- ParseStatement(CHECK_OK); |
+ Statement statement = ParseStatement(CHECK_OK); |
+ if (allow_directive_prologue) { |
+ if (statement == kUseStrictExpressionStatement) { |
+ set_strict_mode(); |
+ } else if (statement != kStringLiteralExpressionStatement) { |
+ allow_directive_prologue = false; |
+ } |
+ } |
} |
return kUnknownSourceElements; |
} |
@@ -299,10 +320,17 @@ PreParser::Statement PreParser::ParseExpressionOrLabelledStatement( |
Expression expr = ParseExpression(true, CHECK_OK); |
if (peek() == i::Token::COLON && expr == kIdentifierExpression) { |
Consume(i::Token::COLON); |
- return ParseStatement(ok); |
+ ParseStatement(ok); |
+ return kUnknownStatement; |
} |
// Parsed expression statement. |
ExpectSemicolon(CHECK_OK); |
+ if (expr == kStringLiteralExpression) { |
+ return kStringLiteralExpressionStatement; |
+ } |
+ if (expr == kUseStrictString) { |
+ return kUseStrictExpressionStatement; |
+ } |
return kUnknownStatement; |
} |
@@ -1057,10 +1085,10 @@ PreParser::Expression PreParser::ParseFunctionLiteral(bool* ok) { |
ScopeType outer_scope_type = scope_->type(); |
bool inside_with = scope_->IsInsideWith(); |
Scope function_scope(&scope_, kFunctionScope); |
- |
// FormalParameterList :: |
// '(' (Identifier)*[','] ')' |
Expect(i::Token::LPAREN, CHECK_OK); |
+ int start_position = scanner_->location().beg_pos; |
bool done = (peek() == i::Token::RPAREN); |
while (!done) { |
ParseIdentifier(CHECK_OK); |
@@ -1099,6 +1127,12 @@ PreParser::Expression PreParser::ParseFunctionLiteral(bool* ok) { |
ParseSourceElements(i::Token::RBRACE, CHECK_OK); |
Expect(i::Token::RBRACE, CHECK_OK); |
} |
+ |
+ if (scope_->is_strict()) { |
+ int end_position = scanner_->location().end_pos; |
+ CheckOctalLiteral(start_position, end_position, CHECK_OK); |
+ } |
+ |
return kUnknownExpression; |
} |
@@ -1149,8 +1183,17 @@ PreParser::Identifier PreParser::GetIdentifierSymbol() { |
PreParser::Expression PreParser::GetStringSymbol() { |
+ const int kUseStrictLength = 10; |
+ const char* kUseStrictChars = "use strict"; |
LogSymbol(); |
- return kUnknownExpression; |
+ if (scanner_->is_literal_ascii() && |
+ scanner_->literal_length() == kUseStrictLength && |
+ !scanner_->literal_contains_escapes() && |
+ !strncmp(scanner_->literal_ascii_string().start(), kUseStrictChars, |
+ kUseStrictLength)) { |
+ return kUseStrictString; |
+ } |
+ return kStringLiteralExpression; |
} |