OLD | NEW |
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 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
56 namespace internal { | 56 namespace internal { |
57 | 57 |
58 PreParser::PreParseResult PreParser::PreParseLazyFunction( | 58 PreParser::PreParseResult PreParser::PreParseLazyFunction( |
59 i::LanguageMode mode, bool is_generator, i::ParserRecorder* log) { | 59 i::LanguageMode mode, bool is_generator, i::ParserRecorder* log) { |
60 log_ = log; | 60 log_ = log; |
61 // Lazy functions always have trivial outer scopes (no with/catch scopes). | 61 // Lazy functions always have trivial outer scopes (no with/catch scopes). |
62 Scope top_scope(&scope_, kTopLevelScope); | 62 Scope top_scope(&scope_, kTopLevelScope); |
63 set_language_mode(mode); | 63 set_language_mode(mode); |
64 Scope function_scope(&scope_, kFunctionScope); | 64 Scope function_scope(&scope_, kFunctionScope); |
65 function_scope.set_is_generator(is_generator); | 65 function_scope.set_is_generator(is_generator); |
66 ASSERT_EQ(i::Token::LBRACE, scanner_->current_token()); | 66 ASSERT_EQ(i::Token::LBRACE, scanner()->current_token()); |
67 bool ok = true; | 67 bool ok = true; |
68 int start_position = scanner_->peek_location().beg_pos; | 68 int start_position = scanner()->peek_location().beg_pos; |
69 ParseLazyFunctionLiteralBody(&ok); | 69 ParseLazyFunctionLiteralBody(&ok); |
70 if (stack_overflow_) return kPreParseStackOverflow; | 70 if (stack_overflow()) return kPreParseStackOverflow; |
71 if (!ok) { | 71 if (!ok) { |
72 ReportUnexpectedToken(scanner_->current_token()); | 72 ReportUnexpectedToken(scanner()->current_token()); |
73 } else { | 73 } else { |
74 ASSERT_EQ(i::Token::RBRACE, scanner_->peek()); | 74 ASSERT_EQ(i::Token::RBRACE, scanner()->peek()); |
75 if (!is_classic_mode()) { | 75 if (!is_classic_mode()) { |
76 int end_pos = scanner_->location().end_pos; | 76 int end_pos = scanner()->location().end_pos; |
77 CheckOctalLiteral(start_position, end_pos, &ok); | 77 CheckOctalLiteral(start_position, end_pos, &ok); |
78 if (ok) { | 78 if (ok) { |
79 CheckDelayedStrictModeViolation(start_position, end_pos, &ok); | 79 CheckDelayedStrictModeViolation(start_position, end_pos, &ok); |
80 } | 80 } |
81 } | 81 } |
82 } | 82 } |
83 return kPreParseSuccess; | 83 return kPreParseSuccess; |
84 } | 84 } |
85 | 85 |
86 | 86 |
87 // Preparsing checks a JavaScript program and emits preparse-data that helps | 87 // Preparsing checks a JavaScript program and emits preparse-data that helps |
88 // a later parsing to be faster. | 88 // a later parsing to be faster. |
89 // See preparser-data.h for the data. | 89 // See preparser-data.h for the data. |
90 | 90 |
91 // The PreParser checks that the syntax follows the grammar for JavaScript, | 91 // The PreParser checks that the syntax follows the grammar for JavaScript, |
92 // and collects some information about the program along the way. | 92 // and collects some information about the program along the way. |
93 // The grammar check is only performed in order to understand the program | 93 // The grammar check is only performed in order to understand the program |
94 // sufficiently to deduce some information about it, that can be used | 94 // 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, | 95 // 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. | 96 // rather it is to speed up properly written and correct programs. |
97 // That means that contextual checks (like a label being declared where | 97 // That means that contextual checks (like a label being declared where |
98 // it is used) are generally omitted. | 98 // it is used) are generally omitted. |
99 | 99 |
100 void PreParser::ReportUnexpectedToken(i::Token::Value token) { | 100 void PreParser::ReportUnexpectedToken(i::Token::Value token) { |
101 // We don't report stack overflows here, to avoid increasing the | 101 // We don't report stack overflows here, to avoid increasing the |
102 // stack depth even further. Instead we report it after parsing is | 102 // stack depth even further. Instead we report it after parsing is |
103 // over, in ParseProgram. | 103 // over, in ParseProgram. |
104 if (token == i::Token::ILLEGAL && stack_overflow_) { | 104 if (token == i::Token::ILLEGAL && stack_overflow()) { |
105 return; | 105 return; |
106 } | 106 } |
107 i::Scanner::Location source_location = scanner_->location(); | 107 i::Scanner::Location source_location = scanner()->location(); |
108 | 108 |
109 // Four of the tokens are treated specially | 109 // Four of the tokens are treated specially |
110 switch (token) { | 110 switch (token) { |
111 case i::Token::EOS: | 111 case i::Token::EOS: |
112 return ReportMessageAt(source_location, "unexpected_eos", NULL); | 112 return ReportMessageAt(source_location, "unexpected_eos", NULL); |
113 case i::Token::NUMBER: | 113 case i::Token::NUMBER: |
114 return ReportMessageAt(source_location, "unexpected_token_number", NULL); | 114 return ReportMessageAt(source_location, "unexpected_token_number", NULL); |
115 case i::Token::STRING: | 115 case i::Token::STRING: |
116 return ReportMessageAt(source_location, "unexpected_token_string", NULL); | 116 return ReportMessageAt(source_location, "unexpected_token_string", NULL); |
117 case i::Token::IDENTIFIER: | 117 case i::Token::IDENTIFIER: |
118 return ReportMessageAt(source_location, | 118 return ReportMessageAt(source_location, |
119 "unexpected_token_identifier", NULL); | 119 "unexpected_token_identifier", NULL); |
120 case i::Token::FUTURE_RESERVED_WORD: | 120 case i::Token::FUTURE_RESERVED_WORD: |
121 return ReportMessageAt(source_location, "unexpected_reserved", NULL); | 121 return ReportMessageAt(source_location, "unexpected_reserved", NULL); |
122 case i::Token::FUTURE_STRICT_RESERVED_WORD: | 122 case i::Token::FUTURE_STRICT_RESERVED_WORD: |
123 return ReportMessageAt(source_location, | 123 return ReportMessageAt(source_location, |
124 "unexpected_strict_reserved", NULL); | 124 "unexpected_strict_reserved", NULL); |
125 default: | 125 default: |
126 const char* name = i::Token::String(token); | 126 const char* name = i::Token::String(token); |
127 ReportMessageAt(source_location, "unexpected_token", name); | 127 ReportMessageAt(source_location, "unexpected_token", name); |
128 } | 128 } |
129 } | 129 } |
130 | 130 |
131 | 131 |
132 // Checks whether octal literal last seen is between beg_pos and end_pos. | 132 // Checks whether octal literal last seen is between beg_pos and end_pos. |
133 // If so, reports an error. | 133 // If so, reports an error. |
134 void PreParser::CheckOctalLiteral(int beg_pos, int end_pos, bool* ok) { | 134 void PreParser::CheckOctalLiteral(int beg_pos, int end_pos, bool* ok) { |
135 i::Scanner::Location octal = scanner_->octal_position(); | 135 i::Scanner::Location octal = scanner()->octal_position(); |
136 if (beg_pos <= octal.beg_pos && octal.end_pos <= end_pos) { | 136 if (beg_pos <= octal.beg_pos && octal.end_pos <= end_pos) { |
137 ReportMessageAt(octal, "strict_octal_literal", NULL); | 137 ReportMessageAt(octal, "strict_octal_literal", NULL); |
138 scanner_->clear_octal_position(); | 138 scanner()->clear_octal_position(); |
139 *ok = false; | 139 *ok = false; |
140 } | 140 } |
141 } | 141 } |
142 | 142 |
143 | 143 |
144 #define CHECK_OK ok); \ | 144 #define CHECK_OK ok); \ |
145 if (!*ok) return kUnknownSourceElements; \ | 145 if (!*ok) return kUnknownSourceElements; \ |
146 ((void)0 | 146 ((void)0 |
147 #define DUMMY ) // to make indentation work | 147 #define DUMMY ) // to make indentation work |
148 #undef DUMMY | 148 #undef DUMMY |
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
267 case i::Token::SWITCH: | 267 case i::Token::SWITCH: |
268 return ParseSwitchStatement(ok); | 268 return ParseSwitchStatement(ok); |
269 | 269 |
270 case i::Token::THROW: | 270 case i::Token::THROW: |
271 return ParseThrowStatement(ok); | 271 return ParseThrowStatement(ok); |
272 | 272 |
273 case i::Token::TRY: | 273 case i::Token::TRY: |
274 return ParseTryStatement(ok); | 274 return ParseTryStatement(ok); |
275 | 275 |
276 case i::Token::FUNCTION: { | 276 case i::Token::FUNCTION: { |
277 i::Scanner::Location start_location = scanner_->peek_location(); | 277 i::Scanner::Location start_location = scanner()->peek_location(); |
278 Statement statement = ParseFunctionDeclaration(CHECK_OK); | 278 Statement statement = ParseFunctionDeclaration(CHECK_OK); |
279 i::Scanner::Location end_location = scanner_->location(); | 279 i::Scanner::Location end_location = scanner()->location(); |
280 if (!is_classic_mode()) { | 280 if (!is_classic_mode()) { |
281 ReportMessageAt(start_location.beg_pos, end_location.end_pos, | 281 ReportMessageAt(start_location.beg_pos, end_location.end_pos, |
282 "strict_function", NULL); | 282 "strict_function", NULL); |
283 *ok = false; | 283 *ok = false; |
284 return Statement::Default(); | 284 return Statement::Default(); |
285 } else { | 285 } else { |
286 return statement; | 286 return statement; |
287 } | 287 } |
288 } | 288 } |
289 | 289 |
290 case i::Token::DEBUGGER: | 290 case i::Token::DEBUGGER: |
291 return ParseDebuggerStatement(ok); | 291 return ParseDebuggerStatement(ok); |
292 | 292 |
293 default: | 293 default: |
294 return ParseExpressionOrLabelledStatement(ok); | 294 return ParseExpressionOrLabelledStatement(ok); |
295 } | 295 } |
296 } | 296 } |
297 | 297 |
298 | 298 |
299 PreParser::Statement PreParser::ParseFunctionDeclaration(bool* ok) { | 299 PreParser::Statement PreParser::ParseFunctionDeclaration(bool* ok) { |
300 // FunctionDeclaration :: | 300 // FunctionDeclaration :: |
301 // 'function' Identifier '(' FormalParameterListopt ')' '{' FunctionBody '}' | 301 // 'function' Identifier '(' FormalParameterListopt ')' '{' FunctionBody '}' |
302 // GeneratorDeclaration :: | 302 // GeneratorDeclaration :: |
303 // 'function' '*' Identifier '(' FormalParameterListopt ')' | 303 // 'function' '*' Identifier '(' FormalParameterListopt ')' |
304 // '{' FunctionBody '}' | 304 // '{' FunctionBody '}' |
305 Expect(i::Token::FUNCTION, CHECK_OK); | 305 Expect(i::Token::FUNCTION, CHECK_OK); |
306 | 306 |
307 bool is_generator = allow_generators_ && Check(i::Token::MUL); | 307 bool is_generator = allow_generators() && Check(i::Token::MUL); |
308 Identifier identifier = ParseIdentifier(CHECK_OK); | 308 Identifier identifier = ParseIdentifier(CHECK_OK); |
309 i::Scanner::Location location = scanner_->location(); | 309 i::Scanner::Location location = scanner()->location(); |
310 | 310 |
311 Expression function_value = ParseFunctionLiteral(is_generator, CHECK_OK); | 311 Expression function_value = ParseFunctionLiteral(is_generator, CHECK_OK); |
312 | 312 |
313 if (function_value.IsStrictFunction() && | 313 if (function_value.IsStrictFunction() && |
314 !identifier.IsValidStrictVariable()) { | 314 !identifier.IsValidStrictVariable()) { |
315 // Strict mode violation, using either reserved word or eval/arguments | 315 // Strict mode violation, using either reserved word or eval/arguments |
316 // as name of strict function. | 316 // as name of strict function. |
317 const char* type = "strict_function_name"; | 317 const char* type = "strict_function_name"; |
318 if (identifier.IsFutureStrictReserved() || identifier.IsYield()) { | 318 if (identifier.IsFutureStrictReserved() || identifier.IsYield()) { |
319 type = "strict_reserved_word"; | 319 type = "strict_reserved_word"; |
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
395 // contained in extended code. | 395 // contained in extended code. |
396 // | 396 // |
397 // However disallowing const in classic mode will break compatibility with | 397 // However disallowing const in classic mode will break compatibility with |
398 // existing pages. Therefore we keep allowing const with the old | 398 // existing pages. Therefore we keep allowing const with the old |
399 // non-harmony semantics in classic mode. | 399 // non-harmony semantics in classic mode. |
400 Consume(i::Token::CONST); | 400 Consume(i::Token::CONST); |
401 switch (language_mode()) { | 401 switch (language_mode()) { |
402 case i::CLASSIC_MODE: | 402 case i::CLASSIC_MODE: |
403 break; | 403 break; |
404 case i::STRICT_MODE: { | 404 case i::STRICT_MODE: { |
405 i::Scanner::Location location = scanner_->peek_location(); | 405 i::Scanner::Location location = scanner()->peek_location(); |
406 ReportMessageAt(location, "strict_const", NULL); | 406 ReportMessageAt(location, "strict_const", NULL); |
407 *ok = false; | 407 *ok = false; |
408 return Statement::Default(); | 408 return Statement::Default(); |
409 } | 409 } |
410 case i::EXTENDED_MODE: | 410 case i::EXTENDED_MODE: |
411 if (var_context != kSourceElement && | 411 if (var_context != kSourceElement && |
412 var_context != kForStatement) { | 412 var_context != kForStatement) { |
413 i::Scanner::Location location = scanner_->peek_location(); | 413 i::Scanner::Location location = scanner()->peek_location(); |
414 ReportMessageAt(location.beg_pos, location.end_pos, | 414 ReportMessageAt(location.beg_pos, location.end_pos, |
415 "unprotected_const", NULL); | 415 "unprotected_const", NULL); |
416 *ok = false; | 416 *ok = false; |
417 return Statement::Default(); | 417 return Statement::Default(); |
418 } | 418 } |
419 require_initializer = true; | 419 require_initializer = true; |
420 break; | 420 break; |
421 } | 421 } |
422 } else if (peek() == i::Token::LET) { | 422 } else if (peek() == i::Token::LET) { |
423 // ES6 Draft Rev4 section 12.2.1: | 423 // ES6 Draft Rev4 section 12.2.1: |
424 // | 424 // |
425 // LetDeclaration : let LetBindingList ; | 425 // LetDeclaration : let LetBindingList ; |
426 // | 426 // |
427 // * It is a Syntax Error if the code that matches this production is not | 427 // * It is a Syntax Error if the code that matches this production is not |
428 // contained in extended code. | 428 // contained in extended code. |
429 if (!is_extended_mode()) { | 429 if (!is_extended_mode()) { |
430 i::Scanner::Location location = scanner_->peek_location(); | 430 i::Scanner::Location location = scanner()->peek_location(); |
431 ReportMessageAt(location.beg_pos, location.end_pos, | 431 ReportMessageAt(location.beg_pos, location.end_pos, |
432 "illegal_let", NULL); | 432 "illegal_let", NULL); |
433 *ok = false; | 433 *ok = false; |
434 return Statement::Default(); | 434 return Statement::Default(); |
435 } | 435 } |
436 Consume(i::Token::LET); | 436 Consume(i::Token::LET); |
437 if (var_context != kSourceElement && | 437 if (var_context != kSourceElement && |
438 var_context != kForStatement) { | 438 var_context != kForStatement) { |
439 i::Scanner::Location location = scanner_->peek_location(); | 439 i::Scanner::Location location = scanner()->peek_location(); |
440 ReportMessageAt(location.beg_pos, location.end_pos, | 440 ReportMessageAt(location.beg_pos, location.end_pos, |
441 "unprotected_let", NULL); | 441 "unprotected_let", NULL); |
442 *ok = false; | 442 *ok = false; |
443 return Statement::Default(); | 443 return Statement::Default(); |
444 } | 444 } |
445 } else { | 445 } else { |
446 *ok = false; | 446 *ok = false; |
447 return Statement::Default(); | 447 return Statement::Default(); |
448 } | 448 } |
449 | 449 |
450 // The scope of a var/const declared variable anywhere inside a function | 450 // The scope of a var/const declared variable anywhere inside a function |
451 // is the entire function (ECMA-262, 3rd, 10.1.3, and 12.2). The scope | 451 // is the entire function (ECMA-262, 3rd, 10.1.3, and 12.2). The scope |
452 // of a let declared variable is the scope of the immediately enclosing | 452 // of a let declared variable is the scope of the immediately enclosing |
453 // block. | 453 // block. |
454 int nvars = 0; // the number of variables declared | 454 int nvars = 0; // the number of variables declared |
455 do { | 455 do { |
456 // Parse variable name. | 456 // Parse variable name. |
457 if (nvars > 0) Consume(i::Token::COMMA); | 457 if (nvars > 0) Consume(i::Token::COMMA); |
458 Identifier identifier = ParseIdentifier(CHECK_OK); | 458 Identifier identifier = ParseIdentifier(CHECK_OK); |
459 if (!is_classic_mode() && !identifier.IsValidStrictVariable()) { | 459 if (!is_classic_mode() && !identifier.IsValidStrictVariable()) { |
460 StrictModeIdentifierViolation(scanner_->location(), | 460 StrictModeIdentifierViolation(scanner()->location(), |
461 "strict_var_name", | 461 "strict_var_name", |
462 identifier, | 462 identifier, |
463 ok); | 463 ok); |
464 return Statement::Default(); | 464 return Statement::Default(); |
465 } | 465 } |
466 nvars++; | 466 nvars++; |
467 if (peek() == i::Token::ASSIGN || require_initializer) { | 467 if (peek() == i::Token::ASSIGN || require_initializer) { |
468 Expect(i::Token::ASSIGN, CHECK_OK); | 468 Expect(i::Token::ASSIGN, CHECK_OK); |
469 ParseAssignmentExpression(var_context != kForStatement, CHECK_OK); | 469 ParseAssignmentExpression(var_context != kForStatement, CHECK_OK); |
470 if (decl_props != NULL) *decl_props = kHasInitializers; | 470 if (decl_props != NULL) *decl_props = kHasInitializers; |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
517 return Statement::Default(); | 517 return Statement::Default(); |
518 } | 518 } |
519 | 519 |
520 | 520 |
521 PreParser::Statement PreParser::ParseContinueStatement(bool* ok) { | 521 PreParser::Statement PreParser::ParseContinueStatement(bool* ok) { |
522 // ContinueStatement :: | 522 // ContinueStatement :: |
523 // 'continue' [no line terminator] Identifier? ';' | 523 // 'continue' [no line terminator] Identifier? ';' |
524 | 524 |
525 Expect(i::Token::CONTINUE, CHECK_OK); | 525 Expect(i::Token::CONTINUE, CHECK_OK); |
526 i::Token::Value tok = peek(); | 526 i::Token::Value tok = peek(); |
527 if (!scanner_->HasAnyLineTerminatorBeforeNext() && | 527 if (!scanner()->HasAnyLineTerminatorBeforeNext() && |
528 tok != i::Token::SEMICOLON && | 528 tok != i::Token::SEMICOLON && |
529 tok != i::Token::RBRACE && | 529 tok != i::Token::RBRACE && |
530 tok != i::Token::EOS) { | 530 tok != i::Token::EOS) { |
531 ParseIdentifier(CHECK_OK); | 531 ParseIdentifier(CHECK_OK); |
532 } | 532 } |
533 ExpectSemicolon(CHECK_OK); | 533 ExpectSemicolon(CHECK_OK); |
534 return Statement::Default(); | 534 return Statement::Default(); |
535 } | 535 } |
536 | 536 |
537 | 537 |
538 PreParser::Statement PreParser::ParseBreakStatement(bool* ok) { | 538 PreParser::Statement PreParser::ParseBreakStatement(bool* ok) { |
539 // BreakStatement :: | 539 // BreakStatement :: |
540 // 'break' [no line terminator] Identifier? ';' | 540 // 'break' [no line terminator] Identifier? ';' |
541 | 541 |
542 Expect(i::Token::BREAK, CHECK_OK); | 542 Expect(i::Token::BREAK, CHECK_OK); |
543 i::Token::Value tok = peek(); | 543 i::Token::Value tok = peek(); |
544 if (!scanner_->HasAnyLineTerminatorBeforeNext() && | 544 if (!scanner()->HasAnyLineTerminatorBeforeNext() && |
545 tok != i::Token::SEMICOLON && | 545 tok != i::Token::SEMICOLON && |
546 tok != i::Token::RBRACE && | 546 tok != i::Token::RBRACE && |
547 tok != i::Token::EOS) { | 547 tok != i::Token::EOS) { |
548 ParseIdentifier(CHECK_OK); | 548 ParseIdentifier(CHECK_OK); |
549 } | 549 } |
550 ExpectSemicolon(CHECK_OK); | 550 ExpectSemicolon(CHECK_OK); |
551 return Statement::Default(); | 551 return Statement::Default(); |
552 } | 552 } |
553 | 553 |
554 | 554 |
555 PreParser::Statement PreParser::ParseReturnStatement(bool* ok) { | 555 PreParser::Statement PreParser::ParseReturnStatement(bool* ok) { |
556 // ReturnStatement :: | 556 // ReturnStatement :: |
557 // 'return' [no line terminator] Expression? ';' | 557 // 'return' [no line terminator] Expression? ';' |
558 | 558 |
559 // Consume the return token. It is necessary to do the before | 559 // Consume the return token. It is necessary to do the before |
560 // reporting any errors on it, because of the way errors are | 560 // reporting any errors on it, because of the way errors are |
561 // reported (underlining). | 561 // reported (underlining). |
562 Expect(i::Token::RETURN, CHECK_OK); | 562 Expect(i::Token::RETURN, CHECK_OK); |
563 | 563 |
564 // An ECMAScript program is considered syntactically incorrect if it | 564 // An ECMAScript program is considered syntactically incorrect if it |
565 // contains a return statement that is not within the body of a | 565 // contains a return statement that is not within the body of a |
566 // function. See ECMA-262, section 12.9, page 67. | 566 // function. See ECMA-262, section 12.9, page 67. |
567 // This is not handled during preparsing. | 567 // This is not handled during preparsing. |
568 | 568 |
569 i::Token::Value tok = peek(); | 569 i::Token::Value tok = peek(); |
570 if (!scanner_->HasAnyLineTerminatorBeforeNext() && | 570 if (!scanner()->HasAnyLineTerminatorBeforeNext() && |
571 tok != i::Token::SEMICOLON && | 571 tok != i::Token::SEMICOLON && |
572 tok != i::Token::RBRACE && | 572 tok != i::Token::RBRACE && |
573 tok != i::Token::EOS) { | 573 tok != i::Token::EOS) { |
574 ParseExpression(true, CHECK_OK); | 574 ParseExpression(true, CHECK_OK); |
575 } | 575 } |
576 ExpectSemicolon(CHECK_OK); | 576 ExpectSemicolon(CHECK_OK); |
577 return Statement::Default(); | 577 return Statement::Default(); |
578 } | 578 } |
579 | 579 |
580 | 580 |
581 PreParser::Statement PreParser::ParseWithStatement(bool* ok) { | 581 PreParser::Statement PreParser::ParseWithStatement(bool* ok) { |
582 // WithStatement :: | 582 // WithStatement :: |
583 // 'with' '(' Expression ')' Statement | 583 // 'with' '(' Expression ')' Statement |
584 Expect(i::Token::WITH, CHECK_OK); | 584 Expect(i::Token::WITH, CHECK_OK); |
585 if (!is_classic_mode()) { | 585 if (!is_classic_mode()) { |
586 i::Scanner::Location location = scanner_->location(); | 586 i::Scanner::Location location = scanner()->location(); |
587 ReportMessageAt(location, "strict_mode_with", NULL); | 587 ReportMessageAt(location, "strict_mode_with", NULL); |
588 *ok = false; | 588 *ok = false; |
589 return Statement::Default(); | 589 return Statement::Default(); |
590 } | 590 } |
591 Expect(i::Token::LPAREN, CHECK_OK); | 591 Expect(i::Token::LPAREN, CHECK_OK); |
592 ParseExpression(true, CHECK_OK); | 592 ParseExpression(true, CHECK_OK); |
593 Expect(i::Token::RPAREN, CHECK_OK); | 593 Expect(i::Token::RPAREN, CHECK_OK); |
594 | 594 |
595 Scope::InsideWith iw(scope_); | 595 Scope::InsideWith iw(scope_); |
596 ParseStatement(CHECK_OK); | 596 ParseStatement(CHECK_OK); |
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
654 ParseExpression(true, CHECK_OK); | 654 ParseExpression(true, CHECK_OK); |
655 Expect(i::Token::RPAREN, CHECK_OK); | 655 Expect(i::Token::RPAREN, CHECK_OK); |
656 ParseStatement(ok); | 656 ParseStatement(ok); |
657 return Statement::Default(); | 657 return Statement::Default(); |
658 } | 658 } |
659 | 659 |
660 | 660 |
661 bool PreParser::CheckInOrOf(bool accept_OF) { | 661 bool PreParser::CheckInOrOf(bool accept_OF) { |
662 if (peek() == i::Token::IN || | 662 if (peek() == i::Token::IN || |
663 (allow_for_of() && accept_OF && peek() == i::Token::IDENTIFIER && | 663 (allow_for_of() && accept_OF && peek() == i::Token::IDENTIFIER && |
664 scanner_->is_next_contextual_keyword(v8::internal::CStrVector("of")))) { | 664 scanner()->is_next_contextual_keyword(v8::internal::CStrVector("of")))) { |
665 Next(); | 665 Next(); |
666 return true; | 666 return true; |
667 } | 667 } |
668 return false; | 668 return false; |
669 } | 669 } |
670 | 670 |
671 | 671 |
672 PreParser::Statement PreParser::ParseForStatement(bool* ok) { | 672 PreParser::Statement PreParser::ParseForStatement(bool* ok) { |
673 // ForStatement :: | 673 // ForStatement :: |
674 // 'for' '(' Expression? ';' Expression? ';' Expression? ')' Statement | 674 // 'for' '(' Expression? ';' Expression? ';' Expression? ')' Statement |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
721 ParseStatement(ok); | 721 ParseStatement(ok); |
722 return Statement::Default(); | 722 return Statement::Default(); |
723 } | 723 } |
724 | 724 |
725 | 725 |
726 PreParser::Statement PreParser::ParseThrowStatement(bool* ok) { | 726 PreParser::Statement PreParser::ParseThrowStatement(bool* ok) { |
727 // ThrowStatement :: | 727 // ThrowStatement :: |
728 // 'throw' [no line terminator] Expression ';' | 728 // 'throw' [no line terminator] Expression ';' |
729 | 729 |
730 Expect(i::Token::THROW, CHECK_OK); | 730 Expect(i::Token::THROW, CHECK_OK); |
731 if (scanner_->HasAnyLineTerminatorBeforeNext()) { | 731 if (scanner()->HasAnyLineTerminatorBeforeNext()) { |
732 i::Scanner::Location pos = scanner_->location(); | 732 i::Scanner::Location pos = scanner()->location(); |
733 ReportMessageAt(pos, "newline_after_throw", NULL); | 733 ReportMessageAt(pos, "newline_after_throw", NULL); |
734 *ok = false; | 734 *ok = false; |
735 return Statement::Default(); | 735 return Statement::Default(); |
736 } | 736 } |
737 ParseExpression(true, CHECK_OK); | 737 ParseExpression(true, CHECK_OK); |
738 ExpectSemicolon(ok); | 738 ExpectSemicolon(ok); |
739 return Statement::Default(); | 739 return Statement::Default(); |
740 } | 740 } |
741 | 741 |
742 | 742 |
(...skipping 15 matching lines...) Expand all Loading... |
758 Expect(i::Token::TRY, CHECK_OK); | 758 Expect(i::Token::TRY, CHECK_OK); |
759 | 759 |
760 ParseBlock(CHECK_OK); | 760 ParseBlock(CHECK_OK); |
761 | 761 |
762 bool catch_or_finally_seen = false; | 762 bool catch_or_finally_seen = false; |
763 if (peek() == i::Token::CATCH) { | 763 if (peek() == i::Token::CATCH) { |
764 Consume(i::Token::CATCH); | 764 Consume(i::Token::CATCH); |
765 Expect(i::Token::LPAREN, CHECK_OK); | 765 Expect(i::Token::LPAREN, CHECK_OK); |
766 Identifier id = ParseIdentifier(CHECK_OK); | 766 Identifier id = ParseIdentifier(CHECK_OK); |
767 if (!is_classic_mode() && !id.IsValidStrictVariable()) { | 767 if (!is_classic_mode() && !id.IsValidStrictVariable()) { |
768 StrictModeIdentifierViolation(scanner_->location(), | 768 StrictModeIdentifierViolation(scanner()->location(), |
769 "strict_catch_variable", | 769 "strict_catch_variable", |
770 id, | 770 id, |
771 ok); | 771 ok); |
772 return Statement::Default(); | 772 return Statement::Default(); |
773 } | 773 } |
774 Expect(i::Token::RPAREN, CHECK_OK); | 774 Expect(i::Token::RPAREN, CHECK_OK); |
775 { Scope::InsideWith iw(scope_); | 775 { Scope::InsideWith iw(scope_); |
776 ParseBlock(CHECK_OK); | 776 ParseBlock(CHECK_OK); |
777 } | 777 } |
778 catch_or_finally_seen = true; | 778 catch_or_finally_seen = true; |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
831 bool* ok) { | 831 bool* ok) { |
832 // AssignmentExpression :: | 832 // AssignmentExpression :: |
833 // ConditionalExpression | 833 // ConditionalExpression |
834 // YieldExpression | 834 // YieldExpression |
835 // LeftHandSideExpression AssignmentOperator AssignmentExpression | 835 // LeftHandSideExpression AssignmentOperator AssignmentExpression |
836 | 836 |
837 if (scope_->is_generator() && peek() == i::Token::YIELD) { | 837 if (scope_->is_generator() && peek() == i::Token::YIELD) { |
838 return ParseYieldExpression(ok); | 838 return ParseYieldExpression(ok); |
839 } | 839 } |
840 | 840 |
841 i::Scanner::Location before = scanner_->peek_location(); | 841 i::Scanner::Location before = scanner()->peek_location(); |
842 Expression expression = ParseConditionalExpression(accept_IN, CHECK_OK); | 842 Expression expression = ParseConditionalExpression(accept_IN, CHECK_OK); |
843 | 843 |
844 if (!i::Token::IsAssignmentOp(peek())) { | 844 if (!i::Token::IsAssignmentOp(peek())) { |
845 // Parsed conditional expression only (no assignment). | 845 // Parsed conditional expression only (no assignment). |
846 return expression; | 846 return expression; |
847 } | 847 } |
848 | 848 |
849 if (!is_classic_mode() && | 849 if (!is_classic_mode() && |
850 expression.IsIdentifier() && | 850 expression.IsIdentifier() && |
851 expression.AsIdentifier().IsEvalOrArguments()) { | 851 expression.AsIdentifier().IsEvalOrArguments()) { |
852 i::Scanner::Location after = scanner_->location(); | 852 i::Scanner::Location after = scanner()->location(); |
853 ReportMessageAt(before.beg_pos, after.end_pos, | 853 ReportMessageAt(before.beg_pos, after.end_pos, |
854 "strict_lhs_assignment", NULL); | 854 "strict_lhs_assignment", NULL); |
855 *ok = false; | 855 *ok = false; |
856 return Expression::Default(); | 856 return Expression::Default(); |
857 } | 857 } |
858 | 858 |
859 i::Token::Value op = Next(); // Get assignment operator. | 859 i::Token::Value op = Next(); // Get assignment operator. |
860 ParseAssignmentExpression(accept_IN, CHECK_OK); | 860 ParseAssignmentExpression(accept_IN, CHECK_OK); |
861 | 861 |
862 if ((op == i::Token::ASSIGN) && expression.IsThisProperty()) { | 862 if ((op == i::Token::ASSIGN) && expression.IsThisProperty()) { |
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
939 // '~' UnaryExpression | 939 // '~' UnaryExpression |
940 // '!' UnaryExpression | 940 // '!' UnaryExpression |
941 | 941 |
942 i::Token::Value op = peek(); | 942 i::Token::Value op = peek(); |
943 if (i::Token::IsUnaryOp(op)) { | 943 if (i::Token::IsUnaryOp(op)) { |
944 op = Next(); | 944 op = Next(); |
945 ParseUnaryExpression(ok); | 945 ParseUnaryExpression(ok); |
946 return Expression::Default(); | 946 return Expression::Default(); |
947 } else if (i::Token::IsCountOp(op)) { | 947 } else if (i::Token::IsCountOp(op)) { |
948 op = Next(); | 948 op = Next(); |
949 i::Scanner::Location before = scanner_->peek_location(); | 949 i::Scanner::Location before = scanner()->peek_location(); |
950 Expression expression = ParseUnaryExpression(CHECK_OK); | 950 Expression expression = ParseUnaryExpression(CHECK_OK); |
951 if (!is_classic_mode() && | 951 if (!is_classic_mode() && |
952 expression.IsIdentifier() && | 952 expression.IsIdentifier() && |
953 expression.AsIdentifier().IsEvalOrArguments()) { | 953 expression.AsIdentifier().IsEvalOrArguments()) { |
954 i::Scanner::Location after = scanner_->location(); | 954 i::Scanner::Location after = scanner()->location(); |
955 ReportMessageAt(before.beg_pos, after.end_pos, | 955 ReportMessageAt(before.beg_pos, after.end_pos, |
956 "strict_lhs_prefix", NULL); | 956 "strict_lhs_prefix", NULL); |
957 *ok = false; | 957 *ok = false; |
958 } | 958 } |
959 return Expression::Default(); | 959 return Expression::Default(); |
960 } else { | 960 } else { |
961 return ParsePostfixExpression(ok); | 961 return ParsePostfixExpression(ok); |
962 } | 962 } |
963 } | 963 } |
964 | 964 |
965 | 965 |
966 PreParser::Expression PreParser::ParsePostfixExpression(bool* ok) { | 966 PreParser::Expression PreParser::ParsePostfixExpression(bool* ok) { |
967 // PostfixExpression :: | 967 // PostfixExpression :: |
968 // LeftHandSideExpression ('++' | '--')? | 968 // LeftHandSideExpression ('++' | '--')? |
969 | 969 |
970 i::Scanner::Location before = scanner_->peek_location(); | 970 i::Scanner::Location before = scanner()->peek_location(); |
971 Expression expression = ParseLeftHandSideExpression(CHECK_OK); | 971 Expression expression = ParseLeftHandSideExpression(CHECK_OK); |
972 if (!scanner_->HasAnyLineTerminatorBeforeNext() && | 972 if (!scanner()->HasAnyLineTerminatorBeforeNext() && |
973 i::Token::IsCountOp(peek())) { | 973 i::Token::IsCountOp(peek())) { |
974 if (!is_classic_mode() && | 974 if (!is_classic_mode() && |
975 expression.IsIdentifier() && | 975 expression.IsIdentifier() && |
976 expression.AsIdentifier().IsEvalOrArguments()) { | 976 expression.AsIdentifier().IsEvalOrArguments()) { |
977 i::Scanner::Location after = scanner_->location(); | 977 i::Scanner::Location after = scanner()->location(); |
978 ReportMessageAt(before.beg_pos, after.end_pos, | 978 ReportMessageAt(before.beg_pos, after.end_pos, |
979 "strict_lhs_postfix", NULL); | 979 "strict_lhs_postfix", NULL); |
980 *ok = false; | 980 *ok = false; |
981 return Expression::Default(); | 981 return Expression::Default(); |
982 } | 982 } |
983 Next(); | 983 Next(); |
984 return Expression::Default(); | 984 return Expression::Default(); |
985 } | 985 } |
986 return expression; | 986 return expression; |
987 } | 987 } |
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1067 unsigned new_count, bool* ok) { | 1067 unsigned new_count, bool* ok) { |
1068 // MemberExpression :: | 1068 // MemberExpression :: |
1069 // (PrimaryExpression | FunctionLiteral) | 1069 // (PrimaryExpression | FunctionLiteral) |
1070 // ('[' Expression ']' | '.' Identifier | Arguments)* | 1070 // ('[' Expression ']' | '.' Identifier | Arguments)* |
1071 | 1071 |
1072 // Parse the initial primary or function expression. | 1072 // Parse the initial primary or function expression. |
1073 Expression result = Expression::Default(); | 1073 Expression result = Expression::Default(); |
1074 if (peek() == i::Token::FUNCTION) { | 1074 if (peek() == i::Token::FUNCTION) { |
1075 Consume(i::Token::FUNCTION); | 1075 Consume(i::Token::FUNCTION); |
1076 | 1076 |
1077 bool is_generator = allow_generators_ && Check(i::Token::MUL); | 1077 bool is_generator = allow_generators() && Check(i::Token::MUL); |
1078 Identifier identifier = Identifier::Default(); | 1078 Identifier identifier = Identifier::Default(); |
1079 if (peek_any_identifier()) { | 1079 if (peek_any_identifier()) { |
1080 identifier = ParseIdentifier(CHECK_OK); | 1080 identifier = ParseIdentifier(CHECK_OK); |
1081 } | 1081 } |
1082 result = ParseFunctionLiteral(is_generator, CHECK_OK); | 1082 result = ParseFunctionLiteral(is_generator, CHECK_OK); |
1083 if (result.IsStrictFunction() && !identifier.IsValidStrictVariable()) { | 1083 if (result.IsStrictFunction() && !identifier.IsValidStrictVariable()) { |
1084 StrictModeIdentifierViolation(scanner_->location(), | 1084 StrictModeIdentifierViolation(scanner()->location(), |
1085 "strict_function_name", | 1085 "strict_function_name", |
1086 identifier, | 1086 identifier, |
1087 ok); | 1087 ok); |
1088 return Expression::Default(); | 1088 return Expression::Default(); |
1089 } | 1089 } |
1090 } else { | 1090 } else { |
1091 result = ParsePrimaryExpression(CHECK_OK); | 1091 result = ParsePrimaryExpression(CHECK_OK); |
1092 } | 1092 } |
1093 | 1093 |
1094 while (true) { | 1094 while (true) { |
(...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1231 } | 1231 } |
1232 | 1232 |
1233 | 1233 |
1234 PreParser::Expression PreParser::ParseObjectLiteral(bool* ok) { | 1234 PreParser::Expression PreParser::ParseObjectLiteral(bool* ok) { |
1235 // ObjectLiteral :: | 1235 // ObjectLiteral :: |
1236 // '{' ( | 1236 // '{' ( |
1237 // ((IdentifierName | String | Number) ':' AssignmentExpression) | 1237 // ((IdentifierName | String | Number) ':' AssignmentExpression) |
1238 // | (('get' | 'set') (IdentifierName | String | Number) FunctionLiteral) | 1238 // | (('get' | 'set') (IdentifierName | String | Number) FunctionLiteral) |
1239 // )*[','] '}' | 1239 // )*[','] '}' |
1240 | 1240 |
1241 i::ObjectLiteralChecker<PreParser> checker(this, scanner_, language_mode()); | 1241 i::ObjectLiteralChecker<PreParser> checker(this, scanner(), language_mode()); |
1242 | 1242 |
1243 Expect(i::Token::LBRACE, CHECK_OK); | 1243 Expect(i::Token::LBRACE, CHECK_OK); |
1244 while (peek() != i::Token::RBRACE) { | 1244 while (peek() != i::Token::RBRACE) { |
1245 i::Token::Value next = peek(); | 1245 i::Token::Value next = peek(); |
1246 switch (next) { | 1246 switch (next) { |
1247 case i::Token::IDENTIFIER: | 1247 case i::Token::IDENTIFIER: |
1248 case i::Token::FUTURE_RESERVED_WORD: | 1248 case i::Token::FUTURE_RESERVED_WORD: |
1249 case i::Token::FUTURE_STRICT_RESERVED_WORD: { | 1249 case i::Token::FUTURE_STRICT_RESERVED_WORD: { |
1250 bool is_getter = false; | 1250 bool is_getter = false; |
1251 bool is_setter = false; | 1251 bool is_setter = false; |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1305 } | 1305 } |
1306 Expect(i::Token::RBRACE, CHECK_OK); | 1306 Expect(i::Token::RBRACE, CHECK_OK); |
1307 | 1307 |
1308 scope_->NextMaterializedLiteralIndex(); | 1308 scope_->NextMaterializedLiteralIndex(); |
1309 return Expression::Default(); | 1309 return Expression::Default(); |
1310 } | 1310 } |
1311 | 1311 |
1312 | 1312 |
1313 PreParser::Expression PreParser::ParseRegExpLiteral(bool seen_equal, | 1313 PreParser::Expression PreParser::ParseRegExpLiteral(bool seen_equal, |
1314 bool* ok) { | 1314 bool* ok) { |
1315 if (!scanner_->ScanRegExpPattern(seen_equal)) { | 1315 if (!scanner()->ScanRegExpPattern(seen_equal)) { |
1316 Next(); | 1316 Next(); |
1317 ReportMessageAt(scanner_->location(), "unterminated_regexp", NULL); | 1317 ReportMessageAt(scanner()->location(), "unterminated_regexp", NULL); |
1318 *ok = false; | 1318 *ok = false; |
1319 return Expression::Default(); | 1319 return Expression::Default(); |
1320 } | 1320 } |
1321 | 1321 |
1322 scope_->NextMaterializedLiteralIndex(); | 1322 scope_->NextMaterializedLiteralIndex(); |
1323 | 1323 |
1324 if (!scanner_->ScanRegExpFlags()) { | 1324 if (!scanner()->ScanRegExpFlags()) { |
1325 Next(); | 1325 Next(); |
1326 ReportMessageAt(scanner_->location(), "invalid_regexp_flags", NULL); | 1326 ReportMessageAt(scanner()->location(), "invalid_regexp_flags", NULL); |
1327 *ok = false; | 1327 *ok = false; |
1328 return Expression::Default(); | 1328 return Expression::Default(); |
1329 } | 1329 } |
1330 Next(); | 1330 Next(); |
1331 return Expression::Default(); | 1331 return Expression::Default(); |
1332 } | 1332 } |
1333 | 1333 |
1334 | 1334 |
1335 PreParser::Arguments PreParser::ParseArguments(bool* ok) { | 1335 PreParser::Arguments PreParser::ParseArguments(bool* ok) { |
1336 // Arguments :: | 1336 // Arguments :: |
(...skipping 24 matching lines...) Expand all Loading... |
1361 // '(' FormalParameterList? ')' '{' FunctionBody '}' | 1361 // '(' FormalParameterList? ')' '{' FunctionBody '}' |
1362 | 1362 |
1363 // Parse function body. | 1363 // Parse function body. |
1364 ScopeType outer_scope_type = scope_->type(); | 1364 ScopeType outer_scope_type = scope_->type(); |
1365 bool inside_with = scope_->IsInsideWith(); | 1365 bool inside_with = scope_->IsInsideWith(); |
1366 Scope function_scope(&scope_, kFunctionScope); | 1366 Scope function_scope(&scope_, kFunctionScope); |
1367 function_scope.set_is_generator(is_generator); | 1367 function_scope.set_is_generator(is_generator); |
1368 // FormalParameterList :: | 1368 // FormalParameterList :: |
1369 // '(' (Identifier)*[','] ')' | 1369 // '(' (Identifier)*[','] ')' |
1370 Expect(i::Token::LPAREN, CHECK_OK); | 1370 Expect(i::Token::LPAREN, CHECK_OK); |
1371 int start_position = scanner_->location().beg_pos; | 1371 int start_position = scanner()->location().beg_pos; |
1372 bool done = (peek() == i::Token::RPAREN); | 1372 bool done = (peek() == i::Token::RPAREN); |
1373 i::DuplicateFinder duplicate_finder(scanner_->unicode_cache()); | 1373 i::DuplicateFinder duplicate_finder(scanner()->unicode_cache()); |
1374 while (!done) { | 1374 while (!done) { |
1375 Identifier id = ParseIdentifier(CHECK_OK); | 1375 Identifier id = ParseIdentifier(CHECK_OK); |
1376 if (!id.IsValidStrictVariable()) { | 1376 if (!id.IsValidStrictVariable()) { |
1377 StrictModeIdentifierViolation(scanner_->location(), | 1377 StrictModeIdentifierViolation(scanner()->location(), |
1378 "strict_param_name", | 1378 "strict_param_name", |
1379 id, | 1379 id, |
1380 CHECK_OK); | 1380 CHECK_OK); |
1381 } | 1381 } |
1382 int prev_value; | 1382 int prev_value; |
1383 if (scanner_->is_literal_ascii()) { | 1383 if (scanner()->is_literal_ascii()) { |
1384 prev_value = | 1384 prev_value = |
1385 duplicate_finder.AddAsciiSymbol(scanner_->literal_ascii_string(), 1); | 1385 duplicate_finder.AddAsciiSymbol(scanner()->literal_ascii_string(), 1); |
1386 } else { | 1386 } else { |
1387 prev_value = | 1387 prev_value = |
1388 duplicate_finder.AddUtf16Symbol(scanner_->literal_utf16_string(), 1); | 1388 duplicate_finder.AddUtf16Symbol(scanner()->literal_utf16_string(), 1); |
1389 } | 1389 } |
1390 | 1390 |
1391 if (prev_value != 0) { | 1391 if (prev_value != 0) { |
1392 SetStrictModeViolation(scanner_->location(), | 1392 SetStrictModeViolation(scanner()->location(), |
1393 "strict_param_dupe", | 1393 "strict_param_dupe", |
1394 CHECK_OK); | 1394 CHECK_OK); |
1395 } | 1395 } |
1396 done = (peek() == i::Token::RPAREN); | 1396 done = (peek() == i::Token::RPAREN); |
1397 if (!done) { | 1397 if (!done) { |
1398 Expect(i::Token::COMMA, CHECK_OK); | 1398 Expect(i::Token::COMMA, CHECK_OK); |
1399 } | 1399 } |
1400 } | 1400 } |
1401 Expect(i::Token::RPAREN, CHECK_OK); | 1401 Expect(i::Token::RPAREN, CHECK_OK); |
1402 | 1402 |
1403 // Determine if the function will be lazily compiled. | 1403 // Determine if the function will be lazily compiled. |
1404 // Currently only happens to top-level functions. | 1404 // Currently only happens to top-level functions. |
1405 // Optimistically assume that all top-level functions are lazily compiled. | 1405 // Optimistically assume that all top-level functions are lazily compiled. |
1406 bool is_lazily_compiled = (outer_scope_type == kTopLevelScope && | 1406 bool is_lazily_compiled = (outer_scope_type == kTopLevelScope && |
1407 !inside_with && allow_lazy_ && | 1407 !inside_with && allow_lazy() && |
1408 !parenthesized_function_); | 1408 !parenthesized_function_); |
1409 parenthesized_function_ = false; | 1409 parenthesized_function_ = false; |
1410 | 1410 |
1411 Expect(i::Token::LBRACE, CHECK_OK); | 1411 Expect(i::Token::LBRACE, CHECK_OK); |
1412 if (is_lazily_compiled) { | 1412 if (is_lazily_compiled) { |
1413 ParseLazyFunctionLiteralBody(CHECK_OK); | 1413 ParseLazyFunctionLiteralBody(CHECK_OK); |
1414 } else { | 1414 } else { |
1415 ParseSourceElements(i::Token::RBRACE, ok); | 1415 ParseSourceElements(i::Token::RBRACE, ok); |
1416 } | 1416 } |
1417 Expect(i::Token::RBRACE, CHECK_OK); | 1417 Expect(i::Token::RBRACE, CHECK_OK); |
1418 | 1418 |
1419 if (!is_classic_mode()) { | 1419 if (!is_classic_mode()) { |
1420 int end_position = scanner_->location().end_pos; | 1420 int end_position = scanner()->location().end_pos; |
1421 CheckOctalLiteral(start_position, end_position, CHECK_OK); | 1421 CheckOctalLiteral(start_position, end_position, CHECK_OK); |
1422 CheckDelayedStrictModeViolation(start_position, end_position, CHECK_OK); | 1422 CheckDelayedStrictModeViolation(start_position, end_position, CHECK_OK); |
1423 return Expression::StrictFunction(); | 1423 return Expression::StrictFunction(); |
1424 } | 1424 } |
1425 | 1425 |
1426 return Expression::Default(); | 1426 return Expression::Default(); |
1427 } | 1427 } |
1428 | 1428 |
1429 | 1429 |
1430 void PreParser::ParseLazyFunctionLiteralBody(bool* ok) { | 1430 void PreParser::ParseLazyFunctionLiteralBody(bool* ok) { |
1431 int body_start = scanner_->location().beg_pos; | 1431 int body_start = scanner()->location().beg_pos; |
1432 log_->PauseRecording(); | 1432 log_->PauseRecording(); |
1433 ParseSourceElements(i::Token::RBRACE, ok); | 1433 ParseSourceElements(i::Token::RBRACE, ok); |
1434 log_->ResumeRecording(); | 1434 log_->ResumeRecording(); |
1435 if (!*ok) return; | 1435 if (!*ok) return; |
1436 | 1436 |
1437 // Position right after terminal '}'. | 1437 // Position right after terminal '}'. |
1438 ASSERT_EQ(i::Token::RBRACE, scanner_->peek()); | 1438 ASSERT_EQ(i::Token::RBRACE, scanner()->peek()); |
1439 int body_end = scanner_->peek_location().end_pos; | 1439 int body_end = scanner()->peek_location().end_pos; |
1440 log_->LogFunction(body_start, body_end, | 1440 log_->LogFunction(body_start, body_end, |
1441 scope_->materialized_literal_count(), | 1441 scope_->materialized_literal_count(), |
1442 scope_->expected_properties(), | 1442 scope_->expected_properties(), |
1443 language_mode()); | 1443 language_mode()); |
1444 } | 1444 } |
1445 | 1445 |
1446 | 1446 |
1447 PreParser::Expression PreParser::ParseV8Intrinsic(bool* ok) { | 1447 PreParser::Expression PreParser::ParseV8Intrinsic(bool* ok) { |
1448 // CallRuntime :: | 1448 // CallRuntime :: |
1449 // '%' Identifier Arguments | 1449 // '%' Identifier Arguments |
1450 Expect(i::Token::MOD, CHECK_OK); | 1450 Expect(i::Token::MOD, CHECK_OK); |
1451 if (!allow_natives_syntax_) { | 1451 if (!allow_natives_syntax()) { |
1452 *ok = false; | 1452 *ok = false; |
1453 return Expression::Default(); | 1453 return Expression::Default(); |
1454 } | 1454 } |
1455 ParseIdentifier(CHECK_OK); | 1455 ParseIdentifier(CHECK_OK); |
1456 ParseArguments(ok); | 1456 ParseArguments(ok); |
1457 | 1457 |
1458 return Expression::Default(); | 1458 return Expression::Default(); |
1459 } | 1459 } |
1460 | 1460 |
1461 #undef CHECK_OK | 1461 #undef CHECK_OK |
1462 | 1462 |
1463 | 1463 |
1464 void PreParser::ExpectSemicolon(bool* ok) { | |
1465 // Check for automatic semicolon insertion according to | |
1466 // the rules given in ECMA-262, section 7.9, page 21. | |
1467 i::Token::Value tok = peek(); | |
1468 if (tok == i::Token::SEMICOLON) { | |
1469 Next(); | |
1470 return; | |
1471 } | |
1472 if (scanner_->HasAnyLineTerminatorBeforeNext() || | |
1473 tok == i::Token::RBRACE || | |
1474 tok == i::Token::EOS) { | |
1475 return; | |
1476 } | |
1477 Expect(i::Token::SEMICOLON, ok); | |
1478 } | |
1479 | |
1480 | |
1481 void PreParser::LogSymbol() { | 1464 void PreParser::LogSymbol() { |
1482 int identifier_pos = scanner_->location().beg_pos; | 1465 int identifier_pos = scanner()->location().beg_pos; |
1483 if (scanner_->is_literal_ascii()) { | 1466 if (scanner()->is_literal_ascii()) { |
1484 log_->LogAsciiSymbol(identifier_pos, scanner_->literal_ascii_string()); | 1467 log_->LogAsciiSymbol(identifier_pos, scanner()->literal_ascii_string()); |
1485 } else { | 1468 } else { |
1486 log_->LogUtf16Symbol(identifier_pos, scanner_->literal_utf16_string()); | 1469 log_->LogUtf16Symbol(identifier_pos, scanner()->literal_utf16_string()); |
1487 } | 1470 } |
1488 } | 1471 } |
1489 | 1472 |
1490 | 1473 |
1491 PreParser::Expression PreParser::GetStringSymbol() { | 1474 PreParser::Expression PreParser::GetStringSymbol() { |
1492 const int kUseStrictLength = 10; | 1475 const int kUseStrictLength = 10; |
1493 const char* kUseStrictChars = "use strict"; | 1476 const char* kUseStrictChars = "use strict"; |
1494 LogSymbol(); | 1477 LogSymbol(); |
1495 if (scanner_->is_literal_ascii() && | 1478 if (scanner()->is_literal_ascii() && |
1496 scanner_->literal_length() == kUseStrictLength && | 1479 scanner()->literal_length() == kUseStrictLength && |
1497 !scanner_->literal_contains_escapes() && | 1480 !scanner()->literal_contains_escapes() && |
1498 !strncmp(scanner_->literal_ascii_string().start(), kUseStrictChars, | 1481 !strncmp(scanner()->literal_ascii_string().start(), kUseStrictChars, |
1499 kUseStrictLength)) { | 1482 kUseStrictLength)) { |
1500 return Expression::UseStrictStringLiteral(); | 1483 return Expression::UseStrictStringLiteral(); |
1501 } | 1484 } |
1502 return Expression::StringLiteral(); | 1485 return Expression::StringLiteral(); |
1503 } | 1486 } |
1504 | 1487 |
1505 | 1488 |
1506 PreParser::Identifier PreParser::GetIdentifierSymbol() { | 1489 PreParser::Identifier PreParser::GetIdentifierSymbol() { |
1507 LogSymbol(); | 1490 LogSymbol(); |
1508 if (scanner_->current_token() == i::Token::FUTURE_RESERVED_WORD) { | 1491 if (scanner()->current_token() == i::Token::FUTURE_RESERVED_WORD) { |
1509 return Identifier::FutureReserved(); | 1492 return Identifier::FutureReserved(); |
1510 } else if (scanner_->current_token() == | 1493 } else if (scanner()->current_token() == |
1511 i::Token::FUTURE_STRICT_RESERVED_WORD) { | 1494 i::Token::FUTURE_STRICT_RESERVED_WORD) { |
1512 return Identifier::FutureStrictReserved(); | 1495 return Identifier::FutureStrictReserved(); |
1513 } else if (scanner_->current_token() == i::Token::YIELD) { | 1496 } else if (scanner()->current_token() == i::Token::YIELD) { |
1514 return Identifier::Yield(); | 1497 return Identifier::Yield(); |
1515 } | 1498 } |
1516 if (scanner_->is_literal_ascii()) { | 1499 if (scanner()->is_literal_ascii()) { |
1517 // Detect strict-mode poison words. | 1500 // Detect strict-mode poison words. |
1518 if (scanner_->literal_length() == 4 && | 1501 if (scanner()->literal_length() == 4 && |
1519 !strncmp(scanner_->literal_ascii_string().start(), "eval", 4)) { | 1502 !strncmp(scanner()->literal_ascii_string().start(), "eval", 4)) { |
1520 return Identifier::Eval(); | 1503 return Identifier::Eval(); |
1521 } | 1504 } |
1522 if (scanner_->literal_length() == 9 && | 1505 if (scanner()->literal_length() == 9 && |
1523 !strncmp(scanner_->literal_ascii_string().start(), "arguments", 9)) { | 1506 !strncmp(scanner()->literal_ascii_string().start(), "arguments", 9)) { |
1524 return Identifier::Arguments(); | 1507 return Identifier::Arguments(); |
1525 } | 1508 } |
1526 } | 1509 } |
1527 return Identifier::Default(); | 1510 return Identifier::Default(); |
1528 } | 1511 } |
1529 | 1512 |
1530 | 1513 |
1531 PreParser::Identifier PreParser::ParseIdentifier(bool* ok) { | 1514 PreParser::Identifier PreParser::ParseIdentifier(bool* ok) { |
1532 i::Token::Value next = Next(); | 1515 i::Token::Value next = Next(); |
1533 switch (next) { | 1516 switch (next) { |
1534 case i::Token::FUTURE_RESERVED_WORD: { | 1517 case i::Token::FUTURE_RESERVED_WORD: { |
1535 i::Scanner::Location location = scanner_->location(); | 1518 i::Scanner::Location location = scanner()->location(); |
1536 ReportMessageAt(location.beg_pos, location.end_pos, | 1519 ReportMessageAt(location.beg_pos, location.end_pos, |
1537 "reserved_word", NULL); | 1520 "reserved_word", NULL); |
1538 *ok = false; | 1521 *ok = false; |
1539 return GetIdentifierSymbol(); | 1522 return GetIdentifierSymbol(); |
1540 } | 1523 } |
1541 case i::Token::YIELD: | 1524 case i::Token::YIELD: |
1542 if (scope_->is_generator()) { | 1525 if (scope_->is_generator()) { |
1543 // 'yield' in a generator is only valid as part of a YieldExpression. | 1526 // 'yield' in a generator is only valid as part of a YieldExpression. |
1544 ReportMessageAt(scanner_->location(), "unexpected_token", "yield"); | 1527 ReportMessageAt(scanner()->location(), "unexpected_token", "yield"); |
1545 *ok = false; | 1528 *ok = false; |
1546 return Identifier::Yield(); | 1529 return Identifier::Yield(); |
1547 } | 1530 } |
1548 // FALLTHROUGH | 1531 // FALLTHROUGH |
1549 case i::Token::FUTURE_STRICT_RESERVED_WORD: | 1532 case i::Token::FUTURE_STRICT_RESERVED_WORD: |
1550 if (!is_classic_mode()) { | 1533 if (!is_classic_mode()) { |
1551 i::Scanner::Location location = scanner_->location(); | 1534 i::Scanner::Location location = scanner()->location(); |
1552 ReportMessageAt(location.beg_pos, location.end_pos, | 1535 ReportMessageAt(location.beg_pos, location.end_pos, |
1553 "strict_reserved_word", NULL); | 1536 "strict_reserved_word", NULL); |
1554 *ok = false; | 1537 *ok = false; |
1555 } | 1538 } |
1556 // FALLTHROUGH | 1539 // FALLTHROUGH |
1557 case i::Token::IDENTIFIER: | 1540 case i::Token::IDENTIFIER: |
1558 return GetIdentifierSymbol(); | 1541 return GetIdentifierSymbol(); |
1559 default: | 1542 default: |
1560 *ok = false; | 1543 *ok = false; |
1561 return Identifier::Default(); | 1544 return Identifier::Default(); |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1612 return; | 1595 return; |
1613 } | 1596 } |
1614 strict_mode_violation_location_ = location; | 1597 strict_mode_violation_location_ = location; |
1615 strict_mode_violation_type_ = type; | 1598 strict_mode_violation_type_ = type; |
1616 } | 1599 } |
1617 | 1600 |
1618 | 1601 |
1619 PreParser::Identifier PreParser::ParseIdentifierName(bool* ok) { | 1602 PreParser::Identifier PreParser::ParseIdentifierName(bool* ok) { |
1620 i::Token::Value next = Next(); | 1603 i::Token::Value next = Next(); |
1621 if (i::Token::IsKeyword(next)) { | 1604 if (i::Token::IsKeyword(next)) { |
1622 int pos = scanner_->location().beg_pos; | 1605 int pos = scanner()->location().beg_pos; |
1623 const char* keyword = i::Token::String(next); | 1606 const char* keyword = i::Token::String(next); |
1624 log_->LogAsciiSymbol(pos, i::Vector<const char>(keyword, | 1607 log_->LogAsciiSymbol(pos, i::Vector<const char>(keyword, |
1625 i::StrLength(keyword))); | 1608 i::StrLength(keyword))); |
1626 return Identifier::Default(); | 1609 return Identifier::Default(); |
1627 } | 1610 } |
1628 if (next == i::Token::IDENTIFIER || | 1611 if (next == i::Token::IDENTIFIER || |
1629 next == i::Token::FUTURE_RESERVED_WORD || | 1612 next == i::Token::FUTURE_RESERVED_WORD || |
1630 next == i::Token::FUTURE_STRICT_RESERVED_WORD) { | 1613 next == i::Token::FUTURE_STRICT_RESERVED_WORD) { |
1631 return GetIdentifierSymbol(); | 1614 return GetIdentifierSymbol(); |
1632 } | 1615 } |
1633 *ok = false; | 1616 *ok = false; |
1634 return Identifier::Default(); | 1617 return Identifier::Default(); |
1635 } | 1618 } |
1636 | 1619 |
1637 #undef CHECK_OK | 1620 #undef CHECK_OK |
1638 | 1621 |
1639 | 1622 |
1640 // This function reads an identifier and determines whether or not it | 1623 // This function reads an identifier and determines whether or not it |
1641 // is 'get' or 'set'. | 1624 // is 'get' or 'set'. |
1642 PreParser::Identifier PreParser::ParseIdentifierNameOrGetOrSet(bool* is_get, | 1625 PreParser::Identifier PreParser::ParseIdentifierNameOrGetOrSet(bool* is_get, |
1643 bool* is_set, | 1626 bool* is_set, |
1644 bool* ok) { | 1627 bool* ok) { |
1645 Identifier result = ParseIdentifierName(ok); | 1628 Identifier result = ParseIdentifierName(ok); |
1646 if (!*ok) return Identifier::Default(); | 1629 if (!*ok) return Identifier::Default(); |
1647 if (scanner_->is_literal_ascii() && | 1630 if (scanner()->is_literal_ascii() && |
1648 scanner_->literal_length() == 3) { | 1631 scanner()->literal_length() == 3) { |
1649 const char* token = scanner_->literal_ascii_string().start(); | 1632 const char* token = scanner()->literal_ascii_string().start(); |
1650 *is_get = strncmp(token, "get", 3) == 0; | 1633 *is_get = strncmp(token, "get", 3) == 0; |
1651 *is_set = !*is_get && strncmp(token, "set", 3) == 0; | 1634 *is_set = !*is_get && strncmp(token, "set", 3) == 0; |
1652 } | 1635 } |
1653 return result; | 1636 return result; |
1654 } | 1637 } |
1655 | 1638 |
1656 | 1639 |
1657 bool PreParser::peek_any_identifier() { | |
1658 i::Token::Value next = peek(); | |
1659 return next == i::Token::IDENTIFIER || | |
1660 next == i::Token::FUTURE_RESERVED_WORD || | |
1661 next == i::Token::FUTURE_STRICT_RESERVED_WORD || | |
1662 next == i::Token::YIELD; | |
1663 } | |
1664 | |
1665 } } // v8::internal | 1640 } } // v8::internal |
OLD | NEW |