OLD | NEW |
1 // Copyright 2011 the V8 project authors. All rights reserved. | 1 // Copyright 2011 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include <cmath> | 5 #include <cmath> |
6 | 6 |
7 #include "src/allocation.h" | 7 #include "src/allocation.h" |
8 #include "src/base/logging.h" | 8 #include "src/base/logging.h" |
9 #include "src/conversions-inl.h" | 9 #include "src/conversions-inl.h" |
10 #include "src/conversions.h" | 10 #include "src/conversions.h" |
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
95 bool name_is_strict_reserved, FunctionKind kind, | 95 bool name_is_strict_reserved, FunctionKind kind, |
96 int function_token_position, FunctionLiteral::FunctionType type, | 96 int function_token_position, FunctionLiteral::FunctionType type, |
97 FunctionLiteral::ArityRestriction arity_restriction, bool* ok) { | 97 FunctionLiteral::ArityRestriction arity_restriction, bool* ok) { |
98 return pre_parser_->ParseFunctionLiteral( | 98 return pre_parser_->ParseFunctionLiteral( |
99 name, function_name_location, name_is_strict_reserved, kind, | 99 name, function_name_location, name_is_strict_reserved, kind, |
100 function_token_position, type, arity_restriction, ok); | 100 function_token_position, type, arity_restriction, ok); |
101 } | 101 } |
102 | 102 |
103 | 103 |
104 PreParser::PreParseResult PreParser::PreParseLazyFunction( | 104 PreParser::PreParseResult PreParser::PreParseLazyFunction( |
105 StrictMode strict_mode, bool is_generator, ParserRecorder* log) { | 105 LanguageMode language_mode, bool is_generator, ParserRecorder* log) { |
106 log_ = log; | 106 log_ = log; |
107 // Lazy functions always have trivial outer scopes (no with/catch scopes). | 107 // Lazy functions always have trivial outer scopes (no with/catch scopes). |
108 PreParserScope top_scope(scope_, SCRIPT_SCOPE); | 108 PreParserScope top_scope(scope_, SCRIPT_SCOPE); |
109 PreParserFactory top_factory(NULL); | 109 PreParserFactory top_factory(NULL); |
110 FunctionState top_state(&function_state_, &scope_, &top_scope, &top_factory); | 110 FunctionState top_state(&function_state_, &scope_, &top_scope, &top_factory); |
111 scope_->SetStrictMode(strict_mode); | 111 scope_->SetLanguageMode(language_mode); |
112 PreParserScope function_scope(scope_, FUNCTION_SCOPE); | 112 PreParserScope function_scope(scope_, FUNCTION_SCOPE); |
113 PreParserFactory function_factory(NULL); | 113 PreParserFactory function_factory(NULL); |
114 FunctionState function_state(&function_state_, &scope_, &function_scope, | 114 FunctionState function_state(&function_state_, &scope_, &function_scope, |
115 &function_factory); | 115 &function_factory); |
116 function_state.set_is_generator(is_generator); | 116 function_state.set_is_generator(is_generator); |
117 DCHECK_EQ(Token::LBRACE, scanner()->current_token()); | 117 DCHECK_EQ(Token::LBRACE, scanner()->current_token()); |
118 bool ok = true; | 118 bool ok = true; |
119 int start_position = peek_position(); | 119 int start_position = peek_position(); |
120 ParseLazyFunctionLiteralBody(&ok); | 120 ParseLazyFunctionLiteralBody(&ok); |
121 if (stack_overflow()) return kPreParseStackOverflow; | 121 if (stack_overflow()) return kPreParseStackOverflow; |
122 if (!ok) { | 122 if (!ok) { |
123 ReportUnexpectedToken(scanner()->current_token()); | 123 ReportUnexpectedToken(scanner()->current_token()); |
124 } else { | 124 } else { |
125 DCHECK_EQ(Token::RBRACE, scanner()->peek()); | 125 DCHECK_EQ(Token::RBRACE, scanner()->peek()); |
126 if (scope_->strict_mode() == STRICT) { | 126 if (is_strict(scope_->language_mode())) { |
127 int end_pos = scanner()->location().end_pos; | 127 int end_pos = scanner()->location().end_pos; |
128 CheckStrictOctalLiteral(start_position, end_pos, &ok); | 128 CheckStrictOctalLiteral(start_position, end_pos, &ok); |
129 } | 129 } |
130 } | 130 } |
131 return kPreParseSuccess; | 131 return kPreParseSuccess; |
132 } | 132 } |
133 | 133 |
134 | 134 |
135 PreParserExpression PreParserTraits::ParseClassLiteral( | 135 PreParserExpression PreParserTraits::ParseClassLiteral( |
136 PreParserIdentifier name, Scanner::Location class_name_location, | 136 PreParserIdentifier name, Scanner::Location class_name_location, |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
181 | 181 |
182 switch (peek()) { | 182 switch (peek()) { |
183 case Token::FUNCTION: | 183 case Token::FUNCTION: |
184 return ParseFunctionDeclaration(ok); | 184 return ParseFunctionDeclaration(ok); |
185 case Token::CLASS: | 185 case Token::CLASS: |
186 return ParseClassDeclaration(ok); | 186 return ParseClassDeclaration(ok); |
187 case Token::CONST: | 187 case Token::CONST: |
188 return ParseVariableStatement(kSourceElement, ok); | 188 return ParseVariableStatement(kSourceElement, ok); |
189 case Token::LET: | 189 case Token::LET: |
190 DCHECK(allow_harmony_scoping()); | 190 DCHECK(allow_harmony_scoping()); |
191 if (strict_mode() == STRICT) { | 191 if (is_strict(language_mode())) { |
192 return ParseVariableStatement(kSourceElement, ok); | 192 return ParseVariableStatement(kSourceElement, ok); |
193 } | 193 } |
194 // Fall through. | 194 // Fall through. |
195 default: | 195 default: |
196 return ParseStatement(ok); | 196 return ParseStatement(ok); |
197 } | 197 } |
198 } | 198 } |
199 | 199 |
200 | 200 |
201 PreParser::SourceElements PreParser::ParseSourceElements(int end_token, | 201 PreParser::SourceElements PreParser::ParseSourceElements(int end_token, |
202 bool* ok) { | 202 bool* ok) { |
203 // SourceElements :: | 203 // SourceElements :: |
204 // (Statement)* <end_token> | 204 // (Statement)* <end_token> |
205 | 205 |
206 bool directive_prologue = true; | 206 bool directive_prologue = true; |
207 while (peek() != end_token) { | 207 while (peek() != end_token) { |
208 if (directive_prologue && peek() != Token::STRING) { | 208 if (directive_prologue && peek() != Token::STRING) { |
209 directive_prologue = false; | 209 directive_prologue = false; |
210 } | 210 } |
211 Statement statement = ParseSourceElement(CHECK_OK); | 211 Statement statement = ParseSourceElement(CHECK_OK); |
212 if (directive_prologue) { | 212 if (directive_prologue) { |
213 if (statement.IsUseStrictLiteral()) { | 213 if (statement.IsUseStrictLiteral()) { |
214 scope_->SetStrictMode(STRICT); | 214 scope_->SetLanguageMode( |
| 215 static_cast<LanguageMode>(scope_->language_mode() | STRICT)); |
215 } else if (!statement.IsStringLiteral()) { | 216 } else if (!statement.IsStringLiteral()) { |
216 directive_prologue = false; | 217 directive_prologue = false; |
217 } | 218 } |
218 } | 219 } |
219 } | 220 } |
220 return kUnknownSourceElements; | 221 return kUnknownSourceElements; |
221 } | 222 } |
222 | 223 |
223 | 224 |
224 #undef CHECK_OK | 225 #undef CHECK_OK |
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
293 case Token::THROW: | 294 case Token::THROW: |
294 return ParseThrowStatement(ok); | 295 return ParseThrowStatement(ok); |
295 | 296 |
296 case Token::TRY: | 297 case Token::TRY: |
297 return ParseTryStatement(ok); | 298 return ParseTryStatement(ok); |
298 | 299 |
299 case Token::FUNCTION: { | 300 case Token::FUNCTION: { |
300 Scanner::Location start_location = scanner()->peek_location(); | 301 Scanner::Location start_location = scanner()->peek_location(); |
301 Statement statement = ParseFunctionDeclaration(CHECK_OK); | 302 Statement statement = ParseFunctionDeclaration(CHECK_OK); |
302 Scanner::Location end_location = scanner()->location(); | 303 Scanner::Location end_location = scanner()->location(); |
303 if (strict_mode() == STRICT) { | 304 if (is_strict(language_mode())) { |
304 PreParserTraits::ReportMessageAt(start_location.beg_pos, | 305 PreParserTraits::ReportMessageAt(start_location.beg_pos, |
305 end_location.end_pos, | 306 end_location.end_pos, |
306 "strict_function"); | 307 "strict_function"); |
307 *ok = false; | 308 *ok = false; |
308 return Statement::Default(); | 309 return Statement::Default(); |
309 } else { | 310 } else { |
310 return statement; | 311 return statement; |
311 } | 312 } |
312 } | 313 } |
313 | 314 |
314 case Token::DEBUGGER: | 315 case Token::DEBUGGER: |
315 return ParseDebuggerStatement(ok); | 316 return ParseDebuggerStatement(ok); |
316 | 317 |
317 case Token::VAR: | 318 case Token::VAR: |
318 return ParseVariableStatement(kStatement, ok); | 319 return ParseVariableStatement(kStatement, ok); |
319 | 320 |
320 case Token::CONST: | 321 case Token::CONST: |
321 // In ES6 CONST is not allowed as a Statement, only as a | 322 // In ES6 CONST is not allowed as a Statement, only as a |
322 // LexicalDeclaration, however we continue to allow it in sloppy mode for | 323 // LexicalDeclaration, however we continue to allow it in sloppy mode for |
323 // backwards compatibility. | 324 // backwards compatibility. |
324 if (strict_mode() == SLOPPY) { | 325 if (is_sloppy(language_mode())) { |
325 return ParseVariableStatement(kStatement, ok); | 326 return ParseVariableStatement(kStatement, ok); |
326 } | 327 } |
327 | 328 |
328 // Fall through. | 329 // Fall through. |
329 default: | 330 default: |
330 return ParseExpressionOrLabelledStatement(ok); | 331 return ParseExpressionOrLabelledStatement(ok); |
331 } | 332 } |
332 } | 333 } |
333 | 334 |
334 | 335 |
(...skipping 13 matching lines...) Expand all Loading... |
348 is_generator ? FunctionKind::kGeneratorFunction | 349 is_generator ? FunctionKind::kGeneratorFunction |
349 : FunctionKind::kNormalFunction, | 350 : FunctionKind::kNormalFunction, |
350 pos, FunctionLiteral::DECLARATION, | 351 pos, FunctionLiteral::DECLARATION, |
351 FunctionLiteral::NORMAL_ARITY, CHECK_OK); | 352 FunctionLiteral::NORMAL_ARITY, CHECK_OK); |
352 return Statement::FunctionDeclaration(); | 353 return Statement::FunctionDeclaration(); |
353 } | 354 } |
354 | 355 |
355 | 356 |
356 PreParser::Statement PreParser::ParseClassDeclaration(bool* ok) { | 357 PreParser::Statement PreParser::ParseClassDeclaration(bool* ok) { |
357 Expect(Token::CLASS, CHECK_OK); | 358 Expect(Token::CLASS, CHECK_OK); |
358 if (!allow_harmony_sloppy() && strict_mode() == SLOPPY) { | 359 if (!allow_harmony_sloppy() && is_sloppy(language_mode())) { |
359 ReportMessage("sloppy_lexical"); | 360 ReportMessage("sloppy_lexical"); |
360 *ok = false; | 361 *ok = false; |
361 return Statement::Default(); | 362 return Statement::Default(); |
362 } | 363 } |
363 | 364 |
364 int pos = position(); | 365 int pos = position(); |
365 bool is_strict_reserved = false; | 366 bool is_strict_reserved = false; |
366 Identifier name = | 367 Identifier name = |
367 ParseIdentifierOrStrictReservedWord(&is_strict_reserved, CHECK_OK); | 368 ParseIdentifierOrStrictReservedWord(&is_strict_reserved, CHECK_OK); |
368 ParseClassLiteral(name, scanner()->location(), is_strict_reserved, pos, | 369 ParseClassLiteral(name, scanner()->location(), is_strict_reserved, pos, |
369 CHECK_OK); | 370 CHECK_OK); |
370 return Statement::Default(); | 371 return Statement::Default(); |
371 } | 372 } |
372 | 373 |
373 | 374 |
374 PreParser::Statement PreParser::ParseBlock(bool* ok) { | 375 PreParser::Statement PreParser::ParseBlock(bool* ok) { |
375 // Block :: | 376 // Block :: |
376 // '{' Statement* '}' | 377 // '{' Statement* '}' |
377 | 378 |
378 // Note that a Block does not introduce a new execution scope! | 379 // Note that a Block does not introduce a new execution scope! |
379 // (ECMA-262, 3rd, 12.2) | 380 // (ECMA-262, 3rd, 12.2) |
380 // | 381 // |
381 Expect(Token::LBRACE, CHECK_OK); | 382 Expect(Token::LBRACE, CHECK_OK); |
382 while (peek() != Token::RBRACE) { | 383 while (peek() != Token::RBRACE) { |
383 if (allow_harmony_scoping() && strict_mode() == STRICT) { | 384 if (allow_harmony_scoping() && is_strict(language_mode())) { |
384 ParseSourceElement(CHECK_OK); | 385 ParseSourceElement(CHECK_OK); |
385 } else { | 386 } else { |
386 ParseStatement(CHECK_OK); | 387 ParseStatement(CHECK_OK); |
387 } | 388 } |
388 } | 389 } |
389 Expect(Token::RBRACE, ok); | 390 Expect(Token::RBRACE, ok); |
390 return Statement::Default(); | 391 return Statement::Default(); |
391 } | 392 } |
392 | 393 |
393 | 394 |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
438 // | 439 // |
439 // ConstDeclaration : const ConstBinding (',' ConstBinding)* ';' | 440 // ConstDeclaration : const ConstBinding (',' ConstBinding)* ';' |
440 // | 441 // |
441 // * It is a Syntax Error if the code that matches this production is not | 442 // * It is a Syntax Error if the code that matches this production is not |
442 // contained in extended code. | 443 // contained in extended code. |
443 // | 444 // |
444 // However disallowing const in sloppy mode will break compatibility with | 445 // However disallowing const in sloppy mode will break compatibility with |
445 // existing pages. Therefore we keep allowing const with the old | 446 // existing pages. Therefore we keep allowing const with the old |
446 // non-harmony semantics in sloppy mode. | 447 // non-harmony semantics in sloppy mode. |
447 Consume(Token::CONST); | 448 Consume(Token::CONST); |
448 if (strict_mode() == STRICT) { | 449 if (is_strict(language_mode())) { |
449 DCHECK(var_context != kStatement); | 450 DCHECK(var_context != kStatement); |
450 if (!allow_harmony_scoping()) { | 451 if (!allow_harmony_scoping()) { |
451 Scanner::Location location = scanner()->peek_location(); | 452 Scanner::Location location = scanner()->peek_location(); |
452 ReportMessageAt(location, "strict_const"); | 453 ReportMessageAt(location, "strict_const"); |
453 *ok = false; | 454 *ok = false; |
454 return Statement::Default(); | 455 return Statement::Default(); |
455 } | 456 } |
456 is_strict_const = true; | 457 is_strict_const = true; |
457 require_initializer = var_context != kForStatement; | 458 require_initializer = var_context != kForStatement; |
458 } | 459 } |
459 } else if (peek() == Token::LET && strict_mode() == STRICT) { | 460 } else if (peek() == Token::LET && is_strict(language_mode())) { |
460 Consume(Token::LET); | 461 Consume(Token::LET); |
461 DCHECK(var_context != kStatement); | 462 DCHECK(var_context != kStatement); |
462 } else { | 463 } else { |
463 *ok = false; | 464 *ok = false; |
464 return Statement::Default(); | 465 return Statement::Default(); |
465 } | 466 } |
466 | 467 |
467 // The scope of a var/const declared variable anywhere inside a function | 468 // The scope of a var/const declared variable anywhere inside a function |
468 // is the entire function (ECMA-262, 3rd, 10.1.3, and 12.2). The scope | 469 // is the entire function (ECMA-262, 3rd, 10.1.3, and 12.2). The scope |
469 // of a let declared variable is the scope of the immediately enclosing | 470 // of a let declared variable is the scope of the immediately enclosing |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
511 | 512 |
512 bool starts_with_identifier = peek_any_identifier(); | 513 bool starts_with_identifier = peek_any_identifier(); |
513 Expression expr = ParseExpression(true, CHECK_OK); | 514 Expression expr = ParseExpression(true, CHECK_OK); |
514 // Even if the expression starts with an identifier, it is not necessarily an | 515 // Even if the expression starts with an identifier, it is not necessarily an |
515 // identifier. For example, "foo + bar" starts with an identifier but is not | 516 // identifier. For example, "foo + bar" starts with an identifier but is not |
516 // an identifier. | 517 // an identifier. |
517 if (starts_with_identifier && expr.IsIdentifier() && peek() == Token::COLON) { | 518 if (starts_with_identifier && expr.IsIdentifier() && peek() == Token::COLON) { |
518 // Expression is a single identifier, and not, e.g., a parenthesized | 519 // Expression is a single identifier, and not, e.g., a parenthesized |
519 // identifier. | 520 // identifier. |
520 DCHECK(!expr.AsIdentifier().IsFutureReserved()); | 521 DCHECK(!expr.AsIdentifier().IsFutureReserved()); |
521 DCHECK(strict_mode() == SLOPPY || | 522 DCHECK(is_sloppy(language_mode()) || |
522 !IsFutureStrictReserved(expr.AsIdentifier())); | 523 !IsFutureStrictReserved(expr.AsIdentifier())); |
523 Consume(Token::COLON); | 524 Consume(Token::COLON); |
524 return ParseStatement(ok); | 525 return ParseStatement(ok); |
525 // Preparsing is disabled for extensions (because the extension details | 526 // Preparsing is disabled for extensions (because the extension details |
526 // aren't passed to lazily compiled functions), so we don't | 527 // aren't passed to lazily compiled functions), so we don't |
527 // accept "native function" in the preparser. | 528 // accept "native function" in the preparser. |
528 } | 529 } |
529 // Parsed expression statement. | 530 // Parsed expression statement. |
530 // Detect attempts at 'let' declarations in sloppy mode. | 531 // Detect attempts at 'let' declarations in sloppy mode. |
531 if (peek() == Token::IDENTIFIER && strict_mode() == SLOPPY && | 532 if (peek() == Token::IDENTIFIER && is_sloppy(language_mode()) && |
532 expr.IsIdentifier() && expr.AsIdentifier().IsLet()) { | 533 expr.IsIdentifier() && expr.AsIdentifier().IsLet()) { |
533 ReportMessage("sloppy_lexical", NULL); | 534 ReportMessage("sloppy_lexical", NULL); |
534 *ok = false; | 535 *ok = false; |
535 return Statement::Default(); | 536 return Statement::Default(); |
536 } | 537 } |
537 ExpectSemicolon(CHECK_OK); | 538 ExpectSemicolon(CHECK_OK); |
538 return Statement::ExpressionStatement(expr); | 539 return Statement::ExpressionStatement(expr); |
539 } | 540 } |
540 | 541 |
541 | 542 |
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
615 } | 616 } |
616 ExpectSemicolon(CHECK_OK); | 617 ExpectSemicolon(CHECK_OK); |
617 return Statement::Default(); | 618 return Statement::Default(); |
618 } | 619 } |
619 | 620 |
620 | 621 |
621 PreParser::Statement PreParser::ParseWithStatement(bool* ok) { | 622 PreParser::Statement PreParser::ParseWithStatement(bool* ok) { |
622 // WithStatement :: | 623 // WithStatement :: |
623 // 'with' '(' Expression ')' Statement | 624 // 'with' '(' Expression ')' Statement |
624 Expect(Token::WITH, CHECK_OK); | 625 Expect(Token::WITH, CHECK_OK); |
625 if (strict_mode() == STRICT) { | 626 if (is_strict(language_mode())) { |
626 ReportMessageAt(scanner()->location(), "strict_mode_with"); | 627 ReportMessageAt(scanner()->location(), "strict_mode_with"); |
627 *ok = false; | 628 *ok = false; |
628 return Statement::Default(); | 629 return Statement::Default(); |
629 } | 630 } |
630 Expect(Token::LPAREN, CHECK_OK); | 631 Expect(Token::LPAREN, CHECK_OK); |
631 ParseExpression(true, CHECK_OK); | 632 ParseExpression(true, CHECK_OK); |
632 Expect(Token::RPAREN, CHECK_OK); | 633 Expect(Token::RPAREN, CHECK_OK); |
633 | 634 |
634 PreParserScope with_scope(scope_, WITH_SCOPE); | 635 PreParserScope with_scope(scope_, WITH_SCOPE); |
635 BlockState block_state(&scope_, &with_scope); | 636 BlockState block_state(&scope_, &with_scope); |
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
709 | 710 |
710 PreParser::Statement PreParser::ParseForStatement(bool* ok) { | 711 PreParser::Statement PreParser::ParseForStatement(bool* ok) { |
711 // ForStatement :: | 712 // ForStatement :: |
712 // 'for' '(' Expression? ';' Expression? ';' Expression? ')' Statement | 713 // 'for' '(' Expression? ';' Expression? ';' Expression? ')' Statement |
713 | 714 |
714 Expect(Token::FOR, CHECK_OK); | 715 Expect(Token::FOR, CHECK_OK); |
715 Expect(Token::LPAREN, CHECK_OK); | 716 Expect(Token::LPAREN, CHECK_OK); |
716 bool is_let_identifier_expression = false; | 717 bool is_let_identifier_expression = false; |
717 if (peek() != Token::SEMICOLON) { | 718 if (peek() != Token::SEMICOLON) { |
718 if (peek() == Token::VAR || peek() == Token::CONST || | 719 if (peek() == Token::VAR || peek() == Token::CONST || |
719 (peek() == Token::LET && strict_mode() == STRICT)) { | 720 (peek() == Token::LET && is_strict(language_mode()))) { |
720 bool is_lexical = peek() == Token::LET || | 721 bool is_lexical = peek() == Token::LET || |
721 (peek() == Token::CONST && strict_mode() == STRICT); | 722 (peek() == Token::CONST && is_strict(language_mode())); |
722 int decl_count; | 723 int decl_count; |
723 VariableDeclarationProperties decl_props = kHasNoInitializers; | 724 VariableDeclarationProperties decl_props = kHasNoInitializers; |
724 ParseVariableDeclarations( | 725 ParseVariableDeclarations( |
725 kForStatement, &decl_props, &decl_count, CHECK_OK); | 726 kForStatement, &decl_props, &decl_count, CHECK_OK); |
726 bool has_initializers = decl_props == kHasInitializers; | 727 bool has_initializers = decl_props == kHasInitializers; |
727 bool accept_IN = decl_count == 1 && !(is_lexical && has_initializers); | 728 bool accept_IN = decl_count == 1 && !(is_lexical && has_initializers); |
728 bool accept_OF = !has_initializers; | 729 bool accept_OF = !has_initializers; |
729 if (accept_IN && CheckInOrOf(accept_OF)) { | 730 if (accept_IN && CheckInOrOf(accept_OF)) { |
730 ParseExpression(true, CHECK_OK); | 731 ParseExpression(true, CHECK_OK); |
731 Expect(Token::RPAREN, CHECK_OK); | 732 Expect(Token::RPAREN, CHECK_OK); |
(...skipping 10 matching lines...) Expand all Loading... |
742 Expect(Token::RPAREN, CHECK_OK); | 743 Expect(Token::RPAREN, CHECK_OK); |
743 | 744 |
744 ParseStatement(CHECK_OK); | 745 ParseStatement(CHECK_OK); |
745 return Statement::Default(); | 746 return Statement::Default(); |
746 } | 747 } |
747 } | 748 } |
748 } | 749 } |
749 | 750 |
750 // Parsed initializer at this point. | 751 // Parsed initializer at this point. |
751 // Detect attempts at 'let' declarations in sloppy mode. | 752 // Detect attempts at 'let' declarations in sloppy mode. |
752 if (peek() == Token::IDENTIFIER && strict_mode() == SLOPPY && | 753 if (peek() == Token::IDENTIFIER && is_sloppy(language_mode()) && |
753 is_let_identifier_expression) { | 754 is_let_identifier_expression) { |
754 ReportMessage("sloppy_lexical", NULL); | 755 ReportMessage("sloppy_lexical", NULL); |
755 *ok = false; | 756 *ok = false; |
756 return Statement::Default(); | 757 return Statement::Default(); |
757 } | 758 } |
758 Expect(Token::SEMICOLON, CHECK_OK); | 759 Expect(Token::SEMICOLON, CHECK_OK); |
759 | 760 |
760 if (peek() != Token::SEMICOLON) { | 761 if (peek() != Token::SEMICOLON) { |
761 ParseExpression(true, CHECK_OK); | 762 ParseExpression(true, CHECK_OK); |
762 } | 763 } |
(...skipping 164 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
927 if (is_lazily_parsed) { | 928 if (is_lazily_parsed) { |
928 ParseLazyFunctionLiteralBody(CHECK_OK); | 929 ParseLazyFunctionLiteralBody(CHECK_OK); |
929 } else { | 930 } else { |
930 ParseSourceElements(Token::RBRACE, ok); | 931 ParseSourceElements(Token::RBRACE, ok); |
931 } | 932 } |
932 Expect(Token::RBRACE, CHECK_OK); | 933 Expect(Token::RBRACE, CHECK_OK); |
933 | 934 |
934 // Validate strict mode. We can do this only after parsing the function, | 935 // Validate strict mode. We can do this only after parsing the function, |
935 // since the function can declare itself strict. | 936 // since the function can declare itself strict. |
936 // Concise methods use StrictFormalParameters. | 937 // Concise methods use StrictFormalParameters. |
937 if (strict_mode() == STRICT || IsConciseMethod(kind) || is_rest) { | 938 if (is_strict(language_mode()) || IsConciseMethod(kind) || is_rest) { |
938 if (function_name.IsEvalOrArguments()) { | 939 if (function_name.IsEvalOrArguments()) { |
939 ReportMessageAt(function_name_location, "strict_eval_arguments"); | 940 ReportMessageAt(function_name_location, "strict_eval_arguments"); |
940 *ok = false; | 941 *ok = false; |
941 return Expression::Default(); | 942 return Expression::Default(); |
942 } | 943 } |
943 if (name_is_strict_reserved) { | 944 if (name_is_strict_reserved) { |
944 ReportMessageAt(function_name_location, "unexpected_strict_reserved"); | 945 ReportMessageAt(function_name_location, "unexpected_strict_reserved"); |
945 *ok = false; | 946 *ok = false; |
946 return Expression::Default(); | 947 return Expression::Default(); |
947 } | 948 } |
(...skipping 22 matching lines...) Expand all Loading... |
970 | 971 |
971 | 972 |
972 void PreParser::ParseLazyFunctionLiteralBody(bool* ok) { | 973 void PreParser::ParseLazyFunctionLiteralBody(bool* ok) { |
973 int body_start = position(); | 974 int body_start = position(); |
974 ParseSourceElements(Token::RBRACE, ok); | 975 ParseSourceElements(Token::RBRACE, ok); |
975 if (!*ok) return; | 976 if (!*ok) return; |
976 | 977 |
977 // Position right after terminal '}'. | 978 // Position right after terminal '}'. |
978 DCHECK_EQ(Token::RBRACE, scanner()->peek()); | 979 DCHECK_EQ(Token::RBRACE, scanner()->peek()); |
979 int body_end = scanner()->peek_location().end_pos; | 980 int body_end = scanner()->peek_location().end_pos; |
980 log_->LogFunction(body_start, body_end, | 981 log_->LogFunction( |
981 function_state_->materialized_literal_count(), | 982 body_start, body_end, function_state_->materialized_literal_count(), |
982 function_state_->expected_property_count(), | 983 function_state_->expected_property_count(), language_mode()); |
983 strict_mode()); | |
984 } | 984 } |
985 | 985 |
986 | 986 |
987 PreParserExpression PreParser::ParseClassLiteral( | 987 PreParserExpression PreParser::ParseClassLiteral( |
988 PreParserIdentifier name, Scanner::Location class_name_location, | 988 PreParserIdentifier name, Scanner::Location class_name_location, |
989 bool name_is_strict_reserved, int pos, bool* ok) { | 989 bool name_is_strict_reserved, int pos, bool* ok) { |
990 // All parts of a ClassDeclaration and ClassExpression are strict code. | 990 // All parts of a ClassDeclaration and ClassExpression are strict code. |
991 if (name_is_strict_reserved) { | 991 if (name_is_strict_reserved) { |
992 ReportMessageAt(class_name_location, "unexpected_strict_reserved"); | 992 ReportMessageAt(class_name_location, "unexpected_strict_reserved"); |
993 *ok = false; | 993 *ok = false; |
994 return EmptyExpression(); | 994 return EmptyExpression(); |
995 } | 995 } |
996 if (IsEvalOrArguments(name)) { | 996 if (IsEvalOrArguments(name)) { |
997 ReportMessageAt(class_name_location, "strict_eval_arguments"); | 997 ReportMessageAt(class_name_location, "strict_eval_arguments"); |
998 *ok = false; | 998 *ok = false; |
999 return EmptyExpression(); | 999 return EmptyExpression(); |
1000 } | 1000 } |
1001 | 1001 |
1002 PreParserScope scope = NewScope(scope_, BLOCK_SCOPE); | 1002 PreParserScope scope = NewScope(scope_, BLOCK_SCOPE); |
1003 BlockState block_state(&scope_, &scope); | 1003 BlockState block_state(&scope_, &scope); |
1004 scope_->SetStrictMode(STRICT); | 1004 scope_->SetLanguageMode( |
| 1005 static_cast<LanguageMode>(scope_->language_mode() | STRICT)); |
1005 scope_->SetScopeName(name); | 1006 scope_->SetScopeName(name); |
1006 | 1007 |
1007 bool has_extends = Check(Token::EXTENDS); | 1008 bool has_extends = Check(Token::EXTENDS); |
1008 if (has_extends) { | 1009 if (has_extends) { |
1009 ParseLeftHandSideExpression(CHECK_OK); | 1010 ParseLeftHandSideExpression(CHECK_OK); |
1010 } | 1011 } |
1011 | 1012 |
1012 ClassLiteralChecker checker(this); | 1013 ClassLiteralChecker checker(this); |
1013 bool has_seen_constructor = false; | 1014 bool has_seen_constructor = false; |
1014 | 1015 |
(...skipping 26 matching lines...) Expand all Loading... |
1041 ParseIdentifier(kAllowEvalOrArguments, CHECK_OK); | 1042 ParseIdentifier(kAllowEvalOrArguments, CHECK_OK); |
1042 ParseArguments(ok); | 1043 ParseArguments(ok); |
1043 | 1044 |
1044 return Expression::Default(); | 1045 return Expression::Default(); |
1045 } | 1046 } |
1046 | 1047 |
1047 #undef CHECK_OK | 1048 #undef CHECK_OK |
1048 | 1049 |
1049 | 1050 |
1050 } } // v8::internal | 1051 } } // v8::internal |
OLD | NEW |