OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 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 662 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
673 body, | 673 body, |
674 function_state.materialized_literal_count(), | 674 function_state.materialized_literal_count(), |
675 function_state.expected_property_count(), | 675 function_state.expected_property_count(), |
676 function_state.handler_count(), | 676 function_state.handler_count(), |
677 function_state.only_simple_this_property_assignments(), | 677 function_state.only_simple_this_property_assignments(), |
678 function_state.this_property_assignments(), | 678 function_state.this_property_assignments(), |
679 0, | 679 0, |
680 FunctionLiteral::kNoDuplicateParameters, | 680 FunctionLiteral::kNoDuplicateParameters, |
681 FunctionLiteral::ANONYMOUS_EXPRESSION, | 681 FunctionLiteral::ANONYMOUS_EXPRESSION, |
682 FunctionLiteral::kGlobalOrEval, | 682 FunctionLiteral::kGlobalOrEval, |
683 FunctionLiteral::kNotParenthesized); | 683 FunctionLiteral::kNotParenthesized, |
| 684 FunctionLiteral::kNotGenerator); |
684 result->set_ast_properties(factory()->visitor()->ast_properties()); | 685 result->set_ast_properties(factory()->visitor()->ast_properties()); |
685 } else if (stack_overflow_) { | 686 } else if (stack_overflow_) { |
686 isolate()->StackOverflow(); | 687 isolate()->StackOverflow(); |
687 } | 688 } |
688 } | 689 } |
689 | 690 |
690 // Make sure the target stack is empty. | 691 // Make sure the target stack is empty. |
691 ASSERT(target_stack_ == NULL); | 692 ASSERT(target_stack_ == NULL); |
692 | 693 |
693 // If there was a syntax error we have to get rid of the AST | 694 // If there was a syntax error we have to get rid of the AST |
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
761 ASSERT(info()->language_mode() == shared_info->language_mode()); | 762 ASSERT(info()->language_mode() == shared_info->language_mode()); |
762 scope->SetLanguageMode(shared_info->language_mode()); | 763 scope->SetLanguageMode(shared_info->language_mode()); |
763 FunctionLiteral::Type type = shared_info->is_expression() | 764 FunctionLiteral::Type type = shared_info->is_expression() |
764 ? (shared_info->is_anonymous() | 765 ? (shared_info->is_anonymous() |
765 ? FunctionLiteral::ANONYMOUS_EXPRESSION | 766 ? FunctionLiteral::ANONYMOUS_EXPRESSION |
766 : FunctionLiteral::NAMED_EXPRESSION) | 767 : FunctionLiteral::NAMED_EXPRESSION) |
767 : FunctionLiteral::DECLARATION; | 768 : FunctionLiteral::DECLARATION; |
768 bool ok = true; | 769 bool ok = true; |
769 result = ParseFunctionLiteral(name, | 770 result = ParseFunctionLiteral(name, |
770 false, // Strict mode name already checked. | 771 false, // Strict mode name already checked. |
| 772 shared_info->is_generator(), |
771 RelocInfo::kNoPosition, | 773 RelocInfo::kNoPosition, |
772 type, | 774 type, |
773 &ok); | 775 &ok); |
774 // Make sure the results agree. | 776 // Make sure the results agree. |
775 ASSERT(ok == (result != NULL)); | 777 ASSERT(ok == (result != NULL)); |
776 } | 778 } |
777 | 779 |
778 // Make sure the target stack is empty. | 780 // Make sure the target stack is empty. |
779 ASSERT(target_stack_ == NULL); | 781 ASSERT(target_stack_ == NULL); |
780 | 782 |
(...skipping 344 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1125 // Statement | 1127 // Statement |
1126 // FunctionDeclaration | 1128 // FunctionDeclaration |
1127 // | 1129 // |
1128 // In harmony mode we allow additionally the following productions | 1130 // In harmony mode we allow additionally the following productions |
1129 // ModuleElement: | 1131 // ModuleElement: |
1130 // LetDeclaration | 1132 // LetDeclaration |
1131 // ConstDeclaration | 1133 // ConstDeclaration |
1132 // ModuleDeclaration | 1134 // ModuleDeclaration |
1133 // ImportDeclaration | 1135 // ImportDeclaration |
1134 // ExportDeclaration | 1136 // ExportDeclaration |
| 1137 // GeneratorDeclaration |
1135 | 1138 |
1136 switch (peek()) { | 1139 switch (peek()) { |
1137 case Token::FUNCTION: | 1140 case Token::FUNCTION: |
1138 return ParseFunctionDeclaration(NULL, ok); | 1141 return ParseFunctionDeclaration(NULL, ok); |
1139 case Token::LET: | 1142 case Token::LET: |
1140 case Token::CONST: | 1143 case Token::CONST: |
1141 return ParseVariableStatement(kModuleElement, NULL, ok); | 1144 return ParseVariableStatement(kModuleElement, NULL, ok); |
1142 case Token::IMPORT: | 1145 case Token::IMPORT: |
1143 return ParseImportDeclaration(ok); | 1146 return ParseImportDeclaration(ok); |
1144 case Token::EXPORT: | 1147 case Token::EXPORT: |
(...skipping 278 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1423 | 1426 |
1424 return block; | 1427 return block; |
1425 } | 1428 } |
1426 | 1429 |
1427 | 1430 |
1428 Statement* Parser::ParseExportDeclaration(bool* ok) { | 1431 Statement* Parser::ParseExportDeclaration(bool* ok) { |
1429 // ExportDeclaration: | 1432 // ExportDeclaration: |
1430 // 'export' Identifier (',' Identifier)* ';' | 1433 // 'export' Identifier (',' Identifier)* ';' |
1431 // 'export' VariableDeclaration | 1434 // 'export' VariableDeclaration |
1432 // 'export' FunctionDeclaration | 1435 // 'export' FunctionDeclaration |
| 1436 // 'export' GeneratorDeclaration |
1433 // 'export' ModuleDeclaration | 1437 // 'export' ModuleDeclaration |
1434 // | 1438 // |
1435 // TODO(ES6): implement structuring ExportSpecifiers | 1439 // TODO(ES6): implement structuring ExportSpecifiers |
1436 | 1440 |
1437 Expect(Token::EXPORT, CHECK_OK); | 1441 Expect(Token::EXPORT, CHECK_OK); |
1438 | 1442 |
1439 Statement* result = NULL; | 1443 Statement* result = NULL; |
1440 ZoneStringList names(1, zone()); | 1444 ZoneStringList names(1, zone()); |
1441 switch (peek()) { | 1445 switch (peek()) { |
1442 case Token::IDENTIFIER: { | 1446 case Token::IDENTIFIER: { |
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1502 bool* ok) { | 1506 bool* ok) { |
1503 // (Ecma 262 5th Edition, clause 14): | 1507 // (Ecma 262 5th Edition, clause 14): |
1504 // SourceElement: | 1508 // SourceElement: |
1505 // Statement | 1509 // Statement |
1506 // FunctionDeclaration | 1510 // FunctionDeclaration |
1507 // | 1511 // |
1508 // In harmony mode we allow additionally the following productions | 1512 // In harmony mode we allow additionally the following productions |
1509 // BlockElement (aka SourceElement): | 1513 // BlockElement (aka SourceElement): |
1510 // LetDeclaration | 1514 // LetDeclaration |
1511 // ConstDeclaration | 1515 // ConstDeclaration |
| 1516 // GeneratorDeclaration |
1512 | 1517 |
1513 switch (peek()) { | 1518 switch (peek()) { |
1514 case Token::FUNCTION: | 1519 case Token::FUNCTION: |
1515 return ParseFunctionDeclaration(NULL, ok); | 1520 return ParseFunctionDeclaration(NULL, ok); |
1516 case Token::LET: | 1521 case Token::LET: |
1517 case Token::CONST: | 1522 case Token::CONST: |
1518 return ParseVariableStatement(kModuleElement, NULL, ok); | 1523 return ParseVariableStatement(kModuleElement, NULL, ok); |
1519 default: | 1524 default: |
1520 return ParseStatement(labels, ok); | 1525 return ParseStatement(labels, ok); |
1521 } | 1526 } |
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1621 } | 1626 } |
1622 | 1627 |
1623 case Token::FUNCTION: { | 1628 case Token::FUNCTION: { |
1624 // FunctionDeclaration is only allowed in the context of SourceElements | 1629 // FunctionDeclaration is only allowed in the context of SourceElements |
1625 // (Ecma 262 5th Edition, clause 14): | 1630 // (Ecma 262 5th Edition, clause 14): |
1626 // SourceElement: | 1631 // SourceElement: |
1627 // Statement | 1632 // Statement |
1628 // FunctionDeclaration | 1633 // FunctionDeclaration |
1629 // Common language extension is to allow function declaration in place | 1634 // Common language extension is to allow function declaration in place |
1630 // of any statement. This language extension is disabled in strict mode. | 1635 // of any statement. This language extension is disabled in strict mode. |
| 1636 // |
| 1637 // In Harmony mode, this case also handles the extension: |
| 1638 // Statement: |
| 1639 // GeneratorDeclaration |
1631 if (!top_scope_->is_classic_mode()) { | 1640 if (!top_scope_->is_classic_mode()) { |
1632 ReportMessageAt(scanner().peek_location(), "strict_function", | 1641 ReportMessageAt(scanner().peek_location(), "strict_function", |
1633 Vector<const char*>::empty()); | 1642 Vector<const char*>::empty()); |
1634 *ok = false; | 1643 *ok = false; |
1635 return NULL; | 1644 return NULL; |
1636 } | 1645 } |
1637 return ParseFunctionDeclaration(NULL, ok); | 1646 return ParseFunctionDeclaration(NULL, ok); |
1638 } | 1647 } |
1639 | 1648 |
1640 case Token::DEBUGGER: | 1649 case Token::DEBUGGER: |
(...skipping 244 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1885 factory()->NewAssignment( | 1894 factory()->NewAssignment( |
1886 Token::INIT_VAR, proxy, lit, RelocInfo::kNoPosition)); | 1895 Token::INIT_VAR, proxy, lit, RelocInfo::kNoPosition)); |
1887 } | 1896 } |
1888 | 1897 |
1889 | 1898 |
1890 Statement* Parser::ParseFunctionDeclaration(ZoneStringList* names, bool* ok) { | 1899 Statement* Parser::ParseFunctionDeclaration(ZoneStringList* names, bool* ok) { |
1891 // FunctionDeclaration :: | 1900 // FunctionDeclaration :: |
1892 // 'function' Identifier '(' FormalParameterListopt ')' '{' FunctionBody '}' | 1901 // 'function' Identifier '(' FormalParameterListopt ')' '{' FunctionBody '}' |
1893 Expect(Token::FUNCTION, CHECK_OK); | 1902 Expect(Token::FUNCTION, CHECK_OK); |
1894 int function_token_position = scanner().location().beg_pos; | 1903 int function_token_position = scanner().location().beg_pos; |
| 1904 bool is_generator = FLAG_harmony_generators && Check(Token::MUL); |
1895 bool is_strict_reserved = false; | 1905 bool is_strict_reserved = false; |
1896 Handle<String> name = ParseIdentifierOrStrictReservedWord( | 1906 Handle<String> name = ParseIdentifierOrStrictReservedWord( |
1897 &is_strict_reserved, CHECK_OK); | 1907 &is_strict_reserved, CHECK_OK); |
1898 FunctionLiteral* fun = ParseFunctionLiteral(name, | 1908 FunctionLiteral* fun = ParseFunctionLiteral(name, |
1899 is_strict_reserved, | 1909 is_strict_reserved, |
| 1910 is_generator, |
1900 function_token_position, | 1911 function_token_position, |
1901 FunctionLiteral::DECLARATION, | 1912 FunctionLiteral::DECLARATION, |
1902 CHECK_OK); | 1913 CHECK_OK); |
1903 // Even if we're not at the top-level of the global or a function | 1914 // Even if we're not at the top-level of the global or a function |
1904 // scope, we treat it as such and introduce the function with its | 1915 // scope, we treat it as such and introduce the function with its |
1905 // initial value upon entering the corresponding scope. | 1916 // initial value upon entering the corresponding scope. |
1906 // In extended mode, a function behaves as a lexical binding, except in the | 1917 // In extended mode, a function behaves as a lexical binding, except in the |
1907 // global scope. | 1918 // global scope. |
1908 VariableMode mode = | 1919 VariableMode mode = |
1909 is_extended_mode() && !top_scope_->is_global_scope() ? LET : VAR; | 1920 is_extended_mode() && !top_scope_->is_global_scope() ? LET : VAR; |
(...skipping 1087 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2997 factory()->NewBinaryOperation(Token::COMMA, result, right, position); | 3008 factory()->NewBinaryOperation(Token::COMMA, result, right, position); |
2998 } | 3009 } |
2999 return result; | 3010 return result; |
3000 } | 3011 } |
3001 | 3012 |
3002 | 3013 |
3003 // Precedence = 2 | 3014 // Precedence = 2 |
3004 Expression* Parser::ParseAssignmentExpression(bool accept_IN, bool* ok) { | 3015 Expression* Parser::ParseAssignmentExpression(bool accept_IN, bool* ok) { |
3005 // AssignmentExpression :: | 3016 // AssignmentExpression :: |
3006 // ConditionalExpression | 3017 // ConditionalExpression |
| 3018 // YieldExpression |
3007 // LeftHandSideExpression AssignmentOperator AssignmentExpression | 3019 // LeftHandSideExpression AssignmentOperator AssignmentExpression |
3008 | 3020 |
| 3021 if (peek() == Token::YIELD && inside_generator()) { |
| 3022 return ParseYieldExpression(ok); |
| 3023 } |
| 3024 |
3009 if (fni_ != NULL) fni_->Enter(); | 3025 if (fni_ != NULL) fni_->Enter(); |
3010 Expression* expression = ParseConditionalExpression(accept_IN, CHECK_OK); | 3026 Expression* expression = ParseConditionalExpression(accept_IN, CHECK_OK); |
3011 | 3027 |
3012 if (!Token::IsAssignmentOp(peek())) { | 3028 if (!Token::IsAssignmentOp(peek())) { |
3013 if (fni_ != NULL) fni_->Leave(); | 3029 if (fni_ != NULL) fni_->Leave(); |
3014 // Parsed conditional expression only (no assignment). | 3030 // Parsed conditional expression only (no assignment). |
3015 return expression; | 3031 return expression; |
3016 } | 3032 } |
3017 | 3033 |
3018 // Signal a reference error if the expression is an invalid left-hand | 3034 // Signal a reference error if the expression is an invalid left-hand |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3067 } else { | 3083 } else { |
3068 fni_->RemoveLastFunction(); | 3084 fni_->RemoveLastFunction(); |
3069 } | 3085 } |
3070 fni_->Leave(); | 3086 fni_->Leave(); |
3071 } | 3087 } |
3072 | 3088 |
3073 return factory()->NewAssignment(op, expression, right, pos); | 3089 return factory()->NewAssignment(op, expression, right, pos); |
3074 } | 3090 } |
3075 | 3091 |
3076 | 3092 |
| 3093 Expression* Parser::ParseYieldExpression(bool* ok) { |
| 3094 // YieldExpression :: |
| 3095 // 'yield' '*'? AssignmentExpression |
| 3096 int position = scanner().peek_location().beg_pos; |
| 3097 Expect(Token::YIELD, CHECK_OK); |
| 3098 bool is_yield_star = Check(Token::MUL); |
| 3099 Expression* expression = ParseAssignmentExpression(false, CHECK_OK); |
| 3100 return factory()->NewYield(expression, is_yield_star, position); |
| 3101 } |
| 3102 |
| 3103 |
3077 // Precedence = 3 | 3104 // Precedence = 3 |
3078 Expression* Parser::ParseConditionalExpression(bool accept_IN, bool* ok) { | 3105 Expression* Parser::ParseConditionalExpression(bool accept_IN, bool* ok) { |
3079 // ConditionalExpression :: | 3106 // ConditionalExpression :: |
3080 // LogicalOrExpression | 3107 // LogicalOrExpression |
3081 // LogicalOrExpression '?' AssignmentExpression ':' AssignmentExpression | 3108 // LogicalOrExpression '?' AssignmentExpression ':' AssignmentExpression |
3082 | 3109 |
3083 // We start using the binary expression parser for prec >= 4 only! | 3110 // We start using the binary expression parser for prec >= 4 only! |
3084 Expression* expression = ParseBinaryExpression(4, accept_IN, CHECK_OK); | 3111 Expression* expression = ParseBinaryExpression(4, accept_IN, CHECK_OK); |
3085 if (peek() != Token::CONDITIONAL) return expression; | 3112 if (peek() != Token::CONDITIONAL) return expression; |
3086 Consume(Token::CONDITIONAL); | 3113 Consume(Token::CONDITIONAL); |
(...skipping 356 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3443 bool* ok) { | 3470 bool* ok) { |
3444 // MemberExpression :: | 3471 // MemberExpression :: |
3445 // (PrimaryExpression | FunctionLiteral) | 3472 // (PrimaryExpression | FunctionLiteral) |
3446 // ('[' Expression ']' | '.' Identifier | Arguments)* | 3473 // ('[' Expression ']' | '.' Identifier | Arguments)* |
3447 | 3474 |
3448 // Parse the initial primary or function expression. | 3475 // Parse the initial primary or function expression. |
3449 Expression* result = NULL; | 3476 Expression* result = NULL; |
3450 if (peek() == Token::FUNCTION) { | 3477 if (peek() == Token::FUNCTION) { |
3451 Expect(Token::FUNCTION, CHECK_OK); | 3478 Expect(Token::FUNCTION, CHECK_OK); |
3452 int function_token_position = scanner().location().beg_pos; | 3479 int function_token_position = scanner().location().beg_pos; |
| 3480 bool is_generator = FLAG_harmony_generators && Check(Token::MUL); |
3453 Handle<String> name; | 3481 Handle<String> name; |
3454 bool is_strict_reserved_name = false; | 3482 bool is_strict_reserved_name = false; |
3455 if (peek_any_identifier()) { | 3483 if (peek_any_identifier()) { |
3456 name = ParseIdentifierOrStrictReservedWord(&is_strict_reserved_name, | 3484 name = ParseIdentifierOrStrictReservedWord(&is_strict_reserved_name, |
3457 CHECK_OK); | 3485 CHECK_OK); |
3458 } | 3486 } |
3459 FunctionLiteral::Type type = name.is_null() | 3487 FunctionLiteral::Type type = name.is_null() |
3460 ? FunctionLiteral::ANONYMOUS_EXPRESSION | 3488 ? FunctionLiteral::ANONYMOUS_EXPRESSION |
3461 : FunctionLiteral::NAMED_EXPRESSION; | 3489 : FunctionLiteral::NAMED_EXPRESSION; |
3462 result = ParseFunctionLiteral(name, | 3490 result = ParseFunctionLiteral(name, |
3463 is_strict_reserved_name, | 3491 is_strict_reserved_name, |
| 3492 is_generator, |
3464 function_token_position, | 3493 function_token_position, |
3465 type, | 3494 type, |
3466 CHECK_OK); | 3495 CHECK_OK); |
3467 } else { | 3496 } else { |
3468 result = ParsePrimaryExpression(CHECK_OK); | 3497 result = ParsePrimaryExpression(CHECK_OK); |
3469 } | 3498 } |
3470 | 3499 |
3471 while (true) { | 3500 while (true) { |
3472 switch (peek()) { | 3501 switch (peek()) { |
3473 case Token::LBRACK: { | 3502 case Token::LBRACK: { |
(...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3597 Consume(Token::TRUE_LITERAL); | 3626 Consume(Token::TRUE_LITERAL); |
3598 result = factory()->NewLiteral(isolate()->factory()->true_value()); | 3627 result = factory()->NewLiteral(isolate()->factory()->true_value()); |
3599 break; | 3628 break; |
3600 | 3629 |
3601 case Token::FALSE_LITERAL: | 3630 case Token::FALSE_LITERAL: |
3602 Consume(Token::FALSE_LITERAL); | 3631 Consume(Token::FALSE_LITERAL); |
3603 result = factory()->NewLiteral(isolate()->factory()->false_value()); | 3632 result = factory()->NewLiteral(isolate()->factory()->false_value()); |
3604 break; | 3633 break; |
3605 | 3634 |
3606 case Token::IDENTIFIER: | 3635 case Token::IDENTIFIER: |
| 3636 case Token::YIELD: |
3607 case Token::FUTURE_STRICT_RESERVED_WORD: { | 3637 case Token::FUTURE_STRICT_RESERVED_WORD: { |
3608 Handle<String> name = ParseIdentifier(CHECK_OK); | 3638 Handle<String> name = ParseIdentifier(CHECK_OK); |
3609 if (fni_ != NULL) fni_->PushVariableName(name); | 3639 if (fni_ != NULL) fni_->PushVariableName(name); |
3610 // The name may refer to a module instance object, so its type is unknown. | 3640 // The name may refer to a module instance object, so its type is unknown. |
3611 #ifdef DEBUG | 3641 #ifdef DEBUG |
3612 if (FLAG_print_interface_details) | 3642 if (FLAG_print_interface_details) |
3613 PrintF("# Variable %s ", name->ToAsciiArray()); | 3643 PrintF("# Variable %s ", name->ToAsciiArray()); |
3614 #endif | 3644 #endif |
3615 Interface* interface = Interface::NewUnknown(zone()); | 3645 Interface* interface = Interface::NewUnknown(zone()); |
3616 result = top_scope_->NewUnresolved( | 3646 result = top_scope_->NewUnresolved( |
(...skipping 385 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4002 next == Token::STRING || is_keyword) { | 4032 next == Token::STRING || is_keyword) { |
4003 Handle<String> name; | 4033 Handle<String> name; |
4004 if (is_keyword) { | 4034 if (is_keyword) { |
4005 name = isolate_->factory()->InternalizeUtf8String(Token::String(next)); | 4035 name = isolate_->factory()->InternalizeUtf8String(Token::String(next)); |
4006 } else { | 4036 } else { |
4007 name = GetSymbol(CHECK_OK); | 4037 name = GetSymbol(CHECK_OK); |
4008 } | 4038 } |
4009 FunctionLiteral* value = | 4039 FunctionLiteral* value = |
4010 ParseFunctionLiteral(name, | 4040 ParseFunctionLiteral(name, |
4011 false, // reserved words are allowed here | 4041 false, // reserved words are allowed here |
| 4042 false, // not a generator |
4012 RelocInfo::kNoPosition, | 4043 RelocInfo::kNoPosition, |
4013 FunctionLiteral::ANONYMOUS_EXPRESSION, | 4044 FunctionLiteral::ANONYMOUS_EXPRESSION, |
4014 CHECK_OK); | 4045 CHECK_OK); |
4015 // Allow any number of parameters for compatibilty with JSC. | 4046 // Allow any number of parameters for compatibilty with JSC. |
4016 // Specification only allows zero parameters for get and one for set. | 4047 // Specification only allows zero parameters for get and one for set. |
4017 return factory()->NewObjectLiteralProperty(is_getter, value); | 4048 return factory()->NewObjectLiteralProperty(is_getter, value); |
4018 } else { | 4049 } else { |
4019 ReportUnexpectedToken(next); | 4050 ReportUnexpectedToken(next); |
4020 *ok = false; | 4051 *ok = false; |
4021 return NULL; | 4052 return NULL; |
(...skipping 281 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4303 int properties_; | 4334 int properties_; |
4304 LanguageMode mode_; | 4335 LanguageMode mode_; |
4305 // For error messages. | 4336 // For error messages. |
4306 const char* message_; | 4337 const char* message_; |
4307 const char* argument_opt_; | 4338 const char* argument_opt_; |
4308 }; | 4339 }; |
4309 | 4340 |
4310 | 4341 |
4311 FunctionLiteral* Parser::ParseFunctionLiteral(Handle<String> function_name, | 4342 FunctionLiteral* Parser::ParseFunctionLiteral(Handle<String> function_name, |
4312 bool name_is_strict_reserved, | 4343 bool name_is_strict_reserved, |
| 4344 bool is_generator, |
4313 int function_token_position, | 4345 int function_token_position, |
4314 FunctionLiteral::Type type, | 4346 FunctionLiteral::Type type, |
4315 bool* ok) { | 4347 bool* ok) { |
4316 // Function :: | 4348 // Function :: |
4317 // '(' FormalParameterList? ')' '{' FunctionBody '}' | 4349 // '(' FormalParameterList? ')' '{' FunctionBody '}' |
4318 | 4350 |
4319 // Anonymous functions were passed either the empty symbol or a null | 4351 // Anonymous functions were passed either the empty symbol or a null |
4320 // handle as the function name. Remember if we were passed a non-empty | 4352 // handle as the function name. Remember if we were passed a non-empty |
4321 // handle to decide whether to invoke function name inference. | 4353 // handle to decide whether to invoke function name inference. |
4322 bool should_infer_name = function_name.is_null(); | 4354 bool should_infer_name = function_name.is_null(); |
4323 | 4355 |
4324 // We want a non-null handle as the function name. | 4356 // We want a non-null handle as the function name. |
4325 if (should_infer_name) { | 4357 if (should_infer_name) { |
4326 function_name = isolate()->factory()->empty_string(); | 4358 function_name = isolate()->factory()->empty_string(); |
4327 } | 4359 } |
4328 | 4360 |
4329 int num_parameters = 0; | 4361 int num_parameters = 0; |
4330 // Function declarations are function scoped in normal mode, so they are | 4362 // Function declarations are function scoped in normal mode, so they are |
4331 // hoisted. In harmony block scoping mode they are block scoped, so they | 4363 // hoisted. In harmony block scoping mode they are block scoped, so they |
4332 // are not hoisted. | 4364 // are not hoisted. |
4333 Scope* scope = (type == FunctionLiteral::DECLARATION && !is_extended_mode()) | 4365 Scope* scope = (type == FunctionLiteral::DECLARATION && !is_extended_mode()) |
4334 ? NewScope(top_scope_->DeclarationScope(), FUNCTION_SCOPE) | 4366 ? NewScope(top_scope_->DeclarationScope(), FUNCTION_SCOPE) |
4335 : NewScope(top_scope_, FUNCTION_SCOPE); | 4367 : NewScope(top_scope_, FUNCTION_SCOPE); |
| 4368 scope->set_inside_generator(is_generator); |
4336 ZoneList<Statement*>* body = NULL; | 4369 ZoneList<Statement*>* body = NULL; |
4337 int materialized_literal_count = -1; | 4370 int materialized_literal_count = -1; |
4338 int expected_property_count = -1; | 4371 int expected_property_count = -1; |
4339 int handler_count = 0; | 4372 int handler_count = 0; |
4340 bool only_simple_this_property_assignments; | 4373 bool only_simple_this_property_assignments; |
4341 Handle<FixedArray> this_property_assignments; | 4374 Handle<FixedArray> this_property_assignments; |
4342 FunctionLiteral::ParameterFlag duplicate_parameters = | 4375 FunctionLiteral::ParameterFlag duplicate_parameters = |
4343 FunctionLiteral::kNoDuplicateParameters; | 4376 FunctionLiteral::kNoDuplicateParameters; |
4344 FunctionLiteral::IsParenthesizedFlag parenthesized = parenthesized_function_ | 4377 FunctionLiteral::IsParenthesizedFlag parenthesized = parenthesized_function_ |
4345 ? FunctionLiteral::kIsParenthesized | 4378 ? FunctionLiteral::kIsParenthesized |
4346 : FunctionLiteral::kNotParenthesized; | 4379 : FunctionLiteral::kNotParenthesized; |
| 4380 FunctionLiteral::IsGeneratorFlag generator = is_generator |
| 4381 ? FunctionLiteral::kIsGenerator |
| 4382 : FunctionLiteral::kNotGenerator; |
4347 AstProperties ast_properties; | 4383 AstProperties ast_properties; |
4348 // Parse function body. | 4384 // Parse function body. |
4349 { FunctionState function_state(this, scope, isolate()); | 4385 { FunctionState function_state(this, scope, isolate()); |
4350 top_scope_->SetScopeName(function_name); | 4386 top_scope_->SetScopeName(function_name); |
4351 | 4387 |
4352 // FormalParameterList :: | 4388 // FormalParameterList :: |
4353 // '(' (Identifier)*[','] ')' | 4389 // '(' (Identifier)*[','] ')' |
4354 Expect(Token::LPAREN, CHECK_OK); | 4390 Expect(Token::LPAREN, CHECK_OK); |
4355 scope->set_start_position(scanner().location().beg_pos); | 4391 scope->set_start_position(scanner().location().beg_pos); |
4356 Scanner::Location name_loc = Scanner::Location::invalid(); | 4392 Scanner::Location name_loc = Scanner::Location::invalid(); |
(...skipping 220 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4577 body, | 4613 body, |
4578 materialized_literal_count, | 4614 materialized_literal_count, |
4579 expected_property_count, | 4615 expected_property_count, |
4580 handler_count, | 4616 handler_count, |
4581 only_simple_this_property_assignments, | 4617 only_simple_this_property_assignments, |
4582 this_property_assignments, | 4618 this_property_assignments, |
4583 num_parameters, | 4619 num_parameters, |
4584 duplicate_parameters, | 4620 duplicate_parameters, |
4585 type, | 4621 type, |
4586 FunctionLiteral::kIsFunction, | 4622 FunctionLiteral::kIsFunction, |
4587 parenthesized); | 4623 parenthesized, |
| 4624 generator); |
4588 function_literal->set_function_token_position(function_token_position); | 4625 function_literal->set_function_token_position(function_token_position); |
4589 function_literal->set_ast_properties(&ast_properties); | 4626 function_literal->set_ast_properties(&ast_properties); |
4590 | 4627 |
4591 if (fni_ != NULL && should_infer_name) fni_->AddFunction(function_literal); | 4628 if (fni_ != NULL && should_infer_name) fni_->AddFunction(function_literal); |
4592 return function_literal; | 4629 return function_literal; |
4593 } | 4630 } |
4594 | 4631 |
4595 | 4632 |
4596 preparser::PreParser::PreParseResult Parser::LazyParseFunctionLiteral( | 4633 preparser::PreParser::PreParseResult Parser::LazyParseFunctionLiteral( |
4597 SingletonLogger* logger) { | 4634 SingletonLogger* logger) { |
4598 HistogramTimerScope preparse_scope(isolate()->counters()->pre_parse()); | 4635 HistogramTimerScope preparse_scope(isolate()->counters()->pre_parse()); |
4599 ASSERT_EQ(Token::LBRACE, scanner().current_token()); | 4636 ASSERT_EQ(Token::LBRACE, scanner().current_token()); |
4600 | 4637 |
4601 if (reusable_preparser_ == NULL) { | 4638 if (reusable_preparser_ == NULL) { |
4602 intptr_t stack_limit = isolate()->stack_guard()->real_climit(); | 4639 intptr_t stack_limit = isolate()->stack_guard()->real_climit(); |
4603 bool do_allow_lazy = true; | 4640 bool do_allow_lazy = true; |
4604 reusable_preparser_ = new preparser::PreParser(&scanner_, | 4641 reusable_preparser_ = new preparser::PreParser(&scanner_, |
4605 NULL, | 4642 NULL, |
4606 stack_limit, | 4643 stack_limit, |
4607 do_allow_lazy, | 4644 do_allow_lazy, |
4608 allow_natives_syntax_, | 4645 allow_natives_syntax_, |
4609 allow_modules_); | 4646 allow_modules_); |
4610 } | 4647 } |
4611 preparser::PreParser::PreParseResult result = | 4648 preparser::PreParser::PreParseResult result = |
4612 reusable_preparser_->PreParseLazyFunction(top_scope_->language_mode(), | 4649 reusable_preparser_->PreParseLazyFunction(top_scope_->language_mode(), |
| 4650 top_scope_->inside_generator(), |
4613 logger); | 4651 logger); |
4614 return result; | 4652 return result; |
4615 } | 4653 } |
4616 | 4654 |
4617 | 4655 |
4618 Expression* Parser::ParseV8Intrinsic(bool* ok) { | 4656 Expression* Parser::ParseV8Intrinsic(bool* ok) { |
4619 // CallRuntime :: | 4657 // CallRuntime :: |
4620 // '%' Identifier Arguments | 4658 // '%' Identifier Arguments |
4621 | 4659 |
4622 Expect(Token::MOD, CHECK_OK); | 4660 Expect(Token::MOD, CHECK_OK); |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4665 | 4703 |
4666 // We have a valid intrinsics call or a call to a builtin. | 4704 // We have a valid intrinsics call or a call to a builtin. |
4667 return factory()->NewCallRuntime(name, function, args); | 4705 return factory()->NewCallRuntime(name, function, args); |
4668 } | 4706 } |
4669 | 4707 |
4670 | 4708 |
4671 bool Parser::peek_any_identifier() { | 4709 bool Parser::peek_any_identifier() { |
4672 Token::Value next = peek(); | 4710 Token::Value next = peek(); |
4673 return next == Token::IDENTIFIER || | 4711 return next == Token::IDENTIFIER || |
4674 next == Token::FUTURE_RESERVED_WORD || | 4712 next == Token::FUTURE_RESERVED_WORD || |
4675 next == Token::FUTURE_STRICT_RESERVED_WORD; | 4713 next == Token::FUTURE_STRICT_RESERVED_WORD || |
| 4714 next == Token::YIELD; |
4676 } | 4715 } |
4677 | 4716 |
4678 | 4717 |
4679 void Parser::Consume(Token::Value token) { | 4718 void Parser::Consume(Token::Value token) { |
4680 Token::Value next = Next(); | 4719 Token::Value next = Next(); |
4681 USE(next); | 4720 USE(next); |
4682 USE(token); | 4721 USE(token); |
4683 ASSERT(next == token); | 4722 ASSERT(next == token); |
4684 } | 4723 } |
4685 | 4724 |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4737 | 4776 |
4738 | 4777 |
4739 Literal* Parser::GetLiteralTheHole() { | 4778 Literal* Parser::GetLiteralTheHole() { |
4740 return factory()->NewLiteral(isolate()->factory()->the_hole_value()); | 4779 return factory()->NewLiteral(isolate()->factory()->the_hole_value()); |
4741 } | 4780 } |
4742 | 4781 |
4743 | 4782 |
4744 // Parses an identifier that is valid for the current scope, in particular it | 4783 // Parses an identifier that is valid for the current scope, in particular it |
4745 // fails on strict mode future reserved keywords in a strict scope. | 4784 // fails on strict mode future reserved keywords in a strict scope. |
4746 Handle<String> Parser::ParseIdentifier(bool* ok) { | 4785 Handle<String> Parser::ParseIdentifier(bool* ok) { |
4747 if (!top_scope_->is_classic_mode()) { | 4786 Token::Value next = Next(); |
4748 Expect(Token::IDENTIFIER, ok); | 4787 if (next == Token::IDENTIFIER || |
4749 } else if (!Check(Token::IDENTIFIER)) { | 4788 (top_scope_->is_classic_mode() && |
4750 Expect(Token::FUTURE_STRICT_RESERVED_WORD, ok); | 4789 (next == Token::FUTURE_STRICT_RESERVED_WORD || |
| 4790 (next == Token::YIELD && !inside_generator())))) { |
| 4791 return GetSymbol(ok); |
| 4792 } else { |
| 4793 ReportUnexpectedToken(next); |
| 4794 *ok = false; |
| 4795 return Handle<String>(); |
4751 } | 4796 } |
4752 if (!*ok) return Handle<String>(); | |
4753 return GetSymbol(ok); | |
4754 } | 4797 } |
4755 | 4798 |
4756 | 4799 |
4757 // Parses and identifier or a strict mode future reserved word, and indicate | 4800 // Parses and identifier or a strict mode future reserved word, and indicate |
4758 // whether it is strict mode future reserved. | 4801 // whether it is strict mode future reserved. |
4759 Handle<String> Parser::ParseIdentifierOrStrictReservedWord( | 4802 Handle<String> Parser::ParseIdentifierOrStrictReservedWord( |
4760 bool* is_strict_reserved, bool* ok) { | 4803 bool* is_strict_reserved, bool* ok) { |
4761 *is_strict_reserved = false; | 4804 Token::Value next = Next(); |
4762 if (!Check(Token::IDENTIFIER)) { | 4805 if (next == Token::IDENTIFIER) { |
4763 Expect(Token::FUTURE_STRICT_RESERVED_WORD, ok); | 4806 *is_strict_reserved = false; |
| 4807 } else if (next == Token::FUTURE_STRICT_RESERVED_WORD || |
| 4808 (next == Token::YIELD && !inside_generator())) { |
4764 *is_strict_reserved = true; | 4809 *is_strict_reserved = true; |
| 4810 } else { |
| 4811 ReportUnexpectedToken(next); |
| 4812 *ok = false; |
| 4813 return Handle<String>(); |
4765 } | 4814 } |
4766 if (!*ok) return Handle<String>(); | |
4767 return GetSymbol(ok); | 4815 return GetSymbol(ok); |
4768 } | 4816 } |
4769 | 4817 |
4770 | 4818 |
4771 Handle<String> Parser::ParseIdentifierName(bool* ok) { | 4819 Handle<String> Parser::ParseIdentifierName(bool* ok) { |
4772 Token::Value next = Next(); | 4820 Token::Value next = Next(); |
4773 if (next != Token::IDENTIFIER && | 4821 if (next != Token::IDENTIFIER && |
4774 next != Token::FUTURE_RESERVED_WORD && | 4822 next != Token::FUTURE_RESERVED_WORD && |
4775 next != Token::FUTURE_STRICT_RESERVED_WORD && | 4823 next != Token::FUTURE_STRICT_RESERVED_WORD && |
4776 !Token::IsKeyword(next)) { | 4824 !Token::IsKeyword(next)) { |
(...skipping 1165 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5942 ASSERT(info->isolate()->has_pending_exception()); | 5990 ASSERT(info->isolate()->has_pending_exception()); |
5943 } else { | 5991 } else { |
5944 result = parser.ParseProgram(); | 5992 result = parser.ParseProgram(); |
5945 } | 5993 } |
5946 } | 5994 } |
5947 info->SetFunction(result); | 5995 info->SetFunction(result); |
5948 return (result != NULL); | 5996 return (result != NULL); |
5949 } | 5997 } |
5950 | 5998 |
5951 } } // namespace v8::internal | 5999 } } // namespace v8::internal |
OLD | NEW |