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

Side by Side Diff: src/preparser.cc

Issue 6927075: Strict mode detection in preparser. (Closed)
Patch Set: Added TODO with bugnumber for R Created 9 years, 7 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 unified diff | Download patch
« no previous file with comments | « src/preparser.h ('k') | src/preparser-api.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2010 the V8 project authors. All rights reserved. 1 // Copyright 2010 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 16 matching lines...) Expand all
27 27
28 #include "../include/v8stdint.h" 28 #include "../include/v8stdint.h"
29 #include "unicode.h" 29 #include "unicode.h"
30 #include "globals.h" 30 #include "globals.h"
31 #include "checks.h" 31 #include "checks.h"
32 #include "allocation.h" 32 #include "allocation.h"
33 #include "utils.h" 33 #include "utils.h"
34 #include "list.h" 34 #include "list.h"
35 35
36 #include "scanner-base.h" 36 #include "scanner-base.h"
37 #include "preparse-data-format.h"
37 #include "preparse-data.h" 38 #include "preparse-data.h"
38 #include "preparser.h" 39 #include "preparser.h"
39 40
40 namespace v8 { 41 namespace v8 {
41 namespace preparser { 42 namespace preparser {
42 43
43 // Preparsing checks a JavaScript program and emits preparse-data that helps 44 // Preparsing checks a JavaScript program and emits preparse-data that helps
44 // a later parsing to be faster. 45 // a later parsing to be faster.
45 // See preparser-data.h for the data. 46 // See preparser-data.h for the data.
46 47
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
87 return ReportMessageAt(source_location.beg_pos, source_location.end_pos, 88 return ReportMessageAt(source_location.beg_pos, source_location.end_pos,
88 "unexpected_token_identifier", NULL); 89 "unexpected_token_identifier", NULL);
89 default: 90 default:
90 const char* name = i::Token::String(token); 91 const char* name = i::Token::String(token);
91 ReportMessageAt(source_location.beg_pos, source_location.end_pos, 92 ReportMessageAt(source_location.beg_pos, source_location.end_pos,
92 "unexpected_token", name); 93 "unexpected_token", name);
93 } 94 }
94 } 95 }
95 96
96 97
98 // Checks whether octal literal last seen is between beg_pos and end_pos.
99 // If so, reports an error.
100 void PreParser::CheckOctalLiteral(int beg_pos, int end_pos, bool* ok) {
101 i::Scanner::Location octal = scanner_->octal_position();
102 if (beg_pos <= octal.beg_pos && octal.end_pos <= end_pos) {
103 ReportMessageAt(octal.beg_pos, octal.end_pos, "strict_octal_literal", NULL);
104 scanner_->clear_octal_position();
105 *ok = false;
106 }
107 }
108
109
97 PreParser::SourceElements PreParser::ParseSourceElements(int end_token, 110 PreParser::SourceElements PreParser::ParseSourceElements(int end_token,
98 bool* ok) { 111 bool* ok) {
99 // SourceElements :: 112 // SourceElements ::
100 // (Statement)* <end_token> 113 // (Statement)* <end_token>
101 114
115 bool allow_directive_prologue = true;
102 while (peek() != end_token) { 116 while (peek() != end_token) {
103 ParseStatement(CHECK_OK); 117 Statement statement = ParseStatement(CHECK_OK);
118 if (allow_directive_prologue) {
119 if (statement == kUseStrictExpressionStatement) {
120 set_strict_mode();
121 } else if (statement != kStringLiteralExpressionStatement) {
122 allow_directive_prologue = false;
123 }
124 }
104 } 125 }
105 return kUnknownSourceElements; 126 return kUnknownSourceElements;
106 } 127 }
107 128
108 129
109 PreParser::Statement PreParser::ParseStatement(bool* ok) { 130 PreParser::Statement PreParser::ParseStatement(bool* ok) {
110 // Statement :: 131 // Statement ::
111 // Block 132 // Block
112 // VariableStatement 133 // VariableStatement
113 // EmptyStatement 134 // EmptyStatement
(...skipping 178 matching lines...) Expand 10 before | Expand all | Expand 10 after
292 313
293 PreParser::Statement PreParser::ParseExpressionOrLabelledStatement( 314 PreParser::Statement PreParser::ParseExpressionOrLabelledStatement(
294 bool* ok) { 315 bool* ok) {
295 // ExpressionStatement | LabelledStatement :: 316 // ExpressionStatement | LabelledStatement ::
296 // Expression ';' 317 // Expression ';'
297 // Identifier ':' Statement 318 // Identifier ':' Statement
298 319
299 Expression expr = ParseExpression(true, CHECK_OK); 320 Expression expr = ParseExpression(true, CHECK_OK);
300 if (peek() == i::Token::COLON && expr == kIdentifierExpression) { 321 if (peek() == i::Token::COLON && expr == kIdentifierExpression) {
301 Consume(i::Token::COLON); 322 Consume(i::Token::COLON);
302 return ParseStatement(ok); 323 ParseStatement(ok);
324 return kUnknownStatement;
303 } 325 }
304 // Parsed expression statement. 326 // Parsed expression statement.
305 ExpectSemicolon(CHECK_OK); 327 ExpectSemicolon(CHECK_OK);
328 if (expr == kStringLiteralExpression) {
329 return kStringLiteralExpressionStatement;
330 }
331 if (expr == kUseStrictString) {
332 return kUseStrictExpressionStatement;
333 }
306 return kUnknownStatement; 334 return kUnknownStatement;
307 } 335 }
308 336
309 337
310 PreParser::Statement PreParser::ParseIfStatement(bool* ok) { 338 PreParser::Statement PreParser::ParseIfStatement(bool* ok) {
311 // IfStatement :: 339 // IfStatement ::
312 // 'if' '(' Expression ')' Statement ('else' Statement)? 340 // 'if' '(' Expression ')' Statement ('else' Statement)?
313 341
314 Expect(i::Token::IF, CHECK_OK); 342 Expect(i::Token::IF, CHECK_OK);
315 Expect(i::Token::LPAREN, CHECK_OK); 343 Expect(i::Token::LPAREN, CHECK_OK);
(...skipping 734 matching lines...) Expand 10 before | Expand all | Expand 10 after
1050 1078
1051 1079
1052 PreParser::Expression PreParser::ParseFunctionLiteral(bool* ok) { 1080 PreParser::Expression PreParser::ParseFunctionLiteral(bool* ok) {
1053 // Function :: 1081 // Function ::
1054 // '(' FormalParameterList? ')' '{' FunctionBody '}' 1082 // '(' FormalParameterList? ')' '{' FunctionBody '}'
1055 1083
1056 // Parse function body. 1084 // Parse function body.
1057 ScopeType outer_scope_type = scope_->type(); 1085 ScopeType outer_scope_type = scope_->type();
1058 bool inside_with = scope_->IsInsideWith(); 1086 bool inside_with = scope_->IsInsideWith();
1059 Scope function_scope(&scope_, kFunctionScope); 1087 Scope function_scope(&scope_, kFunctionScope);
1060
1061 // FormalParameterList :: 1088 // FormalParameterList ::
1062 // '(' (Identifier)*[','] ')' 1089 // '(' (Identifier)*[','] ')'
1063 Expect(i::Token::LPAREN, CHECK_OK); 1090 Expect(i::Token::LPAREN, CHECK_OK);
1091 int start_position = scanner_->location().beg_pos;
1064 bool done = (peek() == i::Token::RPAREN); 1092 bool done = (peek() == i::Token::RPAREN);
1065 while (!done) { 1093 while (!done) {
1066 ParseIdentifier(CHECK_OK); 1094 ParseIdentifier(CHECK_OK);
1067 done = (peek() == i::Token::RPAREN); 1095 done = (peek() == i::Token::RPAREN);
1068 if (!done) { 1096 if (!done) {
1069 Expect(i::Token::COMMA, CHECK_OK); 1097 Expect(i::Token::COMMA, CHECK_OK);
1070 } 1098 }
1071 } 1099 }
1072 Expect(i::Token::RPAREN, CHECK_OK); 1100 Expect(i::Token::RPAREN, CHECK_OK);
1073 1101
(...skipping 18 matching lines...) Expand all
1092 1120
1093 // Position right after terminal '}'. 1121 // Position right after terminal '}'.
1094 int end_pos = scanner_->location().end_pos; 1122 int end_pos = scanner_->location().end_pos;
1095 log_->LogFunction(function_block_pos, end_pos, 1123 log_->LogFunction(function_block_pos, end_pos,
1096 function_scope.materialized_literal_count(), 1124 function_scope.materialized_literal_count(),
1097 function_scope.expected_properties()); 1125 function_scope.expected_properties());
1098 } else { 1126 } else {
1099 ParseSourceElements(i::Token::RBRACE, CHECK_OK); 1127 ParseSourceElements(i::Token::RBRACE, CHECK_OK);
1100 Expect(i::Token::RBRACE, CHECK_OK); 1128 Expect(i::Token::RBRACE, CHECK_OK);
1101 } 1129 }
1130
1131 if (scope_->is_strict()) {
1132 int end_position = scanner_->location().end_pos;
1133 CheckOctalLiteral(start_position, end_position, CHECK_OK);
1134 }
1135
1102 return kUnknownExpression; 1136 return kUnknownExpression;
1103 } 1137 }
1104 1138
1105 1139
1106 PreParser::Expression PreParser::ParseV8Intrinsic(bool* ok) { 1140 PreParser::Expression PreParser::ParseV8Intrinsic(bool* ok) {
1107 // CallRuntime :: 1141 // CallRuntime ::
1108 // '%' Identifier Arguments 1142 // '%' Identifier Arguments
1109 1143
1110 Expect(i::Token::MOD, CHECK_OK); 1144 Expect(i::Token::MOD, CHECK_OK);
1111 ParseIdentifier(CHECK_OK); 1145 ParseIdentifier(CHECK_OK);
(...skipping 30 matching lines...) Expand all
1142 } 1176 }
1143 1177
1144 1178
1145 PreParser::Identifier PreParser::GetIdentifierSymbol() { 1179 PreParser::Identifier PreParser::GetIdentifierSymbol() {
1146 LogSymbol(); 1180 LogSymbol();
1147 return kUnknownIdentifier; 1181 return kUnknownIdentifier;
1148 } 1182 }
1149 1183
1150 1184
1151 PreParser::Expression PreParser::GetStringSymbol() { 1185 PreParser::Expression PreParser::GetStringSymbol() {
1186 const int kUseStrictLength = 10;
1187 const char* kUseStrictChars = "use strict";
1152 LogSymbol(); 1188 LogSymbol();
1153 return kUnknownExpression; 1189 if (scanner_->is_literal_ascii() &&
1190 scanner_->literal_length() == kUseStrictLength &&
1191 !scanner_->literal_contains_escapes() &&
1192 !strncmp(scanner_->literal_ascii_string().start(), kUseStrictChars,
1193 kUseStrictLength)) {
1194 return kUseStrictString;
1195 }
1196 return kStringLiteralExpression;
1154 } 1197 }
1155 1198
1156 1199
1157 PreParser::Identifier PreParser::ParseIdentifier(bool* ok) { 1200 PreParser::Identifier PreParser::ParseIdentifier(bool* ok) {
1158 if (!Check(i::Token::FUTURE_RESERVED_WORD)) { 1201 if (!Check(i::Token::FUTURE_RESERVED_WORD)) {
1159 Expect(i::Token::IDENTIFIER, ok); 1202 Expect(i::Token::IDENTIFIER, ok);
1160 } 1203 }
1161 if (!*ok) return kUnknownIdentifier; 1204 if (!*ok) return kUnknownIdentifier;
1162 return GetIdentifierSymbol(); 1205 return GetIdentifierSymbol();
1163 } 1206 }
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
1196 } 1239 }
1197 1240
1198 bool PreParser::peek_any_identifier() { 1241 bool PreParser::peek_any_identifier() {
1199 i::Token::Value next = peek(); 1242 i::Token::Value next = peek();
1200 return next == i::Token::IDENTIFIER || 1243 return next == i::Token::IDENTIFIER ||
1201 next == i::Token::FUTURE_RESERVED_WORD; 1244 next == i::Token::FUTURE_RESERVED_WORD;
1202 } 1245 }
1203 1246
1204 #undef CHECK_OK 1247 #undef CHECK_OK
1205 } } // v8::preparser 1248 } } // v8::preparser
OLDNEW
« no previous file with comments | « src/preparser.h ('k') | src/preparser-api.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698