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

Side by Side Diff: src/preparser.cc

Issue 185653004: Experimental parser: merge to r19637 (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 unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/preparser.h ('k') | src/prettyprinter.h » ('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 2011 the V8 project authors. All rights reserved. 1 // Copyright 2011 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 24 matching lines...) Expand all
35 #include "conversions-inl.h" 35 #include "conversions-inl.h"
36 #include "globals.h" 36 #include "globals.h"
37 #include "hashmap.h" 37 #include "hashmap.h"
38 #include "list.h" 38 #include "list.h"
39 #include "preparse-data-format.h" 39 #include "preparse-data-format.h"
40 #include "preparse-data.h" 40 #include "preparse-data.h"
41 #include "preparser.h" 41 #include "preparser.h"
42 #include "unicode.h" 42 #include "unicode.h"
43 #include "utils.h" 43 #include "utils.h"
44 44
45 #if V8_CC_MSVC && (_MSC_VER < 1800) 45 #if V8_LIBC_MSVCRT && (_MSC_VER < 1800)
46 namespace std { 46 namespace std {
47 47
48 // Usually defined in math.h, but not in MSVC until VS2013+. 48 // Usually defined in math.h, but not in MSVC until VS2013+.
49 // Abstracted to work 49 // Abstracted to work
50 int isfinite(double value); 50 int isfinite(double value);
51 51
52 } // namespace std 52 } // namespace std
53 #endif 53 #endif
54 54
55 namespace v8 { 55 namespace v8 {
56 namespace internal { 56 namespace internal {
57 57
58 void PreParserTraits::ReportMessageAt(Scanner::Location location,
59 const char* message,
60 Vector<const char*> args) {
61 ReportMessageAt(location.beg_pos,
62 location.end_pos,
63 message,
64 args.length() > 0 ? args[0] : NULL);
65 }
66
67
68 void PreParserTraits::ReportMessageAt(Scanner::Location location,
69 const char* type,
70 const char* name_opt) {
71 pre_parser_->log_
72 ->LogMessage(location.beg_pos, location.end_pos, type, name_opt);
73 }
74
75
76 void PreParserTraits::ReportMessageAt(int start_pos,
77 int end_pos,
78 const char* type,
79 const char* name_opt) {
80 pre_parser_->log_->LogMessage(start_pos, end_pos, type, name_opt);
81 }
82
83
84 PreParserIdentifier PreParserTraits::GetSymbol(Scanner* scanner) {
85 pre_parser_->LogSymbol();
86 if (scanner->current_token() == Token::FUTURE_RESERVED_WORD) {
87 return PreParserIdentifier::FutureReserved();
88 } else if (scanner->current_token() ==
89 Token::FUTURE_STRICT_RESERVED_WORD) {
90 return PreParserIdentifier::FutureStrictReserved();
91 } else if (scanner->current_token() == Token::YIELD) {
92 return PreParserIdentifier::Yield();
93 }
94 if (scanner->is_literal_ascii()) {
95 // Detect strict-mode poison words.
96 if (scanner->literal_length() == 4 &&
97 !strncmp(scanner->literal_ascii_string().start(), "eval", 4)) {
98 return PreParserIdentifier::Eval();
99 }
100 if (scanner->literal_length() == 9 &&
101 !strncmp(scanner->literal_ascii_string().start(), "arguments", 9)) {
102 return PreParserIdentifier::Arguments();
103 }
104 }
105 return PreParserIdentifier::Default();
106 }
107
108
109 PreParserExpression PreParserTraits::ExpressionFromString(
110 int pos, Scanner* scanner, PreParserFactory* factory) {
111 const int kUseStrictLength = 10;
112 const char* kUseStrictChars = "use strict";
113 pre_parser_->LogSymbol();
114 if (scanner->is_literal_ascii() &&
115 scanner->literal_length() == kUseStrictLength &&
116 !scanner->literal_contains_escapes() &&
117 !strncmp(scanner->literal_ascii_string().start(), kUseStrictChars,
118 kUseStrictLength)) {
119 return PreParserExpression::UseStrictStringLiteral();
120 }
121 return PreParserExpression::StringLiteral();
122 }
123
124
125 PreParserExpression PreParserTraits::ParseObjectLiteral(bool* ok) {
126 return pre_parser_->ParseObjectLiteral(ok);
127 }
128
129
130 PreParserExpression PreParserTraits::ParseAssignmentExpression(bool accept_IN,
131 bool* ok) {
132 return pre_parser_->ParseAssignmentExpression(accept_IN, ok);
133 }
134
135
136 PreParserExpression PreParserTraits::ParseV8Intrinsic(bool* ok) {
137 return pre_parser_->ParseV8Intrinsic(ok);
138 }
139
140
58 PreParser::PreParseResult PreParser::PreParseLazyFunction( 141 PreParser::PreParseResult PreParser::PreParseLazyFunction(
59 LanguageMode mode, bool is_generator, ParserRecorder* log) { 142 LanguageMode mode, bool is_generator, ParserRecorder* log) {
60 log_ = log; 143 log_ = log;
61 // Lazy functions always have trivial outer scopes (no with/catch scopes). 144 // Lazy functions always have trivial outer scopes (no with/catch scopes).
62 Scope top_scope(&scope_, kTopLevelScope); 145 PreParserScope top_scope(scope_, GLOBAL_SCOPE);
63 set_language_mode(mode); 146 FunctionState top_state(&function_state_, &scope_, &top_scope);
64 Scope function_scope(&scope_, kFunctionScope); 147 scope_->SetLanguageMode(mode);
65 function_scope.set_is_generator(is_generator); 148 PreParserScope function_scope(scope_, FUNCTION_SCOPE);
149 FunctionState function_state(&function_state_, &scope_, &function_scope);
150 function_state.set_is_generator(is_generator);
66 ASSERT_EQ(Token::LBRACE, scanner()->current_token()); 151 ASSERT_EQ(Token::LBRACE, scanner()->current_token());
67 bool ok = true; 152 bool ok = true;
68 int start_position = peek_position(); 153 int start_position = peek_position();
69 ParseLazyFunctionLiteralBody(&ok); 154 ParseLazyFunctionLiteralBody(&ok);
70 if (stack_overflow()) return kPreParseStackOverflow; 155 if (stack_overflow()) return kPreParseStackOverflow;
71 if (!ok) { 156 if (!ok) {
72 ReportUnexpectedToken(scanner()->current_token()); 157 ReportUnexpectedToken(scanner()->current_token());
73 } else { 158 } else {
74 ASSERT_EQ(Token::RBRACE, scanner()->peek()); 159 ASSERT_EQ(Token::RBRACE, scanner()->peek());
75 if (!is_classic_mode()) { 160 if (!scope_->is_classic_mode()) {
76 int end_pos = scanner()->location().end_pos; 161 int end_pos = scanner()->location().end_pos;
77 CheckOctalLiteral(start_position, end_pos, &ok); 162 CheckOctalLiteral(start_position, end_pos, &ok);
78 if (ok) {
79 CheckDelayedStrictModeViolation(start_position, end_pos, &ok);
80 }
81 } 163 }
82 } 164 }
83 return kPreParseSuccess; 165 return kPreParseSuccess;
84 } 166 }
85 167
86 168
87 // Preparsing checks a JavaScript program and emits preparse-data that helps 169 // Preparsing checks a JavaScript program and emits preparse-data that helps
88 // a later parsing to be faster. 170 // a later parsing to be faster.
89 // See preparser-data.h for the data. 171 // See preparser-data.h for the data.
90 172
91 // The PreParser checks that the syntax follows the grammar for JavaScript, 173 // The PreParser checks that the syntax follows the grammar for JavaScript,
92 // and collects some information about the program along the way. 174 // and collects some information about the program along the way.
93 // The grammar check is only performed in order to understand the program 175 // The grammar check is only performed in order to understand the program
94 // sufficiently to deduce some information about it, that can be used 176 // sufficiently to deduce some information about it, that can be used
95 // to speed up later parsing. Finding errors is not the goal of pre-parsing, 177 // to speed up later parsing. Finding errors is not the goal of pre-parsing,
96 // rather it is to speed up properly written and correct programs. 178 // rather it is to speed up properly written and correct programs.
97 // That means that contextual checks (like a label being declared where 179 // That means that contextual checks (like a label being declared where
98 // it is used) are generally omitted. 180 // it is used) are generally omitted.
99 181
100 void PreParser::ReportUnexpectedToken(Token::Value token) {
101 // We don't report stack overflows here, to avoid increasing the
102 // stack depth even further. Instead we report it after parsing is
103 // over, in ParseProgram.
104 if (token == Token::ILLEGAL && stack_overflow()) {
105 return;
106 }
107 ScannerBase::Location source_location = scanner()->location();
108
109 // Four of the tokens are treated specially
110 switch (token) {
111 case Token::EOS:
112 return ReportMessageAt(source_location, "unexpected_eos", NULL);
113 case Token::NUMBER:
114 return ReportMessageAt(source_location, "unexpected_token_number", NULL);
115 case Token::STRING:
116 return ReportMessageAt(source_location, "unexpected_token_string", NULL);
117 case Token::IDENTIFIER:
118 return ReportMessageAt(source_location,
119 "unexpected_token_identifier", NULL);
120 case Token::FUTURE_RESERVED_WORD:
121 return ReportMessageAt(source_location, "unexpected_reserved", NULL);
122 case Token::FUTURE_STRICT_RESERVED_WORD:
123 return ReportMessageAt(source_location,
124 "unexpected_strict_reserved", NULL);
125 default:
126 const char* name = Token::String(token);
127 ReportMessageAt(source_location, "unexpected_token", name);
128 }
129 }
130
131 182
132 #define CHECK_OK ok); \ 183 #define CHECK_OK ok); \
133 if (!*ok) return kUnknownSourceElements; \ 184 if (!*ok) return kUnknownSourceElements; \
134 ((void)0 185 ((void)0
135 #define DUMMY ) // to make indentation work 186 #define DUMMY ) // to make indentation work
136 #undef DUMMY 187 #undef DUMMY
137 188
138 189
139 PreParser::Statement PreParser::ParseSourceElement(bool* ok) { 190 PreParser::Statement PreParser::ParseSourceElement(bool* ok) {
140 // (Ecma 262 5th Edition, clause 14): 191 // (Ecma 262 5th Edition, clause 14):
(...skipping 17 matching lines...) Expand all
158 return ParseStatement(ok); 209 return ParseStatement(ok);
159 } 210 }
160 } 211 }
161 212
162 213
163 PreParser::SourceElements PreParser::ParseSourceElements(int end_token, 214 PreParser::SourceElements PreParser::ParseSourceElements(int end_token,
164 bool* ok) { 215 bool* ok) {
165 // SourceElements :: 216 // SourceElements ::
166 // (Statement)* <end_token> 217 // (Statement)* <end_token>
167 218
168 bool allow_directive_prologue = true; 219 bool directive_prologue = true;
169 while (peek() != end_token) { 220 while (peek() != end_token) {
221 if (directive_prologue && peek() != Token::STRING) {
222 directive_prologue = false;
223 }
170 Statement statement = ParseSourceElement(CHECK_OK); 224 Statement statement = ParseSourceElement(CHECK_OK);
171 if (allow_directive_prologue) { 225 if (directive_prologue) {
172 if (statement.IsUseStrictLiteral()) { 226 if (statement.IsUseStrictLiteral()) {
173 set_language_mode(allow_harmony_scoping() ? 227 scope_->SetLanguageMode(allow_harmony_scoping() ?
174 EXTENDED_MODE : STRICT_MODE); 228 EXTENDED_MODE : STRICT_MODE);
175 } else if (!statement.IsStringLiteral()) { 229 } else if (!statement.IsStringLiteral()) {
176 allow_directive_prologue = false; 230 directive_prologue = false;
177 } 231 }
178 } 232 }
179 } 233 }
180 return kUnknownSourceElements; 234 return kUnknownSourceElements;
181 } 235 }
182 236
183 237
184 #undef CHECK_OK 238 #undef CHECK_OK
185 #define CHECK_OK ok); \ 239 #define CHECK_OK ok); \
186 if (!*ok) return Statement::Default(); \ 240 if (!*ok) return Statement::Default(); \
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after
255 case Token::SWITCH: 309 case Token::SWITCH:
256 return ParseSwitchStatement(ok); 310 return ParseSwitchStatement(ok);
257 311
258 case Token::THROW: 312 case Token::THROW:
259 return ParseThrowStatement(ok); 313 return ParseThrowStatement(ok);
260 314
261 case Token::TRY: 315 case Token::TRY:
262 return ParseTryStatement(ok); 316 return ParseTryStatement(ok);
263 317
264 case Token::FUNCTION: { 318 case Token::FUNCTION: {
265 ScannerBase::Location start_location = scanner()->peek_location(); 319 Scanner::Location start_location = scanner()->peek_location();
266 Statement statement = ParseFunctionDeclaration(CHECK_OK); 320 Statement statement = ParseFunctionDeclaration(CHECK_OK);
267 ScannerBase::Location end_location = scanner()->location(); 321 Scanner::Location end_location = scanner()->location();
268 if (!is_classic_mode()) { 322 if (!scope_->is_classic_mode()) {
269 ReportMessageAt(start_location.beg_pos, end_location.end_pos, 323 PreParserTraits::ReportMessageAt(start_location.beg_pos,
270 "strict_function", NULL); 324 end_location.end_pos,
325 "strict_function",
326 NULL);
271 *ok = false; 327 *ok = false;
272 return Statement::Default(); 328 return Statement::Default();
273 } else { 329 } else {
274 return statement; 330 return statement;
275 } 331 }
276 } 332 }
277 333
278 case Token::DEBUGGER: 334 case Token::DEBUGGER:
279 return ParseDebuggerStatement(ok); 335 return ParseDebuggerStatement(ok);
280 336
281 default: 337 default:
282 return ParseExpressionOrLabelledStatement(ok); 338 return ParseExpressionOrLabelledStatement(ok);
283 } 339 }
284 } 340 }
285 341
286 342
287 PreParser::Statement PreParser::ParseFunctionDeclaration(bool* ok) { 343 PreParser::Statement PreParser::ParseFunctionDeclaration(bool* ok) {
288 // FunctionDeclaration :: 344 // FunctionDeclaration ::
289 // 'function' Identifier '(' FormalParameterListopt ')' '{' FunctionBody '}' 345 // 'function' Identifier '(' FormalParameterListopt ')' '{' FunctionBody '}'
290 // GeneratorDeclaration :: 346 // GeneratorDeclaration ::
291 // 'function' '*' Identifier '(' FormalParameterListopt ')' 347 // 'function' '*' Identifier '(' FormalParameterListopt ')'
292 // '{' FunctionBody '}' 348 // '{' FunctionBody '}'
293 Expect(Token::FUNCTION, CHECK_OK); 349 Expect(Token::FUNCTION, CHECK_OK);
294 350
295 bool is_generator = allow_generators() && Check(Token::MUL); 351 bool is_generator = allow_generators() && Check(Token::MUL);
296 Identifier identifier = ParseIdentifier(CHECK_OK); 352 bool is_strict_reserved = false;
297 ScannerBase::Location location = scanner()->location(); 353 Identifier name = ParseIdentifierOrStrictReservedWord(
298 354 &is_strict_reserved, CHECK_OK);
299 Expression function_value = ParseFunctionLiteral(is_generator, CHECK_OK); 355 ParseFunctionLiteral(name,
300 356 scanner()->location(),
301 if (function_value.IsStrictFunction() && 357 is_strict_reserved,
302 !identifier.IsValidStrictVariable()) { 358 is_generator,
303 // Strict mode violation, using either reserved word or eval/arguments 359 CHECK_OK);
304 // as name of strict function.
305 const char* type = "strict_function_name";
306 if (identifier.IsFutureStrictReserved() || identifier.IsYield()) {
307 type = "strict_reserved_word";
308 }
309 ReportMessageAt(location, type, NULL);
310 *ok = false;
311 }
312 return Statement::FunctionDeclaration(); 360 return Statement::FunctionDeclaration();
313 } 361 }
314 362
315 363
316 PreParser::Statement PreParser::ParseBlock(bool* ok) { 364 PreParser::Statement PreParser::ParseBlock(bool* ok) {
317 // Block :: 365 // Block ::
318 // '{' Statement* '}' 366 // '{' Statement* '}'
319 367
320 // Note that a Block does not introduce a new execution scope! 368 // Note that a Block does not introduce a new execution scope!
321 // (ECMA-262, 3rd, 12.2) 369 // (ECMA-262, 3rd, 12.2)
322 // 370 //
323 Expect(Token::LBRACE, CHECK_OK); 371 Expect(Token::LBRACE, CHECK_OK);
324 while (peek() != Token::RBRACE) { 372 while (peek() != Token::RBRACE) {
325 if (is_extended_mode()) { 373 if (scope_->is_extended_mode()) {
326 ParseSourceElement(CHECK_OK); 374 ParseSourceElement(CHECK_OK);
327 } else { 375 } else {
328 ParseStatement(CHECK_OK); 376 ParseStatement(CHECK_OK);
329 } 377 }
330 } 378 }
331 Expect(Token::RBRACE, ok); 379 Expect(Token::RBRACE, ok);
332 return Statement::Default(); 380 return Statement::Default();
333 } 381 }
334 382
335 383
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
379 // 427 //
380 // ConstDeclaration : const ConstBinding (',' ConstBinding)* ';' 428 // ConstDeclaration : const ConstBinding (',' ConstBinding)* ';'
381 // 429 //
382 // * It is a Syntax Error if the code that matches this production is not 430 // * It is a Syntax Error if the code that matches this production is not
383 // contained in extended code. 431 // contained in extended code.
384 // 432 //
385 // However disallowing const in classic mode will break compatibility with 433 // However disallowing const in classic mode will break compatibility with
386 // existing pages. Therefore we keep allowing const with the old 434 // existing pages. Therefore we keep allowing const with the old
387 // non-harmony semantics in classic mode. 435 // non-harmony semantics in classic mode.
388 Consume(Token::CONST); 436 Consume(Token::CONST);
389 switch (language_mode()) { 437 switch (scope_->language_mode()) {
390 case CLASSIC_MODE: 438 case CLASSIC_MODE:
391 break; 439 break;
392 case STRICT_MODE: { 440 case STRICT_MODE: {
393 ScannerBase::Location location = scanner()->peek_location(); 441 Scanner::Location location = scanner()->peek_location();
394 ReportMessageAt(location, "strict_const", NULL); 442 ReportMessageAt(location, "strict_const");
395 *ok = false; 443 *ok = false;
396 return Statement::Default(); 444 return Statement::Default();
397 } 445 }
398 case EXTENDED_MODE: 446 case EXTENDED_MODE:
399 if (var_context != kSourceElement && 447 if (var_context != kSourceElement &&
400 var_context != kForStatement) { 448 var_context != kForStatement) {
401 ScannerBase::Location location = scanner()->peek_location(); 449 ReportMessageAt(scanner()->peek_location(), "unprotected_const");
402 ReportMessageAt(location.beg_pos, location.end_pos,
403 "unprotected_const", NULL);
404 *ok = false; 450 *ok = false;
405 return Statement::Default(); 451 return Statement::Default();
406 } 452 }
407 require_initializer = true; 453 require_initializer = true;
408 break; 454 break;
409 } 455 }
410 } else if (peek() == Token::LET) { 456 } else if (peek() == Token::LET) {
411 // ES6 Draft Rev4 section 12.2.1: 457 // ES6 Draft Rev4 section 12.2.1:
412 // 458 //
413 // LetDeclaration : let LetBindingList ; 459 // LetDeclaration : let LetBindingList ;
414 // 460 //
415 // * It is a Syntax Error if the code that matches this production is not 461 // * It is a Syntax Error if the code that matches this production is not
416 // contained in extended code. 462 // contained in extended code.
417 if (!is_extended_mode()) { 463 if (!scope_->is_extended_mode()) {
418 ScannerBase::Location location = scanner()->peek_location(); 464 ReportMessageAt(scanner()->peek_location(), "illegal_let");
419 ReportMessageAt(location.beg_pos, location.end_pos,
420 "illegal_let", NULL);
421 *ok = false; 465 *ok = false;
422 return Statement::Default(); 466 return Statement::Default();
423 } 467 }
424 Consume(Token::LET); 468 Consume(Token::LET);
425 if (var_context != kSourceElement && 469 if (var_context != kSourceElement &&
426 var_context != kForStatement) { 470 var_context != kForStatement) {
427 ScannerBase::Location location = scanner()->peek_location(); 471 ReportMessageAt(scanner()->peek_location(), "unprotected_let");
428 ReportMessageAt(location.beg_pos, location.end_pos,
429 "unprotected_let", NULL);
430 *ok = false; 472 *ok = false;
431 return Statement::Default(); 473 return Statement::Default();
432 } 474 }
433 } else { 475 } else {
434 *ok = false; 476 *ok = false;
435 return Statement::Default(); 477 return Statement::Default();
436 } 478 }
437 479
438 // The scope of a var/const declared variable anywhere inside a function 480 // The scope of a var/const declared variable anywhere inside a function
439 // is the entire function (ECMA-262, 3rd, 10.1.3, and 12.2). The scope 481 // is the entire function (ECMA-262, 3rd, 10.1.3, and 12.2). The scope
440 // of a let declared variable is the scope of the immediately enclosing 482 // of a let declared variable is the scope of the immediately enclosing
441 // block. 483 // block.
442 int nvars = 0; // the number of variables declared 484 int nvars = 0; // the number of variables declared
443 do { 485 do {
444 // Parse variable name. 486 // Parse variable name.
445 if (nvars > 0) Consume(Token::COMMA); 487 if (nvars > 0) Consume(Token::COMMA);
446 Identifier identifier = ParseIdentifier(CHECK_OK); 488 ParseIdentifier(kDontAllowEvalOrArguments, CHECK_OK);
447 if (!is_classic_mode() && !identifier.IsValidStrictVariable()) {
448 StrictModeIdentifierViolation(scanner()->location(),
449 "strict_var_name",
450 identifier,
451 ok);
452 return Statement::Default();
453 }
454 nvars++; 489 nvars++;
455 if (peek() == Token::ASSIGN || require_initializer) { 490 if (peek() == Token::ASSIGN || require_initializer) {
456 Expect(Token::ASSIGN, CHECK_OK); 491 Expect(Token::ASSIGN, CHECK_OK);
457 ParseAssignmentExpression(var_context != kForStatement, CHECK_OK); 492 ParseAssignmentExpression(var_context != kForStatement, CHECK_OK);
458 if (decl_props != NULL) *decl_props = kHasInitializers; 493 if (decl_props != NULL) *decl_props = kHasInitializers;
459 } 494 }
460 } while (peek() == Token::COMMA); 495 } while (peek() == Token::COMMA);
461 496
462 if (num_decl != NULL) *num_decl = nvars; 497 if (num_decl != NULL) *num_decl = nvars;
463 return Statement::Default(); 498 return Statement::Default();
464 } 499 }
465 500
466 501
467 PreParser::Statement PreParser::ParseExpressionOrLabelledStatement(bool* ok) { 502 PreParser::Statement PreParser::ParseExpressionOrLabelledStatement(bool* ok) {
468 // ExpressionStatement | LabelledStatement :: 503 // ExpressionStatement | LabelledStatement ::
469 // Expression ';' 504 // Expression ';'
470 // Identifier ':' Statement 505 // Identifier ':' Statement
471 506
507 bool starts_with_identifier = peek_any_identifier();
472 Expression expr = ParseExpression(true, CHECK_OK); 508 Expression expr = ParseExpression(true, CHECK_OK);
473 if (expr.IsRawIdentifier()) { 509 // Even if the expression starts with an identifier, it is not necessarily an
510 // identifier. For example, "foo + bar" starts with an identifier but is not
511 // an identifier.
512 if (starts_with_identifier && expr.IsIdentifier() && peek() == Token::COLON) {
513 // Expression is a single identifier, and not, e.g., a parenthesized
514 // identifier.
474 ASSERT(!expr.AsIdentifier().IsFutureReserved()); 515 ASSERT(!expr.AsIdentifier().IsFutureReserved());
475 ASSERT(is_classic_mode() || 516 ASSERT(scope_->is_classic_mode() ||
476 (!expr.AsIdentifier().IsFutureStrictReserved() && 517 (!expr.AsIdentifier().IsFutureStrictReserved() &&
477 !expr.AsIdentifier().IsYield())); 518 !expr.AsIdentifier().IsYield()));
478 if (peek() == Token::COLON) { 519 Consume(Token::COLON);
479 Consume(Token::COLON); 520 return ParseStatement(ok);
480 return ParseStatement(ok);
481 }
482 // Preparsing is disabled for extensions (because the extension details 521 // Preparsing is disabled for extensions (because the extension details
483 // aren't passed to lazily compiled functions), so we don't 522 // aren't passed to lazily compiled functions), so we don't
484 // accept "native function" in the preparser. 523 // accept "native function" in the preparser.
485 } 524 }
486 // Parsed expression statement. 525 // Parsed expression statement.
487 ExpectSemicolon(CHECK_OK); 526 ExpectSemicolon(CHECK_OK);
488 return Statement::ExpressionStatement(expr); 527 return Statement::ExpressionStatement(expr);
489 } 528 }
490 529
491 530
(...skipping 17 matching lines...) Expand all
509 PreParser::Statement PreParser::ParseContinueStatement(bool* ok) { 548 PreParser::Statement PreParser::ParseContinueStatement(bool* ok) {
510 // ContinueStatement :: 549 // ContinueStatement ::
511 // 'continue' [no line terminator] Identifier? ';' 550 // 'continue' [no line terminator] Identifier? ';'
512 551
513 Expect(Token::CONTINUE, CHECK_OK); 552 Expect(Token::CONTINUE, CHECK_OK);
514 Token::Value tok = peek(); 553 Token::Value tok = peek();
515 if (!scanner()->HasAnyLineTerminatorBeforeNext() && 554 if (!scanner()->HasAnyLineTerminatorBeforeNext() &&
516 tok != Token::SEMICOLON && 555 tok != Token::SEMICOLON &&
517 tok != Token::RBRACE && 556 tok != Token::RBRACE &&
518 tok != Token::EOS) { 557 tok != Token::EOS) {
519 ParseIdentifier(CHECK_OK); 558 // ECMA allows "eval" or "arguments" as labels even in strict mode.
559 ParseIdentifier(kAllowEvalOrArguments, CHECK_OK);
520 } 560 }
521 ExpectSemicolon(CHECK_OK); 561 ExpectSemicolon(CHECK_OK);
522 return Statement::Default(); 562 return Statement::Default();
523 } 563 }
524 564
525 565
526 PreParser::Statement PreParser::ParseBreakStatement(bool* ok) { 566 PreParser::Statement PreParser::ParseBreakStatement(bool* ok) {
527 // BreakStatement :: 567 // BreakStatement ::
528 // 'break' [no line terminator] Identifier? ';' 568 // 'break' [no line terminator] Identifier? ';'
529 569
530 Expect(Token::BREAK, CHECK_OK); 570 Expect(Token::BREAK, CHECK_OK);
531 Token::Value tok = peek(); 571 Token::Value tok = peek();
532 if (!scanner()->HasAnyLineTerminatorBeforeNext() && 572 if (!scanner()->HasAnyLineTerminatorBeforeNext() &&
533 tok != Token::SEMICOLON && 573 tok != Token::SEMICOLON &&
534 tok != Token::RBRACE && 574 tok != Token::RBRACE &&
535 tok != Token::EOS) { 575 tok != Token::EOS) {
536 ParseIdentifier(CHECK_OK); 576 // ECMA allows "eval" or "arguments" as labels even in strict mode.
577 ParseIdentifier(kAllowEvalOrArguments, CHECK_OK);
537 } 578 }
538 ExpectSemicolon(CHECK_OK); 579 ExpectSemicolon(CHECK_OK);
539 return Statement::Default(); 580 return Statement::Default();
540 } 581 }
541 582
542 583
543 PreParser::Statement PreParser::ParseReturnStatement(bool* ok) { 584 PreParser::Statement PreParser::ParseReturnStatement(bool* ok) {
544 // ReturnStatement :: 585 // ReturnStatement ::
545 // 'return' [no line terminator] Expression? ';' 586 // 'return' [no line terminator] Expression? ';'
546 587
(...skipping 16 matching lines...) Expand all
563 } 604 }
564 ExpectSemicolon(CHECK_OK); 605 ExpectSemicolon(CHECK_OK);
565 return Statement::Default(); 606 return Statement::Default();
566 } 607 }
567 608
568 609
569 PreParser::Statement PreParser::ParseWithStatement(bool* ok) { 610 PreParser::Statement PreParser::ParseWithStatement(bool* ok) {
570 // WithStatement :: 611 // WithStatement ::
571 // 'with' '(' Expression ')' Statement 612 // 'with' '(' Expression ')' Statement
572 Expect(Token::WITH, CHECK_OK); 613 Expect(Token::WITH, CHECK_OK);
573 if (!is_classic_mode()) { 614 if (!scope_->is_classic_mode()) {
574 ScannerBase::Location location = scanner()->location(); 615 ReportMessageAt(scanner()->location(), "strict_mode_with");
575 ReportMessageAt(location, "strict_mode_with", NULL);
576 *ok = false; 616 *ok = false;
577 return Statement::Default(); 617 return Statement::Default();
578 } 618 }
579 Expect(Token::LPAREN, CHECK_OK); 619 Expect(Token::LPAREN, CHECK_OK);
580 ParseExpression(true, CHECK_OK); 620 ParseExpression(true, CHECK_OK);
581 Expect(Token::RPAREN, CHECK_OK); 621 Expect(Token::RPAREN, CHECK_OK);
582 622
583 Scope::InsideWith iw(scope_); 623 PreParserScope with_scope(scope_, WITH_SCOPE);
624 BlockState block_state(&scope_, &with_scope);
584 ParseStatement(CHECK_OK); 625 ParseStatement(CHECK_OK);
585 return Statement::Default(); 626 return Statement::Default();
586 } 627 }
587 628
588 629
589 PreParser::Statement PreParser::ParseSwitchStatement(bool* ok) { 630 PreParser::Statement PreParser::ParseSwitchStatement(bool* ok) {
590 // SwitchStatement :: 631 // SwitchStatement ::
591 // 'switch' '(' Expression ')' '{' CaseClause* '}' 632 // 'switch' '(' Expression ')' '{' CaseClause* '}'
592 633
593 Expect(Token::SWITCH, CHECK_OK); 634 Expect(Token::SWITCH, CHECK_OK);
(...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after
709 return Statement::Default(); 750 return Statement::Default();
710 } 751 }
711 752
712 753
713 PreParser::Statement PreParser::ParseThrowStatement(bool* ok) { 754 PreParser::Statement PreParser::ParseThrowStatement(bool* ok) {
714 // ThrowStatement :: 755 // ThrowStatement ::
715 // 'throw' [no line terminator] Expression ';' 756 // 'throw' [no line terminator] Expression ';'
716 757
717 Expect(Token::THROW, CHECK_OK); 758 Expect(Token::THROW, CHECK_OK);
718 if (scanner()->HasAnyLineTerminatorBeforeNext()) { 759 if (scanner()->HasAnyLineTerminatorBeforeNext()) {
719 ScannerBase::Location pos = scanner()->location(); 760 ReportMessageAt(scanner()->location(), "newline_after_throw");
720 ReportMessageAt(pos, "newline_after_throw", NULL);
721 *ok = false; 761 *ok = false;
722 return Statement::Default(); 762 return Statement::Default();
723 } 763 }
724 ParseExpression(true, CHECK_OK); 764 ParseExpression(true, CHECK_OK);
725 ExpectSemicolon(ok); 765 ExpectSemicolon(ok);
726 return Statement::Default(); 766 return Statement::Default();
727 } 767 }
728 768
729 769
730 PreParser::Statement PreParser::ParseTryStatement(bool* ok) { 770 PreParser::Statement PreParser::ParseTryStatement(bool* ok) {
731 // TryStatement :: 771 // TryStatement ::
732 // 'try' Block Catch 772 // 'try' Block Catch
733 // 'try' Block Finally 773 // 'try' Block Finally
734 // 'try' Block Catch Finally 774 // 'try' Block Catch Finally
735 // 775 //
736 // Catch :: 776 // Catch ::
737 // 'catch' '(' Identifier ')' Block 777 // 'catch' '(' Identifier ')' Block
738 // 778 //
739 // Finally :: 779 // Finally ::
740 // 'finally' Block 780 // 'finally' Block
741 781
742 // In preparsing, allow any number of catch/finally blocks, including zero
743 // of both.
744
745 Expect(Token::TRY, CHECK_OK); 782 Expect(Token::TRY, CHECK_OK);
746 783
747 ParseBlock(CHECK_OK); 784 ParseBlock(CHECK_OK);
748 785
749 bool catch_or_finally_seen = false; 786 Token::Value tok = peek();
750 if (peek() == Token::CATCH) { 787 if (tok != Token::CATCH && tok != Token::FINALLY) {
788 ReportMessageAt(scanner()->location(), "no_catch_or_finally");
789 *ok = false;
790 return Statement::Default();
791 }
792 if (tok == Token::CATCH) {
751 Consume(Token::CATCH); 793 Consume(Token::CATCH);
752 Expect(Token::LPAREN, CHECK_OK); 794 Expect(Token::LPAREN, CHECK_OK);
753 Identifier id = ParseIdentifier(CHECK_OK); 795 ParseIdentifier(kDontAllowEvalOrArguments, CHECK_OK);
754 if (!is_classic_mode() && !id.IsValidStrictVariable()) {
755 StrictModeIdentifierViolation(scanner()->location(),
756 "strict_catch_variable",
757 id,
758 ok);
759 return Statement::Default();
760 }
761 Expect(Token::RPAREN, CHECK_OK); 796 Expect(Token::RPAREN, CHECK_OK);
762 { Scope::InsideWith iw(scope_); 797 {
798 PreParserScope with_scope(scope_, WITH_SCOPE);
799 BlockState block_state(&scope_, &with_scope);
763 ParseBlock(CHECK_OK); 800 ParseBlock(CHECK_OK);
764 } 801 }
765 catch_or_finally_seen = true; 802 tok = peek();
766 } 803 }
767 if (peek() == Token::FINALLY) { 804 if (tok == Token::FINALLY) {
768 Consume(Token::FINALLY); 805 Consume(Token::FINALLY);
769 ParseBlock(CHECK_OK); 806 ParseBlock(CHECK_OK);
770 catch_or_finally_seen = true;
771 }
772 if (!catch_or_finally_seen) {
773 *ok = false;
774 } 807 }
775 return Statement::Default(); 808 return Statement::Default();
776 } 809 }
777 810
778 811
779 PreParser::Statement PreParser::ParseDebuggerStatement(bool* ok) { 812 PreParser::Statement PreParser::ParseDebuggerStatement(bool* ok) {
780 // In ECMA-262 'debugger' is defined as a reserved keyword. In some browser 813 // In ECMA-262 'debugger' is defined as a reserved keyword. In some browser
781 // contexts this is used as a statement which invokes the debugger as if a 814 // contexts this is used as a statement which invokes the debugger as if a
782 // break point is present. 815 // break point is present.
783 // DebuggerStatement :: 816 // DebuggerStatement ::
784 // 'debugger' ';' 817 // 'debugger' ';'
785 818
786 Expect(Token::DEBUGGER, CHECK_OK); 819 Expect(Token::DEBUGGER, CHECK_OK);
787 ExpectSemicolon(ok); 820 ExpectSemicolon(ok);
788 return Statement::Default(); 821 return Statement::Default();
789 } 822 }
790 823
791 824
792 #undef CHECK_OK 825 #undef CHECK_OK
793 #define CHECK_OK ok); \ 826 #define CHECK_OK ok); \
794 if (!*ok) return Expression::Default(); \ 827 if (!*ok) return Expression::Default(); \
795 ((void)0 828 ((void)0
796 #define DUMMY ) // to make indentation work 829 #define DUMMY ) // to make indentation work
797 #undef DUMMY 830 #undef DUMMY
798 831
799 832
800 // Precedence = 1
801 PreParser::Expression PreParser::ParseExpression(bool accept_IN, bool* ok) {
802 // Expression ::
803 // AssignmentExpression
804 // Expression ',' AssignmentExpression
805
806 Expression result = ParseAssignmentExpression(accept_IN, CHECK_OK);
807 while (peek() == Token::COMMA) {
808 Expect(Token::COMMA, CHECK_OK);
809 ParseAssignmentExpression(accept_IN, CHECK_OK);
810 result = Expression::Default();
811 }
812 return result;
813 }
814
815
816 // Precedence = 2 833 // Precedence = 2
817 PreParser::Expression PreParser::ParseAssignmentExpression(bool accept_IN, 834 PreParser::Expression PreParser::ParseAssignmentExpression(bool accept_IN,
818 bool* ok) { 835 bool* ok) {
819 // AssignmentExpression :: 836 // AssignmentExpression ::
820 // ConditionalExpression 837 // ConditionalExpression
821 // YieldExpression 838 // YieldExpression
822 // LeftHandSideExpression AssignmentOperator AssignmentExpression 839 // LeftHandSideExpression AssignmentOperator AssignmentExpression
823 840
824 if (scope_->is_generator() && peek() == Token::YIELD) { 841 if (function_state_->is_generator() && peek() == Token::YIELD) {
825 return ParseYieldExpression(ok); 842 return ParseYieldExpression(ok);
826 } 843 }
827 844
828 ScannerBase::Location before = scanner()->peek_location(); 845 Scanner::Location before = scanner()->peek_location();
829 Expression expression = ParseConditionalExpression(accept_IN, CHECK_OK); 846 Expression expression = ParseConditionalExpression(accept_IN, CHECK_OK);
830 847
831 if (!Token::IsAssignmentOp(peek())) { 848 if (!Token::IsAssignmentOp(peek())) {
832 // Parsed conditional expression only (no assignment). 849 // Parsed conditional expression only (no assignment).
833 return expression; 850 return expression;
834 } 851 }
835 852
836 if (!is_classic_mode() && 853 if (!scope_->is_classic_mode() &&
837 expression.IsIdentifier() && 854 expression.IsIdentifier() &&
838 expression.AsIdentifier().IsEvalOrArguments()) { 855 expression.AsIdentifier().IsEvalOrArguments()) {
839 ScannerBase::Location after = scanner()->location(); 856 Scanner::Location after = scanner()->location();
840 ReportMessageAt(before.beg_pos, after.end_pos, 857 PreParserTraits::ReportMessageAt(before.beg_pos, after.end_pos,
841 "strict_lhs_assignment", NULL); 858 "strict_eval_arguments", NULL);
842 *ok = false; 859 *ok = false;
843 return Expression::Default(); 860 return Expression::Default();
844 } 861 }
845 862
846 Token::Value op = Next(); // Get assignment operator. 863 Token::Value op = Next(); // Get assignment operator.
847 ParseAssignmentExpression(accept_IN, CHECK_OK); 864 ParseAssignmentExpression(accept_IN, CHECK_OK);
848 865
849 if ((op == Token::ASSIGN) && expression.IsThisProperty()) { 866 if ((op == Token::ASSIGN) && expression.IsThisProperty()) {
850 scope_->AddProperty(); 867 function_state_->AddProperty();
851 } 868 }
852 869
853 return Expression::Default(); 870 return Expression::Default();
854 } 871 }
855 872
856 873
857 // Precedence = 3 874 // Precedence = 3
858 PreParser::Expression PreParser::ParseYieldExpression(bool* ok) { 875 PreParser::Expression PreParser::ParseYieldExpression(bool* ok) {
859 // YieldExpression :: 876 // YieldExpression ::
860 // 'yield' '*'? AssignmentExpression 877 // 'yield' '*'? AssignmentExpression
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
918 // '~' UnaryExpression 935 // '~' UnaryExpression
919 // '!' UnaryExpression 936 // '!' UnaryExpression
920 937
921 Token::Value op = peek(); 938 Token::Value op = peek();
922 if (Token::IsUnaryOp(op)) { 939 if (Token::IsUnaryOp(op)) {
923 op = Next(); 940 op = Next();
924 ParseUnaryExpression(ok); 941 ParseUnaryExpression(ok);
925 return Expression::Default(); 942 return Expression::Default();
926 } else if (Token::IsCountOp(op)) { 943 } else if (Token::IsCountOp(op)) {
927 op = Next(); 944 op = Next();
928 ScannerBase::Location before = scanner()->peek_location(); 945 Scanner::Location before = scanner()->peek_location();
929 Expression expression = ParseUnaryExpression(CHECK_OK); 946 Expression expression = ParseUnaryExpression(CHECK_OK);
930 if (!is_classic_mode() && 947 if (!scope_->is_classic_mode() &&
931 expression.IsIdentifier() && 948 expression.IsIdentifier() &&
932 expression.AsIdentifier().IsEvalOrArguments()) { 949 expression.AsIdentifier().IsEvalOrArguments()) {
933 ScannerBase::Location after = scanner()->location(); 950 Scanner::Location after = scanner()->location();
934 ReportMessageAt(before.beg_pos, after.end_pos, 951 PreParserTraits::ReportMessageAt(before.beg_pos, after.end_pos,
935 "strict_lhs_prefix", NULL); 952 "strict_eval_arguments", NULL);
936 *ok = false; 953 *ok = false;
937 } 954 }
938 return Expression::Default(); 955 return Expression::Default();
939 } else { 956 } else {
940 return ParsePostfixExpression(ok); 957 return ParsePostfixExpression(ok);
941 } 958 }
942 } 959 }
943 960
944 961
945 PreParser::Expression PreParser::ParsePostfixExpression(bool* ok) { 962 PreParser::Expression PreParser::ParsePostfixExpression(bool* ok) {
946 // PostfixExpression :: 963 // PostfixExpression ::
947 // LeftHandSideExpression ('++' | '--')? 964 // LeftHandSideExpression ('++' | '--')?
948 965
949 ScannerBase::Location before = scanner()->peek_location(); 966 Scanner::Location before = scanner()->peek_location();
950 Expression expression = ParseLeftHandSideExpression(CHECK_OK); 967 Expression expression = ParseLeftHandSideExpression(CHECK_OK);
951 if (!scanner()->HasAnyLineTerminatorBeforeNext() && 968 if (!scanner()->HasAnyLineTerminatorBeforeNext() &&
952 Token::IsCountOp(peek())) { 969 Token::IsCountOp(peek())) {
953 if (!is_classic_mode() && 970 if (!scope_->is_classic_mode() &&
954 expression.IsIdentifier() && 971 expression.IsIdentifier() &&
955 expression.AsIdentifier().IsEvalOrArguments()) { 972 expression.AsIdentifier().IsEvalOrArguments()) {
956 ScannerBase::Location after = scanner()->location(); 973 Scanner::Location after = scanner()->location();
957 ReportMessageAt(before.beg_pos, after.end_pos, 974 PreParserTraits::ReportMessageAt(before.beg_pos, after.end_pos,
958 "strict_lhs_postfix", NULL); 975 "strict_eval_arguments", NULL);
959 *ok = false; 976 *ok = false;
960 return Expression::Default(); 977 return Expression::Default();
961 } 978 }
962 Next(); 979 Next();
963 return Expression::Default(); 980 return Expression::Default();
964 } 981 }
965 return expression; 982 return expression;
966 } 983 }
967 984
968 985
969 PreParser::Expression PreParser::ParseLeftHandSideExpression(bool* ok) { 986 PreParser::Expression PreParser::ParseLeftHandSideExpression(bool* ok) {
970 // LeftHandSideExpression :: 987 // LeftHandSideExpression ::
971 // (NewExpression | MemberExpression) ... 988 // (NewExpression | MemberExpression) ...
972 989
973 Expression result = Expression::Default(); 990 Expression result = ParseMemberWithNewPrefixesExpression(CHECK_OK);
974 if (peek() == Token::NEW) {
975 result = ParseNewExpression(CHECK_OK);
976 } else {
977 result = ParseMemberExpression(CHECK_OK);
978 }
979 991
980 while (true) { 992 while (true) {
981 switch (peek()) { 993 switch (peek()) {
982 case Token::LBRACK: { 994 case Token::LBRACK: {
983 Consume(Token::LBRACK); 995 Consume(Token::LBRACK);
984 ParseExpression(true, CHECK_OK); 996 ParseExpression(true, CHECK_OK);
985 Expect(Token::RBRACK, CHECK_OK); 997 Expect(Token::RBRACK, CHECK_OK);
986 if (result.IsThis()) { 998 if (result.IsThis()) {
987 result = Expression::ThisProperty(); 999 result = Expression::ThisProperty();
988 } else { 1000 } else {
(...skipping 19 matching lines...) Expand all
1008 break; 1020 break;
1009 } 1021 }
1010 1022
1011 default: 1023 default:
1012 return result; 1024 return result;
1013 } 1025 }
1014 } 1026 }
1015 } 1027 }
1016 1028
1017 1029
1018 PreParser::Expression PreParser::ParseNewExpression(bool* ok) { 1030 PreParser::Expression PreParser::ParseMemberWithNewPrefixesExpression(
1031 bool* ok) {
1019 // NewExpression :: 1032 // NewExpression ::
1020 // ('new')+ MemberExpression 1033 // ('new')+ MemberExpression
1021 1034
1022 // The grammar for new expressions is pretty warped. The keyword 1035 // See Parser::ParseNewExpression.
1023 // 'new' can either be a part of the new expression (where it isn't 1036
1024 // followed by an argument list) or a part of the member expression, 1037 if (peek() == Token::NEW) {
1025 // where it must be followed by an argument list. To accommodate
1026 // this, we parse the 'new' keywords greedily and keep track of how
1027 // many we have parsed. This information is then passed on to the
1028 // member expression parser, which is only allowed to match argument
1029 // lists as long as it has 'new' prefixes left
1030 unsigned new_count = 0;
1031 do {
1032 Consume(Token::NEW); 1038 Consume(Token::NEW);
1033 new_count++; 1039 ParseMemberWithNewPrefixesExpression(CHECK_OK);
1034 } while (peek() == Token::NEW); 1040 if (peek() == Token::LPAREN) {
1035 1041 // NewExpression with arguments.
1036 return ParseMemberWithNewPrefixesExpression(new_count, ok); 1042 ParseArguments(CHECK_OK);
1043 // The expression can still continue with . or [ after the arguments.
1044 ParseMemberExpressionContinuation(Expression::Default(), CHECK_OK);
1045 }
1046 return Expression::Default();
1047 }
1048 // No 'new' keyword.
1049 return ParseMemberExpression(ok);
1037 } 1050 }
1038 1051
1039 1052
1040 PreParser::Expression PreParser::ParseMemberExpression(bool* ok) { 1053 PreParser::Expression PreParser::ParseMemberExpression(bool* ok) {
1041 return ParseMemberWithNewPrefixesExpression(0, ok);
1042 }
1043
1044
1045 PreParser::Expression PreParser::ParseMemberWithNewPrefixesExpression(
1046 unsigned new_count, bool* ok) {
1047 // MemberExpression :: 1054 // MemberExpression ::
1048 // (PrimaryExpression | FunctionLiteral) 1055 // (PrimaryExpression | FunctionLiteral)
1049 // ('[' Expression ']' | '.' Identifier | Arguments)* 1056 // ('[' Expression ']' | '.' Identifier | Arguments)*
1050 1057
1058 // The '[' Expression ']' and '.' Identifier parts are parsed by
1059 // ParseMemberExpressionContinuation, and the Arguments part is parsed by the
1060 // caller.
1061
1051 // Parse the initial primary or function expression. 1062 // Parse the initial primary or function expression.
1052 Expression result = Expression::Default(); 1063 Expression result = Expression::Default();
1053 if (peek() == Token::FUNCTION) { 1064 if (peek() == Token::FUNCTION) {
1054 Consume(Token::FUNCTION); 1065 Consume(Token::FUNCTION);
1055 1066
1056 bool is_generator = allow_generators() && Check(Token::MUL); 1067 bool is_generator = allow_generators() && Check(Token::MUL);
1057 Identifier identifier = Identifier::Default(); 1068 Identifier name = Identifier::Default();
1069 bool is_strict_reserved_name = false;
1070 Scanner::Location function_name_location = Scanner::Location::invalid();
1058 if (peek_any_identifier()) { 1071 if (peek_any_identifier()) {
1059 identifier = ParseIdentifier(CHECK_OK); 1072 name = ParseIdentifierOrStrictReservedWord(&is_strict_reserved_name,
1073 CHECK_OK);
1074 function_name_location = scanner()->location();
1060 } 1075 }
1061 result = ParseFunctionLiteral(is_generator, CHECK_OK); 1076 result = ParseFunctionLiteral(name,
1062 if (result.IsStrictFunction() && !identifier.IsValidStrictVariable()) { 1077 function_name_location,
1063 StrictModeIdentifierViolation(scanner()->location(), 1078 is_strict_reserved_name,
1064 "strict_function_name", 1079 is_generator,
1065 identifier, 1080 CHECK_OK);
1066 ok);
1067 return Expression::Default();
1068 }
1069 } else { 1081 } else {
1070 result = ParsePrimaryExpression(CHECK_OK); 1082 result = ParsePrimaryExpression(CHECK_OK);
1071 } 1083 }
1084 result = ParseMemberExpressionContinuation(result, CHECK_OK);
1085 return result;
1086 }
1072 1087
1088
1089 PreParser::Expression PreParser::ParseMemberExpressionContinuation(
1090 PreParserExpression expression, bool* ok) {
1091 // Parses this part of MemberExpression:
1092 // ('[' Expression ']' | '.' Identifier)*
1073 while (true) { 1093 while (true) {
1074 switch (peek()) { 1094 switch (peek()) {
1075 case Token::LBRACK: { 1095 case Token::LBRACK: {
1076 Consume(Token::LBRACK); 1096 Consume(Token::LBRACK);
1077 ParseExpression(true, CHECK_OK); 1097 ParseExpression(true, CHECK_OK);
1078 Expect(Token::RBRACK, CHECK_OK); 1098 Expect(Token::RBRACK, CHECK_OK);
1079 if (result.IsThis()) { 1099 if (expression.IsThis()) {
1080 result = Expression::ThisProperty(); 1100 expression = Expression::ThisProperty();
1081 } else { 1101 } else {
1082 result = Expression::Default(); 1102 expression = Expression::Default();
1083 } 1103 }
1084 break; 1104 break;
1085 } 1105 }
1086 case Token::PERIOD: { 1106 case Token::PERIOD: {
1087 Consume(Token::PERIOD); 1107 Consume(Token::PERIOD);
1088 ParseIdentifierName(CHECK_OK); 1108 ParseIdentifierName(CHECK_OK);
1089 if (result.IsThis()) { 1109 if (expression.IsThis()) {
1090 result = Expression::ThisProperty(); 1110 expression = Expression::ThisProperty();
1091 } else { 1111 } else {
1092 result = Expression::Default(); 1112 expression = Expression::Default();
1093 } 1113 }
1094 break; 1114 break;
1095 } 1115 }
1096 case Token::LPAREN: {
1097 if (new_count == 0) return result;
1098 // Consume one of the new prefixes (already parsed).
1099 ParseArguments(CHECK_OK);
1100 new_count--;
1101 result = Expression::Default();
1102 break;
1103 }
1104 default: 1116 default:
1105 return result; 1117 return expression;
1106 } 1118 }
1107 } 1119 }
1120 ASSERT(false);
1121 return PreParserExpression::Default();
1108 } 1122 }
1109 1123
1110 1124
1111 PreParser::Expression PreParser::ParsePrimaryExpression(bool* ok) {
1112 // PrimaryExpression ::
1113 // 'this'
1114 // 'null'
1115 // 'true'
1116 // 'false'
1117 // Identifier
1118 // Number
1119 // String
1120 // ArrayLiteral
1121 // ObjectLiteral
1122 // RegExpLiteral
1123 // '(' Expression ')'
1124
1125 Expression result = Expression::Default();
1126 switch (peek()) {
1127 case Token::THIS: {
1128 Next();
1129 result = Expression::This();
1130 break;
1131 }
1132
1133 case Token::FUTURE_RESERVED_WORD:
1134 case Token::FUTURE_STRICT_RESERVED_WORD:
1135 case Token::YIELD:
1136 case Token::IDENTIFIER: {
1137 Identifier id = ParseIdentifier(CHECK_OK);
1138 result = Expression::FromIdentifier(id);
1139 break;
1140 }
1141
1142 case Token::NULL_LITERAL:
1143 case Token::TRUE_LITERAL:
1144 case Token::FALSE_LITERAL:
1145 case Token::NUMBER: {
1146 Next();
1147 break;
1148 }
1149 case Token::STRING: {
1150 Next();
1151 result = GetStringSymbol();
1152 break;
1153 }
1154
1155 case Token::ASSIGN_DIV:
1156 result = ParseRegExpLiteral(true, CHECK_OK);
1157 break;
1158
1159 case Token::DIV:
1160 result = ParseRegExpLiteral(false, CHECK_OK);
1161 break;
1162
1163 case Token::LBRACK:
1164 result = ParseArrayLiteral(CHECK_OK);
1165 break;
1166
1167 case Token::LBRACE:
1168 result = ParseObjectLiteral(CHECK_OK);
1169 break;
1170
1171 case Token::LPAREN:
1172 Consume(Token::LPAREN);
1173 parenthesized_function_ = (peek() == Token::FUNCTION);
1174 result = ParseExpression(true, CHECK_OK);
1175 Expect(Token::RPAREN, CHECK_OK);
1176 result = result.Parenthesize();
1177 break;
1178
1179 case Token::MOD:
1180 result = ParseV8Intrinsic(CHECK_OK);
1181 break;
1182
1183 default: {
1184 Next();
1185 *ok = false;
1186 return Expression::Default();
1187 }
1188 }
1189
1190 return result;
1191 }
1192
1193
1194 PreParser::Expression PreParser::ParseArrayLiteral(bool* ok) {
1195 // ArrayLiteral ::
1196 // '[' Expression? (',' Expression?)* ']'
1197 Expect(Token::LBRACK, CHECK_OK);
1198 while (peek() != Token::RBRACK) {
1199 if (peek() != Token::COMMA) {
1200 ParseAssignmentExpression(true, CHECK_OK);
1201 }
1202 if (peek() != Token::RBRACK) {
1203 Expect(Token::COMMA, CHECK_OK);
1204 }
1205 }
1206 Expect(Token::RBRACK, CHECK_OK);
1207
1208 scope_->NextMaterializedLiteralIndex();
1209 return Expression::Default();
1210 }
1211
1212
1213 PreParser::Expression PreParser::ParseObjectLiteral(bool* ok) { 1125 PreParser::Expression PreParser::ParseObjectLiteral(bool* ok) {
1214 // ObjectLiteral :: 1126 // ObjectLiteral ::
1215 // '{' ( 1127 // '{' (
1216 // ((IdentifierName | String | Number) ':' AssignmentExpression) 1128 // ((IdentifierName | String | Number) ':' AssignmentExpression)
1217 // | (('get' | 'set') (IdentifierName | String | Number) FunctionLiteral) 1129 // | (('get' | 'set') (IdentifierName | String | Number) FunctionLiteral)
1218 // )*[','] '}' 1130 // )*[','] '}'
1219 1131
1220 ObjectLiteralChecker checker(this, language_mode()); 1132 ObjectLiteralChecker checker(this, scope_->language_mode());
1221 1133
1222 Expect(Token::LBRACE, CHECK_OK); 1134 Expect(Token::LBRACE, CHECK_OK);
1223 while (peek() != Token::RBRACE) { 1135 while (peek() != Token::RBRACE) {
1224 Token::Value next = peek(); 1136 Token::Value next = peek();
1225 switch (next) { 1137 switch (next) {
1226 case Token::IDENTIFIER: 1138 case Token::IDENTIFIER:
1227 case Token::FUTURE_RESERVED_WORD: 1139 case Token::FUTURE_RESERVED_WORD:
1228 case Token::FUTURE_STRICT_RESERVED_WORD: { 1140 case Token::FUTURE_STRICT_RESERVED_WORD: {
1229 bool is_getter = false; 1141 bool is_getter = false;
1230 bool is_setter = false; 1142 bool is_setter = false;
1231 ParseIdentifierNameOrGetOrSet(&is_getter, &is_setter, CHECK_OK); 1143 ParseIdentifierNameOrGetOrSet(&is_getter, &is_setter, CHECK_OK);
1232 if ((is_getter || is_setter) && peek() != Token::COLON) { 1144 if ((is_getter || is_setter) && peek() != Token::COLON) {
1233 Token::Value name = Next(); 1145 Token::Value name = Next();
1234 bool is_keyword = Token::IsKeyword(name); 1146 bool is_keyword = Token::IsKeyword(name);
1235 if (name != Token::IDENTIFIER && 1147 if (name != Token::IDENTIFIER &&
1236 name != Token::FUTURE_RESERVED_WORD && 1148 name != Token::FUTURE_RESERVED_WORD &&
1237 name != Token::FUTURE_STRICT_RESERVED_WORD && 1149 name != Token::FUTURE_STRICT_RESERVED_WORD &&
1238 name != Token::NUMBER && 1150 name != Token::NUMBER &&
1239 name != Token::STRING && 1151 name != Token::STRING &&
1240 !is_keyword) { 1152 !is_keyword) {
1241 *ok = false; 1153 *ok = false;
1242 return Expression::Default(); 1154 return Expression::Default();
1243 } 1155 }
1244 if (!is_keyword) { 1156 if (!is_keyword) {
1245 LogSymbol(); 1157 LogSymbol();
1246 } 1158 }
1247 PropertyKind type = is_getter ? kGetterProperty : kSetterProperty; 1159 PropertyKind type = is_getter ? kGetterProperty : kSetterProperty;
1248 checker.CheckProperty(name, type, CHECK_OK); 1160 checker.CheckProperty(name, type, CHECK_OK);
1249 ParseFunctionLiteral(false, CHECK_OK); 1161 ParseFunctionLiteral(Identifier::Default(),
1162 scanner()->location(),
1163 false, // reserved words are allowed here
1164 false, // not a generator
1165 CHECK_OK);
1250 if (peek() != Token::RBRACE) { 1166 if (peek() != Token::RBRACE) {
1251 Expect(Token::COMMA, CHECK_OK); 1167 Expect(Token::COMMA, CHECK_OK);
1252 } 1168 }
1253 continue; // restart the while 1169 continue; // restart the while
1254 } 1170 }
1255 checker.CheckProperty(next, kValueProperty, CHECK_OK); 1171 checker.CheckProperty(next, kValueProperty, CHECK_OK);
1256 break; 1172 break;
1257 } 1173 }
1258 case Token::STRING: 1174 case Token::STRING:
1259 Consume(next); 1175 Consume(next);
1260 checker.CheckProperty(next, kValueProperty, CHECK_OK); 1176 checker.CheckProperty(next, kValueProperty, CHECK_OK);
1261 GetStringSymbol(); 1177 LogSymbol();
1262 break; 1178 break;
1263 case Token::NUMBER: 1179 case Token::NUMBER:
1264 Consume(next); 1180 Consume(next);
1265 checker.CheckProperty(next, kValueProperty, CHECK_OK); 1181 checker.CheckProperty(next, kValueProperty, CHECK_OK);
1266 break; 1182 break;
1267 default: 1183 default:
1268 if (Token::IsKeyword(next)) { 1184 if (Token::IsKeyword(next)) {
1269 Consume(next); 1185 Consume(next);
1270 checker.CheckProperty(next, kValueProperty, CHECK_OK); 1186 checker.CheckProperty(next, kValueProperty, CHECK_OK);
1187 LogSymbol();
1271 } else { 1188 } else {
1272 // Unexpected token. 1189 // Unexpected token.
1273 *ok = false; 1190 *ok = false;
1274 return Expression::Default(); 1191 return Expression::Default();
1275 } 1192 }
1276 } 1193 }
1277 1194
1278 Expect(Token::COLON, CHECK_OK); 1195 Expect(Token::COLON, CHECK_OK);
1279 ParseAssignmentExpression(true, CHECK_OK); 1196 ParseAssignmentExpression(true, CHECK_OK);
1280 1197
1281 // TODO(1240767): Consider allowing trailing comma. 1198 // TODO(1240767): Consider allowing trailing comma.
1282 if (peek() != Token::RBRACE) Expect(Token::COMMA, CHECK_OK); 1199 if (peek() != Token::RBRACE) Expect(Token::COMMA, CHECK_OK);
1283 } 1200 }
1284 Expect(Token::RBRACE, CHECK_OK); 1201 Expect(Token::RBRACE, CHECK_OK);
1285 1202
1286 scope_->NextMaterializedLiteralIndex(); 1203 function_state_->NextMaterializedLiteralIndex();
1287 return Expression::Default(); 1204 return Expression::Default();
1288 } 1205 }
1289 1206
1290
1291 PreParser::Expression PreParser::ParseRegExpLiteral(bool seen_equal,
1292 bool* ok) {
1293 if (!scanner()->ScanRegExpPattern(seen_equal)) {
1294 Next();
1295 ReportMessageAt(scanner()->location(), "unterminated_regexp", NULL);
1296 *ok = false;
1297 return Expression::Default();
1298 }
1299
1300 scope_->NextMaterializedLiteralIndex();
1301
1302 if (!scanner()->ScanRegExpFlags()) {
1303 Next();
1304 ReportMessageAt(scanner()->location(), "invalid_regexp_flags", NULL);
1305 *ok = false;
1306 return Expression::Default();
1307 }
1308 Next();
1309 return Expression::Default();
1310 }
1311
1312 1207
1313 PreParser::Arguments PreParser::ParseArguments(bool* ok) { 1208 PreParser::Arguments PreParser::ParseArguments(bool* ok) {
1314 // Arguments :: 1209 // Arguments ::
1315 // '(' (AssignmentExpression)*[','] ')' 1210 // '(' (AssignmentExpression)*[','] ')'
1316 1211
1317 Expect(Token::LPAREN, ok); 1212 Expect(Token::LPAREN, ok);
1318 if (!*ok) return -1; 1213 if (!*ok) return -1;
1319 bool done = (peek() == Token::RPAREN); 1214 bool done = (peek() == Token::RPAREN);
1320 int argc = 0; 1215 int argc = 0;
1321 while (!done) { 1216 while (!done) {
1322 ParseAssignmentExpression(true, ok); 1217 ParseAssignmentExpression(true, ok);
1323 if (!*ok) return -1; 1218 if (!*ok) return -1;
1324 argc++; 1219 argc++;
1325 done = (peek() == Token::RPAREN); 1220 done = (peek() == Token::RPAREN);
1326 if (!done) { 1221 if (!done) {
1327 Expect(Token::COMMA, ok); 1222 Expect(Token::COMMA, ok);
1328 if (!*ok) return -1; 1223 if (!*ok) return -1;
1329 } 1224 }
1330 } 1225 }
1331 Expect(Token::RPAREN, ok); 1226 Expect(Token::RPAREN, ok);
1332 return argc; 1227 return argc;
1333 } 1228 }
1334 1229
1335 1230 PreParser::Expression PreParser::ParseFunctionLiteral(
1336 PreParser::Expression PreParser::ParseFunctionLiteral(bool is_generator, 1231 Identifier function_name,
1337 bool* ok) { 1232 Scanner::Location function_name_location,
1233 bool name_is_strict_reserved,
1234 bool is_generator,
1235 bool* ok) {
1338 // Function :: 1236 // Function ::
1339 // '(' FormalParameterList? ')' '{' FunctionBody '}' 1237 // '(' FormalParameterList? ')' '{' FunctionBody '}'
1340 1238
1341 // Parse function body. 1239 // Parse function body.
1342 ScopeType outer_scope_type = scope_->type(); 1240 ScopeType outer_scope_type = scope_->type();
1343 bool inside_with = scope_->IsInsideWith(); 1241 bool inside_with = scope_->inside_with();
1344 Scope function_scope(&scope_, kFunctionScope); 1242 PreParserScope function_scope(scope_, FUNCTION_SCOPE);
1345 function_scope.set_is_generator(is_generator); 1243 FunctionState function_state(&function_state_, &scope_, &function_scope);
1244 function_state.set_is_generator(is_generator);
1346 // FormalParameterList :: 1245 // FormalParameterList ::
1347 // '(' (Identifier)*[','] ')' 1246 // '(' (Identifier)*[','] ')'
1348 Expect(Token::LPAREN, CHECK_OK); 1247 Expect(Token::LPAREN, CHECK_OK);
1349 int start_position = position(); 1248 int start_position = position();
1350 bool done = (peek() == Token::RPAREN); 1249 bool done = (peek() == Token::RPAREN);
1351 DuplicateFinder duplicate_finder(scanner()->unicode_cache()); 1250 DuplicateFinder duplicate_finder(scanner()->unicode_cache());
1251 // We don't yet know if the function will be strict, so we cannot yet produce
1252 // errors for parameter names or duplicates. However, we remember the
1253 // locations of these errors if they occur and produce the errors later.
1254 Scanner::Location eval_args_error_loc = Scanner::Location::invalid();
1255 Scanner::Location dupe_error_loc = Scanner::Location::invalid();
1256 Scanner::Location reserved_error_loc = Scanner::Location::invalid();
1352 while (!done) { 1257 while (!done) {
1353 Identifier id = ParseIdentifier(CHECK_OK); 1258 bool is_strict_reserved = false;
1354 if (!id.IsValidStrictVariable()) { 1259 Identifier param_name =
1355 StrictModeIdentifierViolation(scanner()->location(), 1260 ParseIdentifierOrStrictReservedWord(&is_strict_reserved, CHECK_OK);
1356 "strict_param_name", 1261 if (!eval_args_error_loc.IsValid() && param_name.IsEvalOrArguments()) {
1357 id, 1262 eval_args_error_loc = scanner()->location();
1358 CHECK_OK);
1359 } 1263 }
1264 if (!reserved_error_loc.IsValid() && is_strict_reserved) {
1265 reserved_error_loc = scanner()->location();
1266 }
1267
1360 int prev_value; 1268 int prev_value;
1361 if (scanner()->is_literal_ascii()) { 1269 if (scanner()->is_literal_ascii()) {
1362 prev_value = 1270 prev_value =
1363 duplicate_finder.AddAsciiSymbol(scanner()->literal_ascii_string(), 1); 1271 duplicate_finder.AddAsciiSymbol(scanner()->literal_ascii_string(), 1);
1364 } else { 1272 } else {
1365 prev_value = 1273 prev_value =
1366 duplicate_finder.AddUtf16Symbol(scanner()->literal_utf16_string(), 1); 1274 duplicate_finder.AddUtf16Symbol(scanner()->literal_utf16_string(), 1);
1367 } 1275 }
1368 1276
1369 if (prev_value != 0) { 1277 if (!dupe_error_loc.IsValid() && prev_value != 0) {
1370 SetStrictModeViolation(scanner()->location(), 1278 dupe_error_loc = scanner()->location();
1371 "strict_param_dupe",
1372 CHECK_OK);
1373 } 1279 }
1280
1374 done = (peek() == Token::RPAREN); 1281 done = (peek() == Token::RPAREN);
1375 if (!done) { 1282 if (!done) {
1376 Expect(Token::COMMA, CHECK_OK); 1283 Expect(Token::COMMA, CHECK_OK);
1377 } 1284 }
1378 } 1285 }
1379 Expect(Token::RPAREN, CHECK_OK); 1286 Expect(Token::RPAREN, CHECK_OK);
1380 1287
1381 // Determine if the function will be lazily compiled. 1288 // See Parser::ParseFunctionLiteral for more information about lazy parsing
1382 // Currently only happens to top-level functions. 1289 // and lazy compilation.
1383 // Optimistically assume that all top-level functions are lazily compiled. 1290 bool is_lazily_parsed = (outer_scope_type == GLOBAL_SCOPE &&
1384 bool is_lazily_compiled = (outer_scope_type == kTopLevelScope && 1291 !inside_with && allow_lazy() &&
1385 !inside_with && allow_lazy() && 1292 !parenthesized_function_);
1386 !parenthesized_function_);
1387 parenthesized_function_ = false; 1293 parenthesized_function_ = false;
1388 1294
1389 Expect(Token::LBRACE, CHECK_OK); 1295 Expect(Token::LBRACE, CHECK_OK);
1390 if (is_lazily_compiled) { 1296 if (is_lazily_parsed) {
1391 ParseLazyFunctionLiteralBody(CHECK_OK); 1297 ParseLazyFunctionLiteralBody(CHECK_OK);
1392 } else { 1298 } else {
1393 ParseSourceElements(Token::RBRACE, ok); 1299 ParseSourceElements(Token::RBRACE, ok);
1394 } 1300 }
1395 Expect(Token::RBRACE, CHECK_OK); 1301 Expect(Token::RBRACE, CHECK_OK);
1396 1302
1397 if (!is_classic_mode()) { 1303 // Validate strict mode. We can do this only after parsing the function,
1304 // since the function can declare itself strict.
1305 if (!scope_->is_classic_mode()) {
1306 if (function_name.IsEvalOrArguments()) {
1307 ReportMessageAt(function_name_location, "strict_eval_arguments");
1308 *ok = false;
1309 return Expression::Default();
1310 }
1311 if (name_is_strict_reserved) {
1312 ReportMessageAt(function_name_location, "unexpected_strict_reserved");
1313 *ok = false;
1314 return Expression::Default();
1315 }
1316 if (eval_args_error_loc.IsValid()) {
1317 ReportMessageAt(eval_args_error_loc, "strict_eval_arguments");
1318 *ok = false;
1319 return Expression::Default();
1320 }
1321 if (dupe_error_loc.IsValid()) {
1322 ReportMessageAt(dupe_error_loc, "strict_param_dupe");
1323 *ok = false;
1324 return Expression::Default();
1325 }
1326 if (reserved_error_loc.IsValid()) {
1327 ReportMessageAt(reserved_error_loc, "unexpected_strict_reserved");
1328 *ok = false;
1329 return Expression::Default();
1330 }
1331
1398 int end_position = scanner()->location().end_pos; 1332 int end_position = scanner()->location().end_pos;
1399 CheckOctalLiteral(start_position, end_position, CHECK_OK); 1333 CheckOctalLiteral(start_position, end_position, CHECK_OK);
1400 CheckDelayedStrictModeViolation(start_position, end_position, CHECK_OK);
1401 return Expression::StrictFunction(); 1334 return Expression::StrictFunction();
1402 } 1335 }
1403 1336
1404 return Expression::Default(); 1337 return Expression::Default();
1405 } 1338 }
1406 1339
1407 1340
1408 void PreParser::ParseLazyFunctionLiteralBody(bool* ok) { 1341 void PreParser::ParseLazyFunctionLiteralBody(bool* ok) {
1409 int body_start = position(); 1342 int body_start = position();
1410 log_->PauseRecording(); 1343 log_->PauseRecording();
1411 ParseSourceElements(Token::RBRACE, ok); 1344 ParseSourceElements(Token::RBRACE, ok);
1412 log_->ResumeRecording(); 1345 log_->ResumeRecording();
1413 if (!*ok) return; 1346 if (!*ok) return;
1414 1347
1415 // Position right after terminal '}'. 1348 // Position right after terminal '}'.
1416 ASSERT_EQ(Token::RBRACE, scanner()->peek()); 1349 ASSERT_EQ(Token::RBRACE, scanner()->peek());
1417 int body_end = scanner()->peek_location().end_pos; 1350 int body_end = scanner()->peek_location().end_pos;
1418 log_->LogFunction(body_start, body_end, 1351 log_->LogFunction(body_start, body_end,
1419 scope_->materialized_literal_count(), 1352 function_state_->materialized_literal_count(),
1420 scope_->expected_properties(), 1353 function_state_->expected_property_count(),
1421 language_mode()); 1354 scope_->language_mode());
1422 } 1355 }
1423 1356
1424 1357
1425 PreParser::Expression PreParser::ParseV8Intrinsic(bool* ok) { 1358 PreParser::Expression PreParser::ParseV8Intrinsic(bool* ok) {
1426 // CallRuntime :: 1359 // CallRuntime ::
1427 // '%' Identifier Arguments 1360 // '%' Identifier Arguments
1428 Expect(Token::MOD, CHECK_OK); 1361 Expect(Token::MOD, CHECK_OK);
1429 if (!allow_natives_syntax()) { 1362 if (!allow_natives_syntax()) {
1430 *ok = false; 1363 *ok = false;
1431 return Expression::Default(); 1364 return Expression::Default();
1432 } 1365 }
1433 ParseIdentifier(CHECK_OK); 1366 // Allow "eval" or "arguments" for backward compatibility.
1367 ParseIdentifier(kAllowEvalOrArguments, CHECK_OK);
1434 ParseArguments(ok); 1368 ParseArguments(ok);
1435 1369
1436 return Expression::Default(); 1370 return Expression::Default();
1437 } 1371 }
1438 1372
1439 #undef CHECK_OK 1373 #undef CHECK_OK
1440 1374
1441 1375
1442 void PreParser::LogSymbol() { 1376 void PreParser::LogSymbol() {
1443 int identifier_pos = position(); 1377 int identifier_pos = position();
1444 if (scanner()->is_literal_ascii()) { 1378 if (scanner()->is_literal_ascii()) {
1445 log_->LogAsciiSymbol(identifier_pos, scanner()->literal_ascii_string()); 1379 log_->LogAsciiSymbol(identifier_pos, scanner()->literal_ascii_string());
1446 } else { 1380 } else {
1447 log_->LogUtf16Symbol(identifier_pos, scanner()->literal_utf16_string()); 1381 log_->LogUtf16Symbol(identifier_pos, scanner()->literal_utf16_string());
1448 } 1382 }
1449 } 1383 }
1450 1384
1451 1385
1452 PreParser::Expression PreParser::GetStringSymbol() {
1453 const int kUseStrictLength = 10;
1454 const char* kUseStrictChars = "use strict";
1455 LogSymbol();
1456 if (scanner()->is_literal_ascii() &&
1457 scanner()->literal_length() == kUseStrictLength &&
1458 !scanner()->literal_contains_escapes() &&
1459 !strncmp(scanner()->literal_ascii_string().start(), kUseStrictChars,
1460 kUseStrictLength)) {
1461 return Expression::UseStrictStringLiteral();
1462 }
1463 return Expression::StringLiteral();
1464 }
1465
1466
1467 PreParser::Identifier PreParser::GetIdentifierSymbol() {
1468 LogSymbol();
1469 if (scanner()->current_token() == Token::FUTURE_RESERVED_WORD) {
1470 return Identifier::FutureReserved();
1471 } else if (scanner()->current_token() ==
1472 Token::FUTURE_STRICT_RESERVED_WORD) {
1473 return Identifier::FutureStrictReserved();
1474 } else if (scanner()->current_token() == Token::YIELD) {
1475 return Identifier::Yield();
1476 }
1477 if (scanner()->is_literal_ascii()) {
1478 // Detect strict-mode poison words.
1479 if (scanner()->literal_length() == 4 &&
1480 !strncmp(scanner()->literal_ascii_string().start(), "eval", 4)) {
1481 return Identifier::Eval();
1482 }
1483 if (scanner()->literal_length() == 9 &&
1484 !strncmp(scanner()->literal_ascii_string().start(), "arguments", 9)) {
1485 return Identifier::Arguments();
1486 }
1487 }
1488 return Identifier::Default();
1489 }
1490
1491
1492 PreParser::Identifier PreParser::ParseIdentifier(bool* ok) {
1493 Token::Value next = Next();
1494 switch (next) {
1495 case Token::FUTURE_RESERVED_WORD: {
1496 ScannerBase::Location location = scanner()->location();
1497 ReportMessageAt(location.beg_pos, location.end_pos,
1498 "reserved_word", NULL);
1499 *ok = false;
1500 return GetIdentifierSymbol();
1501 }
1502 case Token::YIELD:
1503 if (scope_->is_generator()) {
1504 // 'yield' in a generator is only valid as part of a YieldExpression.
1505 ReportMessageAt(scanner()->location(), "unexpected_token", "yield");
1506 *ok = false;
1507 return Identifier::Yield();
1508 }
1509 // FALLTHROUGH
1510 case Token::FUTURE_STRICT_RESERVED_WORD:
1511 if (!is_classic_mode()) {
1512 ScannerBase::Location location = scanner()->location();
1513 ReportMessageAt(location.beg_pos, location.end_pos,
1514 "strict_reserved_word", NULL);
1515 *ok = false;
1516 }
1517 // FALLTHROUGH
1518 case Token::IDENTIFIER:
1519 return GetIdentifierSymbol();
1520 default:
1521 *ok = false;
1522 return Identifier::Default();
1523 }
1524 }
1525
1526
1527 void PreParser::SetStrictModeViolation(ScannerBase::Location location,
1528 const char* type,
1529 bool* ok) {
1530 if (!is_classic_mode()) {
1531 ReportMessageAt(location, type, NULL);
1532 *ok = false;
1533 return;
1534 }
1535 // Delay report in case this later turns out to be strict code
1536 // (i.e., for function names and parameters prior to a "use strict"
1537 // directive).
1538 // It's safe to overwrite an existing violation.
1539 // It's either from a function that turned out to be non-strict,
1540 // or it's in the current function (and we just need to report
1541 // one error), or it's in a unclosed nesting function that wasn't
1542 // strict (otherwise we would already be in strict mode).
1543 strict_mode_violation_location_ = location;
1544 strict_mode_violation_type_ = type;
1545 }
1546
1547
1548 void PreParser::CheckDelayedStrictModeViolation(int beg_pos,
1549 int end_pos,
1550 bool* ok) {
1551 ScannerBase::Location location = strict_mode_violation_location_;
1552 if (location.IsValid() &&
1553 location.beg_pos > beg_pos && location.end_pos < end_pos) {
1554 ReportMessageAt(location, strict_mode_violation_type_, NULL);
1555 *ok = false;
1556 }
1557 }
1558
1559
1560 void PreParser::StrictModeIdentifierViolation(ScannerBase::Location location,
1561 const char* eval_args_type,
1562 Identifier identifier,
1563 bool* ok) {
1564 const char* type = eval_args_type;
1565 if (identifier.IsFutureReserved()) {
1566 type = "reserved_word";
1567 } else if (identifier.IsFutureStrictReserved() || identifier.IsYield()) {
1568 type = "strict_reserved_word";
1569 }
1570 if (!is_classic_mode()) {
1571 ReportMessageAt(location, type, NULL);
1572 *ok = false;
1573 return;
1574 }
1575 strict_mode_violation_location_ = location;
1576 strict_mode_violation_type_ = type;
1577 }
1578
1579
1580 PreParser::Identifier PreParser::ParseIdentifierName(bool* ok) {
1581 Token::Value next = Next();
1582 if (Token::IsKeyword(next)) {
1583 int pos = position();
1584 const char* keyword = Token::String(next);
1585 log_->LogAsciiSymbol(pos, Vector<const char>(keyword, StrLength(keyword)));
1586 return Identifier::Default();
1587 }
1588 if (next == Token::IDENTIFIER ||
1589 next == Token::FUTURE_RESERVED_WORD ||
1590 next == Token::FUTURE_STRICT_RESERVED_WORD) {
1591 return GetIdentifierSymbol();
1592 }
1593 *ok = false;
1594 return Identifier::Default();
1595 }
1596
1597 #undef CHECK_OK
1598
1599
1600 // This function reads an identifier and determines whether or not it
1601 // is 'get' or 'set'.
1602 PreParser::Identifier PreParser::ParseIdentifierNameOrGetOrSet(bool* is_get,
1603 bool* is_set,
1604 bool* ok) {
1605 Identifier result = ParseIdentifierName(ok);
1606 if (!*ok) return Identifier::Default();
1607 if (scanner()->is_literal_ascii() &&
1608 scanner()->literal_length() == 3) {
1609 const char* token = scanner()->literal_ascii_string().start();
1610 *is_get = strncmp(token, "get", 3) == 0;
1611 *is_set = !*is_get && strncmp(token, "set", 3) == 0;
1612 }
1613 return result;
1614 }
1615
1616
1617 void PreParser::ObjectLiteralChecker::CheckProperty(Token::Value property,
1618 PropertyKind type,
1619 bool* ok) {
1620 int old;
1621 if (property == Token::NUMBER) {
1622 old = finder_.AddNumber(scanner()->literal_ascii_string(), type);
1623 } else if (scanner()->is_literal_ascii()) {
1624 old = finder_.AddAsciiSymbol(scanner()->literal_ascii_string(), type);
1625 } else {
1626 old = finder_.AddUtf16Symbol(scanner()->literal_utf16_string(), type);
1627 }
1628 PropertyKind old_type = static_cast<PropertyKind>(old);
1629 if (HasConflict(old_type, type)) {
1630 if (IsDataDataConflict(old_type, type)) {
1631 // Both are data properties.
1632 if (language_mode_ == CLASSIC_MODE) return;
1633 parser()->ReportMessageAt(scanner()->location(),
1634 "strict_duplicate_property");
1635 } else if (IsDataAccessorConflict(old_type, type)) {
1636 // Both a data and an accessor property with the same name.
1637 parser()->ReportMessageAt(scanner()->location(),
1638 "accessor_data_property");
1639 } else {
1640 ASSERT(IsAccessorAccessorConflict(old_type, type));
1641 // Both accessors of the same type.
1642 parser()->ReportMessageAt(scanner()->location(),
1643 "accessor_get_set");
1644 }
1645 *ok = false;
1646 }
1647 }
1648
1649 } } // v8::internal 1386 } } // v8::internal
OLDNEW
« no previous file with comments | « src/preparser.h ('k') | src/prettyprinter.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698