| 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 518 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 529 #define CHECK_FAILED /**/); \ | 529 #define CHECK_FAILED /**/); \ |
| 530 if (failed_) return NULL; \ | 530 if (failed_) return NULL; \ |
| 531 ((void)0 | 531 ((void)0 |
| 532 #define DUMMY ) // to make indentation work | 532 #define DUMMY ) // to make indentation work |
| 533 #undef DUMMY | 533 #undef DUMMY |
| 534 | 534 |
| 535 // ---------------------------------------------------------------------------- | 535 // ---------------------------------------------------------------------------- |
| 536 // Implementation of Parser | 536 // Implementation of Parser |
| 537 | 537 |
| 538 Parser::Parser(CompilationInfo* info) | 538 Parser::Parser(CompilationInfo* info) |
| 539 : isolate_(info->isolate()), | 539 : ParserBase(&scanner_, info->isolate()->stack_guard()->real_climit()), |
| 540 isolate_(info->isolate()), |
| 540 symbol_cache_(0, info->zone()), | 541 symbol_cache_(0, info->zone()), |
| 541 script_(info->script()), | 542 script_(info->script()), |
| 542 scanner_(isolate_->unicode_cache()), | 543 scanner_(isolate_->unicode_cache()), |
| 543 reusable_preparser_(NULL), | 544 reusable_preparser_(NULL), |
| 544 top_scope_(NULL), | 545 top_scope_(NULL), |
| 545 original_scope_(NULL), | 546 original_scope_(NULL), |
| 546 current_function_state_(NULL), | 547 current_function_state_(NULL), |
| 547 target_stack_(NULL), | 548 target_stack_(NULL), |
| 548 extension_(info->extension()), | 549 extension_(info->extension()), |
| 549 pre_parse_data_(NULL), | 550 pre_parse_data_(NULL), |
| 550 fni_(NULL), | 551 fni_(NULL), |
| 551 allow_natives_syntax_(false), | |
| 552 allow_lazy_(false), | |
| 553 allow_generators_(false), | |
| 554 allow_for_of_(false), | |
| 555 stack_overflow_(false), | |
| 556 parenthesized_function_(false), | 552 parenthesized_function_(false), |
| 557 zone_(info->zone()), | 553 zone_(info->zone()), |
| 558 info_(info) { | 554 info_(info) { |
| 559 ASSERT(!script_.is_null()); | 555 ASSERT(!script_.is_null()); |
| 560 isolate_->set_ast_node_id(0); | 556 isolate_->set_ast_node_id(0); |
| 561 set_allow_harmony_scoping(!info->is_native() && FLAG_harmony_scoping); | 557 set_allow_harmony_scoping(!info->is_native() && FLAG_harmony_scoping); |
| 562 set_allow_modules(!info->is_native() && FLAG_harmony_modules); | 558 set_allow_modules(!info->is_native() && FLAG_harmony_modules); |
| 563 set_allow_natives_syntax(FLAG_allow_natives_syntax || info->is_native()); | 559 set_allow_natives_syntax(FLAG_allow_natives_syntax || info->is_native()); |
| 564 set_allow_lazy(false); // Must be explicitly enabled. | 560 set_allow_lazy(false); // Must be explicitly enabled. |
| 565 set_allow_generators(FLAG_harmony_generators); | 561 set_allow_generators(FLAG_harmony_generators); |
| 566 set_allow_for_of(FLAG_harmony_iteration); | 562 set_allow_for_of(FLAG_harmony_iteration); |
| 567 set_allow_harmony_numeric_literals(FLAG_harmony_numeric_literals); | 563 set_allow_harmony_numeric_literals(FLAG_harmony_numeric_literals); |
| 568 } | 564 } |
| 569 | 565 |
| 570 | 566 |
| 571 FunctionLiteral* Parser::ParseProgram() { | 567 FunctionLiteral* Parser::ParseProgram() { |
| 572 HistogramTimerScope timer_scope(isolate()->counters()->parse()); | 568 // TODO(bmeurer): We temporarily need to pass allow_nesting = true here, |
| 569 // see comment for HistogramTimerScope class. |
| 570 HistogramTimerScope timer_scope(isolate()->counters()->parse(), true); |
| 573 Handle<String> source(String::cast(script_->source())); | 571 Handle<String> source(String::cast(script_->source())); |
| 574 isolate()->counters()->total_parse_size()->Increment(source->length()); | 572 isolate()->counters()->total_parse_size()->Increment(source->length()); |
| 575 ElapsedTimer timer; | 573 ElapsedTimer timer; |
| 576 if (FLAG_trace_parse) { | 574 if (FLAG_trace_parse) { |
| 577 timer.Start(); | 575 timer.Start(); |
| 578 } | 576 } |
| 579 fni_ = new(zone()) FuncNameInferrer(isolate(), zone()); | 577 fni_ = new(zone()) FuncNameInferrer(isolate(), zone()); |
| 580 | 578 |
| 581 // Initialize parser state. | 579 // Initialize parser state. |
| 582 source->TryFlatten(); | 580 source->TryFlatten(); |
| (...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 645 mode = PARSE_EAGERLY; | 643 mode = PARSE_EAGERLY; |
| 646 } | 644 } |
| 647 ParsingModeScope parsing_mode(this, mode); | 645 ParsingModeScope parsing_mode(this, mode); |
| 648 | 646 |
| 649 // Enters 'scope'. | 647 // Enters 'scope'. |
| 650 FunctionState function_state(this, scope, isolate()); | 648 FunctionState function_state(this, scope, isolate()); |
| 651 | 649 |
| 652 top_scope_->SetLanguageMode(info->language_mode()); | 650 top_scope_->SetLanguageMode(info->language_mode()); |
| 653 ZoneList<Statement*>* body = new(zone()) ZoneList<Statement*>(16, zone()); | 651 ZoneList<Statement*>* body = new(zone()) ZoneList<Statement*>(16, zone()); |
| 654 bool ok = true; | 652 bool ok = true; |
| 655 int beg_loc = scanner().location().beg_pos; | 653 int beg_pos = scanner().location().beg_pos; |
| 656 ParseSourceElements(body, Token::EOS, info->is_eval(), true, &ok); | 654 ParseSourceElements(body, Token::EOS, info->is_eval(), true, &ok); |
| 657 if (ok && !top_scope_->is_classic_mode()) { | 655 if (ok && !top_scope_->is_classic_mode()) { |
| 658 CheckOctalLiteral(beg_loc, scanner().location().end_pos, &ok); | 656 CheckOctalLiteral(beg_pos, scanner().location().end_pos, &ok); |
| 659 } | 657 } |
| 660 | 658 |
| 661 if (ok && is_extended_mode()) { | 659 if (ok && is_extended_mode()) { |
| 662 CheckConflictingVarDeclarations(top_scope_, &ok); | 660 CheckConflictingVarDeclarations(top_scope_, &ok); |
| 663 } | 661 } |
| 664 | 662 |
| 665 if (ok && info->parse_restriction() == ONLY_SINGLE_FUNCTION_LITERAL) { | 663 if (ok && info->parse_restriction() == ONLY_SINGLE_FUNCTION_LITERAL) { |
| 666 if (body->length() != 1 || | 664 if (body->length() != 1 || |
| 667 !body->at(0)->IsExpressionStatement() || | 665 !body->at(0)->IsExpressionStatement() || |
| 668 !body->at(0)->AsExpressionStatement()-> | 666 !body->at(0)->AsExpressionStatement()-> |
| 669 expression()->IsFunctionLiteral()) { | 667 expression()->IsFunctionLiteral()) { |
| 670 ReportMessage("single_function_literal", Vector<const char*>::empty()); | 668 ReportMessage("single_function_literal", Vector<const char*>::empty()); |
| 671 ok = false; | 669 ok = false; |
| 672 } | 670 } |
| 673 } | 671 } |
| 674 | 672 |
| 675 if (ok) { | 673 if (ok) { |
| 676 result = factory()->NewFunctionLiteral( | 674 result = factory()->NewFunctionLiteral( |
| 677 no_name, | 675 no_name, |
| 678 top_scope_, | 676 top_scope_, |
| 679 body, | 677 body, |
| 680 function_state.materialized_literal_count(), | 678 function_state.materialized_literal_count(), |
| 681 function_state.expected_property_count(), | 679 function_state.expected_property_count(), |
| 682 function_state.handler_count(), | 680 function_state.handler_count(), |
| 683 0, | 681 0, |
| 684 FunctionLiteral::kNoDuplicateParameters, | 682 FunctionLiteral::kNoDuplicateParameters, |
| 685 FunctionLiteral::ANONYMOUS_EXPRESSION, | 683 FunctionLiteral::ANONYMOUS_EXPRESSION, |
| 686 FunctionLiteral::kGlobalOrEval, | 684 FunctionLiteral::kGlobalOrEval, |
| 687 FunctionLiteral::kNotParenthesized, | 685 FunctionLiteral::kNotParenthesized, |
| 688 FunctionLiteral::kNotGenerator); | 686 FunctionLiteral::kNotGenerator, |
| 687 0); |
| 689 result->set_ast_properties(factory()->visitor()->ast_properties()); | 688 result->set_ast_properties(factory()->visitor()->ast_properties()); |
| 690 result->set_dont_optimize_reason( | 689 result->set_dont_optimize_reason( |
| 691 factory()->visitor()->dont_optimize_reason()); | 690 factory()->visitor()->dont_optimize_reason()); |
| 692 } else if (stack_overflow_) { | 691 } else if (stack_overflow()) { |
| 693 isolate()->StackOverflow(); | 692 isolate()->StackOverflow(); |
| 694 } | 693 } |
| 695 } | 694 } |
| 696 | 695 |
| 697 // Make sure the target stack is empty. | 696 // Make sure the target stack is empty. |
| 698 ASSERT(target_stack_ == NULL); | 697 ASSERT(target_stack_ == NULL); |
| 699 | 698 |
| 700 return result; | 699 return result; |
| 701 } | 700 } |
| 702 | 701 |
| (...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 779 function_type, | 778 function_type, |
| 780 &ok); | 779 &ok); |
| 781 // Make sure the results agree. | 780 // Make sure the results agree. |
| 782 ASSERT(ok == (result != NULL)); | 781 ASSERT(ok == (result != NULL)); |
| 783 } | 782 } |
| 784 | 783 |
| 785 // Make sure the target stack is empty. | 784 // Make sure the target stack is empty. |
| 786 ASSERT(target_stack_ == NULL); | 785 ASSERT(target_stack_ == NULL); |
| 787 | 786 |
| 788 if (result == NULL) { | 787 if (result == NULL) { |
| 789 if (stack_overflow_) isolate()->StackOverflow(); | 788 if (stack_overflow()) isolate()->StackOverflow(); |
| 790 } else { | 789 } else { |
| 791 Handle<String> inferred_name(shared_info->inferred_name()); | 790 Handle<String> inferred_name(shared_info->inferred_name()); |
| 792 result->set_inferred_name(inferred_name); | 791 result->set_inferred_name(inferred_name); |
| 793 } | 792 } |
| 794 return result; | 793 return result; |
| 795 } | 794 } |
| 796 | 795 |
| 797 | 796 |
| 798 Handle<String> Parser::GetSymbol() { | 797 Handle<String> Parser::GetSymbol() { |
| 799 int symbol_id = -1; | 798 int symbol_id = -1; |
| (...skipping 177 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 977 return stmt; | 976 return stmt; |
| 978 } | 977 } |
| 979 } | 978 } |
| 980 } | 979 } |
| 981 | 980 |
| 982 | 981 |
| 983 Statement* Parser::ParseModuleDeclaration(ZoneStringList* names, bool* ok) { | 982 Statement* Parser::ParseModuleDeclaration(ZoneStringList* names, bool* ok) { |
| 984 // ModuleDeclaration: | 983 // ModuleDeclaration: |
| 985 // 'module' Identifier Module | 984 // 'module' Identifier Module |
| 986 | 985 |
| 986 int pos = peek_position(); |
| 987 Handle<String> name = ParseIdentifier(CHECK_OK); | 987 Handle<String> name = ParseIdentifier(CHECK_OK); |
| 988 | 988 |
| 989 #ifdef DEBUG | 989 #ifdef DEBUG |
| 990 if (FLAG_print_interface_details) | 990 if (FLAG_print_interface_details) |
| 991 PrintF("# Module %s...\n", name->ToAsciiArray()); | 991 PrintF("# Module %s...\n", name->ToAsciiArray()); |
| 992 #endif | 992 #endif |
| 993 | 993 |
| 994 Module* module = ParseModule(CHECK_OK); | 994 Module* module = ParseModule(CHECK_OK); |
| 995 VariableProxy* proxy = NewUnresolved(name, MODULE, module->interface()); | 995 VariableProxy* proxy = NewUnresolved(name, MODULE, module->interface()); |
| 996 Declaration* declaration = | 996 Declaration* declaration = |
| 997 factory()->NewModuleDeclaration(proxy, module, top_scope_); | 997 factory()->NewModuleDeclaration(proxy, module, top_scope_, pos); |
| 998 Declare(declaration, true, CHECK_OK); | 998 Declare(declaration, true, CHECK_OK); |
| 999 | 999 |
| 1000 #ifdef DEBUG | 1000 #ifdef DEBUG |
| 1001 if (FLAG_print_interface_details) | 1001 if (FLAG_print_interface_details) |
| 1002 PrintF("# Module %s.\n", name->ToAsciiArray()); | 1002 PrintF("# Module %s.\n", name->ToAsciiArray()); |
| 1003 | 1003 |
| 1004 if (FLAG_print_interfaces) { | 1004 if (FLAG_print_interfaces) { |
| 1005 PrintF("module %s : ", name->ToAsciiArray()); | 1005 PrintF("module %s : ", name->ToAsciiArray()); |
| 1006 module->interface()->Print(); | 1006 module->interface()->Print(); |
| 1007 } | 1007 } |
| 1008 #endif | 1008 #endif |
| 1009 | 1009 |
| 1010 if (names) names->Add(name, zone()); | 1010 if (names) names->Add(name, zone()); |
| 1011 if (module->body() == NULL) | 1011 if (module->body() == NULL) |
| 1012 return factory()->NewEmptyStatement(); | 1012 return factory()->NewEmptyStatement(pos); |
| 1013 else | 1013 else |
| 1014 return factory()->NewModuleStatement(proxy, module->body()); | 1014 return factory()->NewModuleStatement(proxy, module->body(), pos); |
| 1015 } | 1015 } |
| 1016 | 1016 |
| 1017 | 1017 |
| 1018 Module* Parser::ParseModule(bool* ok) { | 1018 Module* Parser::ParseModule(bool* ok) { |
| 1019 // Module: | 1019 // Module: |
| 1020 // '{' ModuleElement '}' | 1020 // '{' ModuleElement '}' |
| 1021 // '=' ModulePath ';' | 1021 // '=' ModulePath ';' |
| 1022 // 'at' String ';' | 1022 // 'at' String ';' |
| 1023 | 1023 |
| 1024 switch (peek()) { | 1024 switch (peek()) { |
| (...skipping 14 matching lines...) Expand all Loading... |
| 1039 return result; | 1039 return result; |
| 1040 } | 1040 } |
| 1041 } | 1041 } |
| 1042 } | 1042 } |
| 1043 | 1043 |
| 1044 | 1044 |
| 1045 Module* Parser::ParseModuleLiteral(bool* ok) { | 1045 Module* Parser::ParseModuleLiteral(bool* ok) { |
| 1046 // Module: | 1046 // Module: |
| 1047 // '{' ModuleElement '}' | 1047 // '{' ModuleElement '}' |
| 1048 | 1048 |
| 1049 int pos = peek_position(); |
| 1049 // Construct block expecting 16 statements. | 1050 // Construct block expecting 16 statements. |
| 1050 Block* body = factory()->NewBlock(NULL, 16, false); | 1051 Block* body = factory()->NewBlock(NULL, 16, false, RelocInfo::kNoPosition); |
| 1051 #ifdef DEBUG | 1052 #ifdef DEBUG |
| 1052 if (FLAG_print_interface_details) PrintF("# Literal "); | 1053 if (FLAG_print_interface_details) PrintF("# Literal "); |
| 1053 #endif | 1054 #endif |
| 1054 Scope* scope = NewScope(top_scope_, MODULE_SCOPE); | 1055 Scope* scope = NewScope(top_scope_, MODULE_SCOPE); |
| 1055 | 1056 |
| 1056 Expect(Token::LBRACE, CHECK_OK); | 1057 Expect(Token::LBRACE, CHECK_OK); |
| 1057 scope->set_start_position(scanner().location().beg_pos); | 1058 scope->set_start_position(scanner().location().beg_pos); |
| 1058 scope->SetLanguageMode(EXTENDED_MODE); | 1059 scope->SetLanguageMode(EXTENDED_MODE); |
| 1059 | 1060 |
| 1060 { | 1061 { |
| (...skipping 24 matching lines...) Expand all Loading... |
| 1085 Vector<Handle<String> >(&name, 1)); | 1086 Vector<Handle<String> >(&name, 1)); |
| 1086 *ok = false; | 1087 *ok = false; |
| 1087 return NULL; | 1088 return NULL; |
| 1088 } | 1089 } |
| 1089 } | 1090 } |
| 1090 | 1091 |
| 1091 interface->MakeModule(ok); | 1092 interface->MakeModule(ok); |
| 1092 ASSERT(*ok); | 1093 ASSERT(*ok); |
| 1093 interface->Freeze(ok); | 1094 interface->Freeze(ok); |
| 1094 ASSERT(*ok); | 1095 ASSERT(*ok); |
| 1095 return factory()->NewModuleLiteral(body, interface); | 1096 return factory()->NewModuleLiteral(body, interface, pos); |
| 1096 } | 1097 } |
| 1097 | 1098 |
| 1098 | 1099 |
| 1099 Module* Parser::ParseModulePath(bool* ok) { | 1100 Module* Parser::ParseModulePath(bool* ok) { |
| 1100 // ModulePath: | 1101 // ModulePath: |
| 1101 // Identifier | 1102 // Identifier |
| 1102 // ModulePath '.' Identifier | 1103 // ModulePath '.' Identifier |
| 1103 | 1104 |
| 1105 int pos = peek_position(); |
| 1104 Module* result = ParseModuleVariable(CHECK_OK); | 1106 Module* result = ParseModuleVariable(CHECK_OK); |
| 1105 while (Check(Token::PERIOD)) { | 1107 while (Check(Token::PERIOD)) { |
| 1106 Handle<String> name = ParseIdentifierName(CHECK_OK); | 1108 Handle<String> name = ParseIdentifierName(CHECK_OK); |
| 1107 #ifdef DEBUG | 1109 #ifdef DEBUG |
| 1108 if (FLAG_print_interface_details) | 1110 if (FLAG_print_interface_details) |
| 1109 PrintF("# Path .%s ", name->ToAsciiArray()); | 1111 PrintF("# Path .%s ", name->ToAsciiArray()); |
| 1110 #endif | 1112 #endif |
| 1111 Module* member = factory()->NewModulePath(result, name); | 1113 Module* member = factory()->NewModulePath(result, name, pos); |
| 1112 result->interface()->Add(name, member->interface(), zone(), ok); | 1114 result->interface()->Add(name, member->interface(), zone(), ok); |
| 1113 if (!*ok) { | 1115 if (!*ok) { |
| 1114 #ifdef DEBUG | 1116 #ifdef DEBUG |
| 1115 if (FLAG_print_interfaces) { | 1117 if (FLAG_print_interfaces) { |
| 1116 PrintF("PATH TYPE ERROR at '%s'\n", name->ToAsciiArray()); | 1118 PrintF("PATH TYPE ERROR at '%s'\n", name->ToAsciiArray()); |
| 1117 PrintF("result: "); | 1119 PrintF("result: "); |
| 1118 result->interface()->Print(); | 1120 result->interface()->Print(); |
| 1119 PrintF("member: "); | 1121 PrintF("member: "); |
| 1120 member->interface()->Print(); | 1122 member->interface()->Print(); |
| 1121 } | 1123 } |
| 1122 #endif | 1124 #endif |
| 1123 ReportMessage("invalid_module_path", Vector<Handle<String> >(&name, 1)); | 1125 ReportMessage("invalid_module_path", Vector<Handle<String> >(&name, 1)); |
| 1124 return NULL; | 1126 return NULL; |
| 1125 } | 1127 } |
| 1126 result = member; | 1128 result = member; |
| 1127 } | 1129 } |
| 1128 | 1130 |
| 1129 return result; | 1131 return result; |
| 1130 } | 1132 } |
| 1131 | 1133 |
| 1132 | 1134 |
| 1133 Module* Parser::ParseModuleVariable(bool* ok) { | 1135 Module* Parser::ParseModuleVariable(bool* ok) { |
| 1134 // ModulePath: | 1136 // ModulePath: |
| 1135 // Identifier | 1137 // Identifier |
| 1136 | 1138 |
| 1139 int pos = peek_position(); |
| 1137 Handle<String> name = ParseIdentifier(CHECK_OK); | 1140 Handle<String> name = ParseIdentifier(CHECK_OK); |
| 1138 #ifdef DEBUG | 1141 #ifdef DEBUG |
| 1139 if (FLAG_print_interface_details) | 1142 if (FLAG_print_interface_details) |
| 1140 PrintF("# Module variable %s ", name->ToAsciiArray()); | 1143 PrintF("# Module variable %s ", name->ToAsciiArray()); |
| 1141 #endif | 1144 #endif |
| 1142 VariableProxy* proxy = top_scope_->NewUnresolved( | 1145 VariableProxy* proxy = top_scope_->NewUnresolved( |
| 1143 factory(), name, Interface::NewModule(zone()), | 1146 factory(), name, Interface::NewModule(zone()), |
| 1144 scanner().location().beg_pos); | 1147 scanner().location().beg_pos); |
| 1145 | 1148 |
| 1146 return factory()->NewModuleVariable(proxy); | 1149 return factory()->NewModuleVariable(proxy, pos); |
| 1147 } | 1150 } |
| 1148 | 1151 |
| 1149 | 1152 |
| 1150 Module* Parser::ParseModuleUrl(bool* ok) { | 1153 Module* Parser::ParseModuleUrl(bool* ok) { |
| 1151 // Module: | 1154 // Module: |
| 1152 // String | 1155 // String |
| 1153 | 1156 |
| 1157 int pos = peek_position(); |
| 1154 Expect(Token::STRING, CHECK_OK); | 1158 Expect(Token::STRING, CHECK_OK); |
| 1155 Handle<String> symbol = GetSymbol(); | 1159 Handle<String> symbol = GetSymbol(); |
| 1156 | 1160 |
| 1157 // TODO(ES6): Request JS resource from environment... | 1161 // TODO(ES6): Request JS resource from environment... |
| 1158 | 1162 |
| 1159 #ifdef DEBUG | 1163 #ifdef DEBUG |
| 1160 if (FLAG_print_interface_details) PrintF("# Url "); | 1164 if (FLAG_print_interface_details) PrintF("# Url "); |
| 1161 #endif | 1165 #endif |
| 1162 | 1166 |
| 1163 // Create an empty literal as long as the feature isn't finished. | 1167 // Create an empty literal as long as the feature isn't finished. |
| 1164 USE(symbol); | 1168 USE(symbol); |
| 1165 Scope* scope = NewScope(top_scope_, MODULE_SCOPE); | 1169 Scope* scope = NewScope(top_scope_, MODULE_SCOPE); |
| 1166 Block* body = factory()->NewBlock(NULL, 1, false); | 1170 Block* body = factory()->NewBlock(NULL, 1, false, RelocInfo::kNoPosition); |
| 1167 body->set_scope(scope); | 1171 body->set_scope(scope); |
| 1168 Interface* interface = scope->interface(); | 1172 Interface* interface = scope->interface(); |
| 1169 Module* result = factory()->NewModuleLiteral(body, interface); | 1173 Module* result = factory()->NewModuleLiteral(body, interface, pos); |
| 1170 interface->Freeze(ok); | 1174 interface->Freeze(ok); |
| 1171 ASSERT(*ok); | 1175 ASSERT(*ok); |
| 1172 interface->Unify(scope->interface(), zone(), ok); | 1176 interface->Unify(scope->interface(), zone(), ok); |
| 1173 ASSERT(*ok); | 1177 ASSERT(*ok); |
| 1174 return result; | 1178 return result; |
| 1175 } | 1179 } |
| 1176 | 1180 |
| 1177 | 1181 |
| 1178 Module* Parser::ParseModuleSpecifier(bool* ok) { | 1182 Module* Parser::ParseModuleSpecifier(bool* ok) { |
| 1179 // ModuleSpecifier: | 1183 // ModuleSpecifier: |
| 1180 // String | 1184 // String |
| 1181 // ModulePath | 1185 // ModulePath |
| 1182 | 1186 |
| 1183 if (peek() == Token::STRING) { | 1187 if (peek() == Token::STRING) { |
| 1184 return ParseModuleUrl(ok); | 1188 return ParseModuleUrl(ok); |
| 1185 } else { | 1189 } else { |
| 1186 return ParseModulePath(ok); | 1190 return ParseModulePath(ok); |
| 1187 } | 1191 } |
| 1188 } | 1192 } |
| 1189 | 1193 |
| 1190 | 1194 |
| 1191 Block* Parser::ParseImportDeclaration(bool* ok) { | 1195 Block* Parser::ParseImportDeclaration(bool* ok) { |
| 1192 // ImportDeclaration: | 1196 // ImportDeclaration: |
| 1193 // 'import' IdentifierName (',' IdentifierName)* 'from' ModuleSpecifier ';' | 1197 // 'import' IdentifierName (',' IdentifierName)* 'from' ModuleSpecifier ';' |
| 1194 // | 1198 // |
| 1195 // TODO(ES6): implement destructuring ImportSpecifiers | 1199 // TODO(ES6): implement destructuring ImportSpecifiers |
| 1196 | 1200 |
| 1201 int pos = peek_position(); |
| 1197 Expect(Token::IMPORT, CHECK_OK); | 1202 Expect(Token::IMPORT, CHECK_OK); |
| 1198 ZoneStringList names(1, zone()); | 1203 ZoneStringList names(1, zone()); |
| 1199 | 1204 |
| 1200 Handle<String> name = ParseIdentifierName(CHECK_OK); | 1205 Handle<String> name = ParseIdentifierName(CHECK_OK); |
| 1201 names.Add(name, zone()); | 1206 names.Add(name, zone()); |
| 1202 while (peek() == Token::COMMA) { | 1207 while (peek() == Token::COMMA) { |
| 1203 Consume(Token::COMMA); | 1208 Consume(Token::COMMA); |
| 1204 name = ParseIdentifierName(CHECK_OK); | 1209 name = ParseIdentifierName(CHECK_OK); |
| 1205 names.Add(name, zone()); | 1210 names.Add(name, zone()); |
| 1206 } | 1211 } |
| 1207 | 1212 |
| 1208 ExpectContextualKeyword(CStrVector("from"), CHECK_OK); | 1213 ExpectContextualKeyword(CStrVector("from"), CHECK_OK); |
| 1209 Module* module = ParseModuleSpecifier(CHECK_OK); | 1214 Module* module = ParseModuleSpecifier(CHECK_OK); |
| 1210 ExpectSemicolon(CHECK_OK); | 1215 ExpectSemicolon(CHECK_OK); |
| 1211 | 1216 |
| 1212 // Generate a separate declaration for each identifier. | 1217 // Generate a separate declaration for each identifier. |
| 1213 // TODO(ES6): once we implement destructuring, make that one declaration. | 1218 // TODO(ES6): once we implement destructuring, make that one declaration. |
| 1214 Block* block = factory()->NewBlock(NULL, 1, true); | 1219 Block* block = factory()->NewBlock(NULL, 1, true, RelocInfo::kNoPosition); |
| 1215 for (int i = 0; i < names.length(); ++i) { | 1220 for (int i = 0; i < names.length(); ++i) { |
| 1216 #ifdef DEBUG | 1221 #ifdef DEBUG |
| 1217 if (FLAG_print_interface_details) | 1222 if (FLAG_print_interface_details) |
| 1218 PrintF("# Import %s ", names[i]->ToAsciiArray()); | 1223 PrintF("# Import %s ", names[i]->ToAsciiArray()); |
| 1219 #endif | 1224 #endif |
| 1220 Interface* interface = Interface::NewUnknown(zone()); | 1225 Interface* interface = Interface::NewUnknown(zone()); |
| 1221 module->interface()->Add(names[i], interface, zone(), ok); | 1226 module->interface()->Add(names[i], interface, zone(), ok); |
| 1222 if (!*ok) { | 1227 if (!*ok) { |
| 1223 #ifdef DEBUG | 1228 #ifdef DEBUG |
| 1224 if (FLAG_print_interfaces) { | 1229 if (FLAG_print_interfaces) { |
| 1225 PrintF("IMPORT TYPE ERROR at '%s'\n", names[i]->ToAsciiArray()); | 1230 PrintF("IMPORT TYPE ERROR at '%s'\n", names[i]->ToAsciiArray()); |
| 1226 PrintF("module: "); | 1231 PrintF("module: "); |
| 1227 module->interface()->Print(); | 1232 module->interface()->Print(); |
| 1228 } | 1233 } |
| 1229 #endif | 1234 #endif |
| 1230 ReportMessage("invalid_module_path", Vector<Handle<String> >(&name, 1)); | 1235 ReportMessage("invalid_module_path", Vector<Handle<String> >(&name, 1)); |
| 1231 return NULL; | 1236 return NULL; |
| 1232 } | 1237 } |
| 1233 VariableProxy* proxy = NewUnresolved(names[i], LET, interface); | 1238 VariableProxy* proxy = NewUnresolved(names[i], LET, interface); |
| 1234 Declaration* declaration = | 1239 Declaration* declaration = |
| 1235 factory()->NewImportDeclaration(proxy, module, top_scope_); | 1240 factory()->NewImportDeclaration(proxy, module, top_scope_, pos); |
| 1236 Declare(declaration, true, CHECK_OK); | 1241 Declare(declaration, true, CHECK_OK); |
| 1237 } | 1242 } |
| 1238 | 1243 |
| 1239 return block; | 1244 return block; |
| 1240 } | 1245 } |
| 1241 | 1246 |
| 1242 | 1247 |
| 1243 Statement* Parser::ParseExportDeclaration(bool* ok) { | 1248 Statement* Parser::ParseExportDeclaration(bool* ok) { |
| 1244 // ExportDeclaration: | 1249 // ExportDeclaration: |
| 1245 // 'export' Identifier (',' Identifier)* ';' | 1250 // 'export' Identifier (',' Identifier)* ';' |
| 1246 // 'export' VariableDeclaration | 1251 // 'export' VariableDeclaration |
| 1247 // 'export' FunctionDeclaration | 1252 // 'export' FunctionDeclaration |
| 1248 // 'export' GeneratorDeclaration | 1253 // 'export' GeneratorDeclaration |
| 1249 // 'export' ModuleDeclaration | 1254 // 'export' ModuleDeclaration |
| 1250 // | 1255 // |
| 1251 // TODO(ES6): implement structuring ExportSpecifiers | 1256 // TODO(ES6): implement structuring ExportSpecifiers |
| 1252 | 1257 |
| 1253 Expect(Token::EXPORT, CHECK_OK); | 1258 Expect(Token::EXPORT, CHECK_OK); |
| 1254 | 1259 |
| 1255 Statement* result = NULL; | 1260 Statement* result = NULL; |
| 1256 ZoneStringList names(1, zone()); | 1261 ZoneStringList names(1, zone()); |
| 1257 switch (peek()) { | 1262 switch (peek()) { |
| 1258 case Token::IDENTIFIER: { | 1263 case Token::IDENTIFIER: { |
| 1264 int pos = position(); |
| 1259 Handle<String> name = ParseIdentifier(CHECK_OK); | 1265 Handle<String> name = ParseIdentifier(CHECK_OK); |
| 1260 // Handle 'module' as a context-sensitive keyword. | 1266 // Handle 'module' as a context-sensitive keyword. |
| 1261 if (!name->IsOneByteEqualTo(STATIC_ASCII_VECTOR("module"))) { | 1267 if (!name->IsOneByteEqualTo(STATIC_ASCII_VECTOR("module"))) { |
| 1262 names.Add(name, zone()); | 1268 names.Add(name, zone()); |
| 1263 while (peek() == Token::COMMA) { | 1269 while (peek() == Token::COMMA) { |
| 1264 Consume(Token::COMMA); | 1270 Consume(Token::COMMA); |
| 1265 name = ParseIdentifier(CHECK_OK); | 1271 name = ParseIdentifier(CHECK_OK); |
| 1266 names.Add(name, zone()); | 1272 names.Add(name, zone()); |
| 1267 } | 1273 } |
| 1268 ExpectSemicolon(CHECK_OK); | 1274 ExpectSemicolon(CHECK_OK); |
| 1269 result = factory()->NewEmptyStatement(); | 1275 result = factory()->NewEmptyStatement(pos); |
| 1270 } else { | 1276 } else { |
| 1271 result = ParseModuleDeclaration(&names, CHECK_OK); | 1277 result = ParseModuleDeclaration(&names, CHECK_OK); |
| 1272 } | 1278 } |
| 1273 break; | 1279 break; |
| 1274 } | 1280 } |
| 1275 | 1281 |
| 1276 case Token::FUNCTION: | 1282 case Token::FUNCTION: |
| 1277 result = ParseFunctionDeclaration(&names, CHECK_OK); | 1283 result = ParseFunctionDeclaration(&names, CHECK_OK); |
| 1278 break; | 1284 break; |
| 1279 | 1285 |
| (...skipping 18 matching lines...) Expand all Loading... |
| 1298 #endif | 1304 #endif |
| 1299 Interface* inner = Interface::NewUnknown(zone()); | 1305 Interface* inner = Interface::NewUnknown(zone()); |
| 1300 interface->Add(names[i], inner, zone(), CHECK_OK); | 1306 interface->Add(names[i], inner, zone(), CHECK_OK); |
| 1301 if (!*ok) | 1307 if (!*ok) |
| 1302 return NULL; | 1308 return NULL; |
| 1303 VariableProxy* proxy = NewUnresolved(names[i], LET, inner); | 1309 VariableProxy* proxy = NewUnresolved(names[i], LET, inner); |
| 1304 USE(proxy); | 1310 USE(proxy); |
| 1305 // TODO(rossberg): Rethink whether we actually need to store export | 1311 // TODO(rossberg): Rethink whether we actually need to store export |
| 1306 // declarations (for compilation?). | 1312 // declarations (for compilation?). |
| 1307 // ExportDeclaration* declaration = | 1313 // ExportDeclaration* declaration = |
| 1308 // factory()->NewExportDeclaration(proxy, top_scope_); | 1314 // factory()->NewExportDeclaration(proxy, top_scope_, position); |
| 1309 // top_scope_->AddDeclaration(declaration); | 1315 // top_scope_->AddDeclaration(declaration); |
| 1310 } | 1316 } |
| 1311 | 1317 |
| 1312 ASSERT(result != NULL); | 1318 ASSERT(result != NULL); |
| 1313 return result; | 1319 return result; |
| 1314 } | 1320 } |
| 1315 | 1321 |
| 1316 | 1322 |
| 1317 Statement* Parser::ParseBlockElement(ZoneStringList* labels, | 1323 Statement* Parser::ParseBlockElement(ZoneStringList* labels, |
| 1318 bool* ok) { | 1324 bool* ok) { |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1356 // ThrowStatement | 1362 // ThrowStatement |
| 1357 // TryStatement | 1363 // TryStatement |
| 1358 // DebuggerStatement | 1364 // DebuggerStatement |
| 1359 | 1365 |
| 1360 // Note: Since labels can only be used by 'break' and 'continue' | 1366 // Note: Since labels can only be used by 'break' and 'continue' |
| 1361 // statements, which themselves are only valid within blocks, | 1367 // statements, which themselves are only valid within blocks, |
| 1362 // iterations or 'switch' statements (i.e., BreakableStatements), | 1368 // iterations or 'switch' statements (i.e., BreakableStatements), |
| 1363 // labels can be simply ignored in all other cases; except for | 1369 // labels can be simply ignored in all other cases; except for |
| 1364 // trivial labeled break statements 'label: break label' which is | 1370 // trivial labeled break statements 'label: break label' which is |
| 1365 // parsed into an empty statement. | 1371 // parsed into an empty statement. |
| 1366 | |
| 1367 // Keep the source position of the statement | |
| 1368 int statement_pos = scanner().peek_location().beg_pos; | |
| 1369 Statement* stmt = NULL; | |
| 1370 switch (peek()) { | 1372 switch (peek()) { |
| 1371 case Token::LBRACE: | 1373 case Token::LBRACE: |
| 1372 return ParseBlock(labels, ok); | 1374 return ParseBlock(labels, ok); |
| 1373 | 1375 |
| 1374 case Token::CONST: // fall through | 1376 case Token::CONST: // fall through |
| 1375 case Token::LET: | 1377 case Token::LET: |
| 1376 case Token::VAR: | 1378 case Token::VAR: |
| 1377 stmt = ParseVariableStatement(kStatement, NULL, ok); | 1379 return ParseVariableStatement(kStatement, NULL, ok); |
| 1378 break; | |
| 1379 | 1380 |
| 1380 case Token::SEMICOLON: | 1381 case Token::SEMICOLON: |
| 1381 Next(); | 1382 Next(); |
| 1382 return factory()->NewEmptyStatement(); | 1383 return factory()->NewEmptyStatement(RelocInfo::kNoPosition); |
| 1383 | 1384 |
| 1384 case Token::IF: | 1385 case Token::IF: |
| 1385 stmt = ParseIfStatement(labels, ok); | 1386 return ParseIfStatement(labels, ok); |
| 1386 break; | |
| 1387 | 1387 |
| 1388 case Token::DO: | 1388 case Token::DO: |
| 1389 stmt = ParseDoWhileStatement(labels, ok); | 1389 return ParseDoWhileStatement(labels, ok); |
| 1390 break; | |
| 1391 | 1390 |
| 1392 case Token::WHILE: | 1391 case Token::WHILE: |
| 1393 stmt = ParseWhileStatement(labels, ok); | 1392 return ParseWhileStatement(labels, ok); |
| 1394 break; | |
| 1395 | 1393 |
| 1396 case Token::FOR: | 1394 case Token::FOR: |
| 1397 stmt = ParseForStatement(labels, ok); | 1395 return ParseForStatement(labels, ok); |
| 1398 break; | |
| 1399 | 1396 |
| 1400 case Token::CONTINUE: | 1397 case Token::CONTINUE: |
| 1401 stmt = ParseContinueStatement(ok); | 1398 return ParseContinueStatement(ok); |
| 1402 break; | |
| 1403 | 1399 |
| 1404 case Token::BREAK: | 1400 case Token::BREAK: |
| 1405 stmt = ParseBreakStatement(labels, ok); | 1401 return ParseBreakStatement(labels, ok); |
| 1406 break; | |
| 1407 | 1402 |
| 1408 case Token::RETURN: | 1403 case Token::RETURN: |
| 1409 stmt = ParseReturnStatement(ok); | 1404 return ParseReturnStatement(ok); |
| 1410 break; | |
| 1411 | 1405 |
| 1412 case Token::WITH: | 1406 case Token::WITH: |
| 1413 stmt = ParseWithStatement(labels, ok); | 1407 return ParseWithStatement(labels, ok); |
| 1414 break; | |
| 1415 | 1408 |
| 1416 case Token::SWITCH: | 1409 case Token::SWITCH: |
| 1417 stmt = ParseSwitchStatement(labels, ok); | 1410 return ParseSwitchStatement(labels, ok); |
| 1418 break; | |
| 1419 | 1411 |
| 1420 case Token::THROW: | 1412 case Token::THROW: |
| 1421 stmt = ParseThrowStatement(ok); | 1413 return ParseThrowStatement(ok); |
| 1422 break; | |
| 1423 | 1414 |
| 1424 case Token::TRY: { | 1415 case Token::TRY: { |
| 1425 // NOTE: It is somewhat complicated to have labels on | 1416 // NOTE: It is somewhat complicated to have labels on |
| 1426 // try-statements. When breaking out of a try-finally statement, | 1417 // try-statements. When breaking out of a try-finally statement, |
| 1427 // one must take great care not to treat it as a | 1418 // one must take great care not to treat it as a |
| 1428 // fall-through. It is much easier just to wrap the entire | 1419 // fall-through. It is much easier just to wrap the entire |
| 1429 // try-statement in a statement block and put the labels there | 1420 // try-statement in a statement block and put the labels there |
| 1430 Block* result = factory()->NewBlock(labels, 1, false); | 1421 Block* result = |
| 1422 factory()->NewBlock(labels, 1, false, RelocInfo::kNoPosition); |
| 1431 Target target(&this->target_stack_, result); | 1423 Target target(&this->target_stack_, result); |
| 1432 TryStatement* statement = ParseTryStatement(CHECK_OK); | 1424 TryStatement* statement = ParseTryStatement(CHECK_OK); |
| 1433 if (statement) { | |
| 1434 statement->set_statement_pos(statement_pos); | |
| 1435 } | |
| 1436 if (result) result->AddStatement(statement, zone()); | 1425 if (result) result->AddStatement(statement, zone()); |
| 1437 return result; | 1426 return result; |
| 1438 } | 1427 } |
| 1439 | 1428 |
| 1440 case Token::FUNCTION: { | 1429 case Token::FUNCTION: { |
| 1441 // FunctionDeclaration is only allowed in the context of SourceElements | 1430 // FunctionDeclaration is only allowed in the context of SourceElements |
| 1442 // (Ecma 262 5th Edition, clause 14): | 1431 // (Ecma 262 5th Edition, clause 14): |
| 1443 // SourceElement: | 1432 // SourceElement: |
| 1444 // Statement | 1433 // Statement |
| 1445 // FunctionDeclaration | 1434 // FunctionDeclaration |
| 1446 // Common language extension is to allow function declaration in place | 1435 // Common language extension is to allow function declaration in place |
| 1447 // of any statement. This language extension is disabled in strict mode. | 1436 // of any statement. This language extension is disabled in strict mode. |
| 1448 // | 1437 // |
| 1449 // In Harmony mode, this case also handles the extension: | 1438 // In Harmony mode, this case also handles the extension: |
| 1450 // Statement: | 1439 // Statement: |
| 1451 // GeneratorDeclaration | 1440 // GeneratorDeclaration |
| 1452 if (!top_scope_->is_classic_mode()) { | 1441 if (!top_scope_->is_classic_mode()) { |
| 1453 ReportMessageAt(scanner().peek_location(), "strict_function", | 1442 ReportMessageAt(scanner().peek_location(), "strict_function", |
| 1454 Vector<const char*>::empty()); | 1443 Vector<const char*>::empty()); |
| 1455 *ok = false; | 1444 *ok = false; |
| 1456 return NULL; | 1445 return NULL; |
| 1457 } | 1446 } |
| 1458 return ParseFunctionDeclaration(NULL, ok); | 1447 return ParseFunctionDeclaration(NULL, ok); |
| 1459 } | 1448 } |
| 1460 | 1449 |
| 1461 case Token::DEBUGGER: | 1450 case Token::DEBUGGER: |
| 1462 stmt = ParseDebuggerStatement(ok); | 1451 return ParseDebuggerStatement(ok); |
| 1463 break; | |
| 1464 | 1452 |
| 1465 default: | 1453 default: |
| 1466 stmt = ParseExpressionOrLabelledStatement(labels, ok); | 1454 return ParseExpressionOrLabelledStatement(labels, ok); |
| 1467 } | 1455 } |
| 1468 | |
| 1469 // Store the source position of the statement | |
| 1470 if (stmt != NULL) stmt->set_statement_pos(statement_pos); | |
| 1471 return stmt; | |
| 1472 } | 1456 } |
| 1473 | 1457 |
| 1474 | 1458 |
| 1475 VariableProxy* Parser::NewUnresolved( | 1459 VariableProxy* Parser::NewUnresolved( |
| 1476 Handle<String> name, VariableMode mode, Interface* interface) { | 1460 Handle<String> name, VariableMode mode, Interface* interface) { |
| 1477 // If we are inside a function, a declaration of a var/const variable is a | 1461 // If we are inside a function, a declaration of a var/const variable is a |
| 1478 // truly local variable, and the scope of the variable is always the function | 1462 // truly local variable, and the scope of the variable is always the function |
| 1479 // scope. | 1463 // scope. |
| 1480 // Let/const variables in harmony mode are always added to the immediately | 1464 // Let/const variables in harmony mode are always added to the immediately |
| 1481 // enclosing scope. | 1465 // enclosing scope. |
| 1482 return DeclarationScope(mode)->NewUnresolved( | 1466 return DeclarationScope(mode)->NewUnresolved( |
| 1483 factory(), name, interface, scanner().location().beg_pos); | 1467 factory(), name, interface, position()); |
| 1484 } | 1468 } |
| 1485 | 1469 |
| 1486 | 1470 |
| 1487 void Parser::Declare(Declaration* declaration, bool resolve, bool* ok) { | 1471 void Parser::Declare(Declaration* declaration, bool resolve, bool* ok) { |
| 1488 VariableProxy* proxy = declaration->proxy(); | 1472 VariableProxy* proxy = declaration->proxy(); |
| 1489 Handle<String> name = proxy->name(); | 1473 Handle<String> name = proxy->name(); |
| 1490 VariableMode mode = declaration->mode(); | 1474 VariableMode mode = declaration->mode(); |
| 1491 Scope* declaration_scope = DeclarationScope(mode); | 1475 Scope* declaration_scope = DeclarationScope(mode); |
| 1492 Variable* var = NULL; | 1476 Variable* var = NULL; |
| 1493 | 1477 |
| (...skipping 146 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1640 } | 1624 } |
| 1641 } | 1625 } |
| 1642 } | 1626 } |
| 1643 | 1627 |
| 1644 | 1628 |
| 1645 // Language extension which is only enabled for source files loaded | 1629 // Language extension which is only enabled for source files loaded |
| 1646 // through the API's extension mechanism. A native function | 1630 // through the API's extension mechanism. A native function |
| 1647 // declaration is resolved by looking up the function through a | 1631 // declaration is resolved by looking up the function through a |
| 1648 // callback provided by the extension. | 1632 // callback provided by the extension. |
| 1649 Statement* Parser::ParseNativeDeclaration(bool* ok) { | 1633 Statement* Parser::ParseNativeDeclaration(bool* ok) { |
| 1634 int pos = peek_position(); |
| 1650 Expect(Token::FUNCTION, CHECK_OK); | 1635 Expect(Token::FUNCTION, CHECK_OK); |
| 1651 Handle<String> name = ParseIdentifier(CHECK_OK); | 1636 Handle<String> name = ParseIdentifier(CHECK_OK); |
| 1652 Expect(Token::LPAREN, CHECK_OK); | 1637 Expect(Token::LPAREN, CHECK_OK); |
| 1653 bool done = (peek() == Token::RPAREN); | 1638 bool done = (peek() == Token::RPAREN); |
| 1654 while (!done) { | 1639 while (!done) { |
| 1655 ParseIdentifier(CHECK_OK); | 1640 ParseIdentifier(CHECK_OK); |
| 1656 done = (peek() == Token::RPAREN); | 1641 done = (peek() == Token::RPAREN); |
| 1657 if (!done) { | 1642 if (!done) { |
| 1658 Expect(Token::COMMA, CHECK_OK); | 1643 Expect(Token::COMMA, CHECK_OK); |
| 1659 } | 1644 } |
| 1660 } | 1645 } |
| 1661 Expect(Token::RPAREN, CHECK_OK); | 1646 Expect(Token::RPAREN, CHECK_OK); |
| 1662 Expect(Token::SEMICOLON, CHECK_OK); | 1647 Expect(Token::SEMICOLON, CHECK_OK); |
| 1663 | 1648 |
| 1664 // Make sure that the function containing the native declaration | 1649 // Make sure that the function containing the native declaration |
| 1665 // isn't lazily compiled. The extension structures are only | 1650 // isn't lazily compiled. The extension structures are only |
| 1666 // accessible while parsing the first time not when reparsing | 1651 // accessible while parsing the first time not when reparsing |
| 1667 // because of lazy compilation. | 1652 // because of lazy compilation. |
| 1668 DeclarationScope(VAR)->ForceEagerCompilation(); | 1653 DeclarationScope(VAR)->ForceEagerCompilation(); |
| 1669 | 1654 |
| 1670 // TODO(1240846): It's weird that native function declarations are | 1655 // TODO(1240846): It's weird that native function declarations are |
| 1671 // introduced dynamically when we meet their declarations, whereas | 1656 // introduced dynamically when we meet their declarations, whereas |
| 1672 // other functions are set up when entering the surrounding scope. | 1657 // other functions are set up when entering the surrounding scope. |
| 1673 VariableProxy* proxy = NewUnresolved(name, VAR, Interface::NewValue()); | 1658 VariableProxy* proxy = NewUnresolved(name, VAR, Interface::NewValue()); |
| 1674 Declaration* declaration = | 1659 Declaration* declaration = |
| 1675 factory()->NewVariableDeclaration(proxy, VAR, top_scope_); | 1660 factory()->NewVariableDeclaration(proxy, VAR, top_scope_, pos); |
| 1676 Declare(declaration, true, CHECK_OK); | 1661 Declare(declaration, true, CHECK_OK); |
| 1677 NativeFunctionLiteral* lit = | 1662 NativeFunctionLiteral* lit = factory()->NewNativeFunctionLiteral( |
| 1678 factory()->NewNativeFunctionLiteral(name, extension_); | 1663 name, extension_, RelocInfo::kNoPosition); |
| 1679 return factory()->NewExpressionStatement( | 1664 return factory()->NewExpressionStatement( |
| 1680 factory()->NewAssignment( | 1665 factory()->NewAssignment( |
| 1681 Token::INIT_VAR, proxy, lit, RelocInfo::kNoPosition)); | 1666 Token::INIT_VAR, proxy, lit, RelocInfo::kNoPosition), |
| 1667 pos); |
| 1682 } | 1668 } |
| 1683 | 1669 |
| 1684 | 1670 |
| 1685 Statement* Parser::ParseFunctionDeclaration(ZoneStringList* names, bool* ok) { | 1671 Statement* Parser::ParseFunctionDeclaration(ZoneStringList* names, bool* ok) { |
| 1686 // FunctionDeclaration :: | 1672 // FunctionDeclaration :: |
| 1687 // 'function' Identifier '(' FormalParameterListopt ')' '{' FunctionBody '}' | 1673 // 'function' Identifier '(' FormalParameterListopt ')' '{' FunctionBody '}' |
| 1688 // GeneratorDeclaration :: | 1674 // GeneratorDeclaration :: |
| 1689 // 'function' '*' Identifier '(' FormalParameterListopt ')' | 1675 // 'function' '*' Identifier '(' FormalParameterListopt ')' |
| 1690 // '{' FunctionBody '}' | 1676 // '{' FunctionBody '}' |
| 1691 Expect(Token::FUNCTION, CHECK_OK); | 1677 Expect(Token::FUNCTION, CHECK_OK); |
| 1692 int function_token_position = scanner().location().beg_pos; | 1678 int pos = position(); |
| 1693 bool is_generator = allow_generators() && Check(Token::MUL); | 1679 bool is_generator = allow_generators() && Check(Token::MUL); |
| 1694 bool is_strict_reserved = false; | 1680 bool is_strict_reserved = false; |
| 1695 Handle<String> name = ParseIdentifierOrStrictReservedWord( | 1681 Handle<String> name = ParseIdentifierOrStrictReservedWord( |
| 1696 &is_strict_reserved, CHECK_OK); | 1682 &is_strict_reserved, CHECK_OK); |
| 1697 FunctionLiteral* fun = ParseFunctionLiteral(name, | 1683 FunctionLiteral* fun = ParseFunctionLiteral(name, |
| 1698 is_strict_reserved, | 1684 is_strict_reserved, |
| 1699 is_generator, | 1685 is_generator, |
| 1700 function_token_position, | 1686 pos, |
| 1701 FunctionLiteral::DECLARATION, | 1687 FunctionLiteral::DECLARATION, |
| 1702 CHECK_OK); | 1688 CHECK_OK); |
| 1703 // Even if we're not at the top-level of the global or a function | 1689 // Even if we're not at the top-level of the global or a function |
| 1704 // scope, we treat it as such and introduce the function with its | 1690 // scope, we treat it as such and introduce the function with its |
| 1705 // initial value upon entering the corresponding scope. | 1691 // initial value upon entering the corresponding scope. |
| 1706 // In extended mode, a function behaves as a lexical binding, except in the | 1692 // In extended mode, a function behaves as a lexical binding, except in the |
| 1707 // global scope. | 1693 // global scope. |
| 1708 VariableMode mode = | 1694 VariableMode mode = |
| 1709 is_extended_mode() && !top_scope_->is_global_scope() ? LET : VAR; | 1695 is_extended_mode() && !top_scope_->is_global_scope() ? LET : VAR; |
| 1710 VariableProxy* proxy = NewUnresolved(name, mode, Interface::NewValue()); | 1696 VariableProxy* proxy = NewUnresolved(name, mode, Interface::NewValue()); |
| 1711 Declaration* declaration = | 1697 Declaration* declaration = |
| 1712 factory()->NewFunctionDeclaration(proxy, mode, fun, top_scope_); | 1698 factory()->NewFunctionDeclaration(proxy, mode, fun, top_scope_, pos); |
| 1713 Declare(declaration, true, CHECK_OK); | 1699 Declare(declaration, true, CHECK_OK); |
| 1714 if (names) names->Add(name, zone()); | 1700 if (names) names->Add(name, zone()); |
| 1715 return factory()->NewEmptyStatement(); | 1701 return factory()->NewEmptyStatement(RelocInfo::kNoPosition); |
| 1716 } | 1702 } |
| 1717 | 1703 |
| 1718 | 1704 |
| 1719 Block* Parser::ParseBlock(ZoneStringList* labels, bool* ok) { | 1705 Block* Parser::ParseBlock(ZoneStringList* labels, bool* ok) { |
| 1720 if (top_scope_->is_extended_mode()) return ParseScopedBlock(labels, ok); | 1706 if (top_scope_->is_extended_mode()) return ParseScopedBlock(labels, ok); |
| 1721 | 1707 |
| 1722 // Block :: | 1708 // Block :: |
| 1723 // '{' Statement* '}' | 1709 // '{' Statement* '}' |
| 1724 | 1710 |
| 1725 // Note that a Block does not introduce a new execution scope! | 1711 // Note that a Block does not introduce a new execution scope! |
| 1726 // (ECMA-262, 3rd, 12.2) | 1712 // (ECMA-262, 3rd, 12.2) |
| 1727 // | 1713 // |
| 1728 // Construct block expecting 16 statements. | 1714 // Construct block expecting 16 statements. |
| 1729 Block* result = factory()->NewBlock(labels, 16, false); | 1715 Block* result = |
| 1716 factory()->NewBlock(labels, 16, false, RelocInfo::kNoPosition); |
| 1730 Target target(&this->target_stack_, result); | 1717 Target target(&this->target_stack_, result); |
| 1731 Expect(Token::LBRACE, CHECK_OK); | 1718 Expect(Token::LBRACE, CHECK_OK); |
| 1732 while (peek() != Token::RBRACE) { | 1719 while (peek() != Token::RBRACE) { |
| 1733 Statement* stat = ParseStatement(NULL, CHECK_OK); | 1720 Statement* stat = ParseStatement(NULL, CHECK_OK); |
| 1734 if (stat && !stat->IsEmpty()) { | 1721 if (stat && !stat->IsEmpty()) { |
| 1735 result->AddStatement(stat, zone()); | 1722 result->AddStatement(stat, zone()); |
| 1736 } | 1723 } |
| 1737 } | 1724 } |
| 1738 Expect(Token::RBRACE, CHECK_OK); | 1725 Expect(Token::RBRACE, CHECK_OK); |
| 1739 return result; | 1726 return result; |
| 1740 } | 1727 } |
| 1741 | 1728 |
| 1742 | 1729 |
| 1743 Block* Parser::ParseScopedBlock(ZoneStringList* labels, bool* ok) { | 1730 Block* Parser::ParseScopedBlock(ZoneStringList* labels, bool* ok) { |
| 1744 // The harmony mode uses block elements instead of statements. | 1731 // The harmony mode uses block elements instead of statements. |
| 1745 // | 1732 // |
| 1746 // Block :: | 1733 // Block :: |
| 1747 // '{' BlockElement* '}' | 1734 // '{' BlockElement* '}' |
| 1748 | 1735 |
| 1749 // Construct block expecting 16 statements. | 1736 // Construct block expecting 16 statements. |
| 1750 Block* body = factory()->NewBlock(labels, 16, false); | 1737 Block* body = |
| 1738 factory()->NewBlock(labels, 16, false, RelocInfo::kNoPosition); |
| 1751 Scope* block_scope = NewScope(top_scope_, BLOCK_SCOPE); | 1739 Scope* block_scope = NewScope(top_scope_, BLOCK_SCOPE); |
| 1752 | 1740 |
| 1753 // Parse the statements and collect escaping labels. | 1741 // Parse the statements and collect escaping labels. |
| 1754 Expect(Token::LBRACE, CHECK_OK); | 1742 Expect(Token::LBRACE, CHECK_OK); |
| 1755 block_scope->set_start_position(scanner().location().beg_pos); | 1743 block_scope->set_start_position(scanner().location().beg_pos); |
| 1756 { BlockState block_state(this, block_scope); | 1744 { BlockState block_state(this, block_scope); |
| 1757 TargetCollector collector(zone()); | 1745 TargetCollector collector(zone()); |
| 1758 Target target(&this->target_stack_, &collector); | 1746 Target target(&this->target_stack_, &collector); |
| 1759 Target target_body(&this->target_stack_, body); | 1747 Target target_body(&this->target_stack_, body); |
| 1760 | 1748 |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1810 // The ES6 Draft Rev3 specifies the following grammar for const declarations | 1798 // The ES6 Draft Rev3 specifies the following grammar for const declarations |
| 1811 // | 1799 // |
| 1812 // ConstDeclaration :: | 1800 // ConstDeclaration :: |
| 1813 // const ConstBinding (',' ConstBinding)* ';' | 1801 // const ConstBinding (',' ConstBinding)* ';' |
| 1814 // ConstBinding :: | 1802 // ConstBinding :: |
| 1815 // Identifier '=' AssignmentExpression | 1803 // Identifier '=' AssignmentExpression |
| 1816 // | 1804 // |
| 1817 // TODO(ES6): | 1805 // TODO(ES6): |
| 1818 // ConstBinding :: | 1806 // ConstBinding :: |
| 1819 // BindingPattern '=' AssignmentExpression | 1807 // BindingPattern '=' AssignmentExpression |
| 1808 |
| 1809 int pos = peek_position(); |
| 1820 VariableMode mode = VAR; | 1810 VariableMode mode = VAR; |
| 1821 // True if the binding needs initialization. 'let' and 'const' declared | 1811 // True if the binding needs initialization. 'let' and 'const' declared |
| 1822 // bindings are created uninitialized by their declaration nodes and | 1812 // bindings are created uninitialized by their declaration nodes and |
| 1823 // need initialization. 'var' declared bindings are always initialized | 1813 // need initialization. 'var' declared bindings are always initialized |
| 1824 // immediately by their declaration nodes. | 1814 // immediately by their declaration nodes. |
| 1825 bool needs_init = false; | 1815 bool needs_init = false; |
| 1826 bool is_const = false; | 1816 bool is_const = false; |
| 1827 Token::Value init_op = Token::INIT_VAR; | 1817 Token::Value init_op = Token::INIT_VAR; |
| 1828 if (peek() == Token::VAR) { | 1818 if (peek() == Token::VAR) { |
| 1829 Consume(Token::VAR); | 1819 Consume(Token::VAR); |
| (...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1895 // Scope declaration, and rewrite the source-level initialization into an | 1885 // Scope declaration, and rewrite the source-level initialization into an |
| 1896 // assignment statement. We use a block to collect multiple assignments. | 1886 // assignment statement. We use a block to collect multiple assignments. |
| 1897 // | 1887 // |
| 1898 // We mark the block as initializer block because we don't want the | 1888 // We mark the block as initializer block because we don't want the |
| 1899 // rewriter to add a '.result' assignment to such a block (to get compliant | 1889 // rewriter to add a '.result' assignment to such a block (to get compliant |
| 1900 // behavior for code such as print(eval('var x = 7')), and for cosmetic | 1890 // behavior for code such as print(eval('var x = 7')), and for cosmetic |
| 1901 // reasons when pretty-printing. Also, unless an assignment (initialization) | 1891 // reasons when pretty-printing. Also, unless an assignment (initialization) |
| 1902 // is inside an initializer block, it is ignored. | 1892 // is inside an initializer block, it is ignored. |
| 1903 // | 1893 // |
| 1904 // Create new block with one expected declaration. | 1894 // Create new block with one expected declaration. |
| 1905 Block* block = factory()->NewBlock(NULL, 1, true); | 1895 Block* block = factory()->NewBlock(NULL, 1, true, pos); |
| 1906 int nvars = 0; // the number of variables declared | 1896 int nvars = 0; // the number of variables declared |
| 1907 Handle<String> name; | 1897 Handle<String> name; |
| 1908 do { | 1898 do { |
| 1909 if (fni_ != NULL) fni_->Enter(); | 1899 if (fni_ != NULL) fni_->Enter(); |
| 1910 | 1900 |
| 1911 // Parse variable name. | 1901 // Parse variable name. |
| 1912 if (nvars > 0) Consume(Token::COMMA); | 1902 if (nvars > 0) Consume(Token::COMMA); |
| 1913 name = ParseIdentifier(CHECK_OK); | 1903 name = ParseIdentifier(CHECK_OK); |
| 1914 if (fni_ != NULL) fni_->PushVariableName(name); | 1904 if (fni_ != NULL) fni_->PushVariableName(name); |
| 1915 | 1905 |
| (...skipping 16 matching lines...) Expand all Loading... |
| 1932 // If we have a const declaration, in an inner scope, the proxy is always | 1922 // If we have a const declaration, in an inner scope, the proxy is always |
| 1933 // bound to the declared variable (independent of possibly surrounding with | 1923 // bound to the declared variable (independent of possibly surrounding with |
| 1934 // statements). | 1924 // statements). |
| 1935 // For let/const declarations in harmony mode, we can also immediately | 1925 // For let/const declarations in harmony mode, we can also immediately |
| 1936 // pre-resolve the proxy because it resides in the same scope as the | 1926 // pre-resolve the proxy because it resides in the same scope as the |
| 1937 // declaration. | 1927 // declaration. |
| 1938 Interface* interface = | 1928 Interface* interface = |
| 1939 is_const ? Interface::NewConst() : Interface::NewValue(); | 1929 is_const ? Interface::NewConst() : Interface::NewValue(); |
| 1940 VariableProxy* proxy = NewUnresolved(name, mode, interface); | 1930 VariableProxy* proxy = NewUnresolved(name, mode, interface); |
| 1941 Declaration* declaration = | 1931 Declaration* declaration = |
| 1942 factory()->NewVariableDeclaration(proxy, mode, top_scope_); | 1932 factory()->NewVariableDeclaration(proxy, mode, top_scope_, pos); |
| 1943 Declare(declaration, mode != VAR, CHECK_OK); | 1933 Declare(declaration, mode != VAR, CHECK_OK); |
| 1944 nvars++; | 1934 nvars++; |
| 1945 if (declaration_scope->num_var_or_const() > kMaxNumFunctionLocals) { | 1935 if (declaration_scope->num_var_or_const() > kMaxNumFunctionLocals) { |
| 1946 ReportMessageAt(scanner().location(), "too_many_variables", | 1936 ReportMessageAt(scanner().location(), "too_many_variables", |
| 1947 Vector<const char*>::empty()); | 1937 Vector<const char*>::empty()); |
| 1948 *ok = false; | 1938 *ok = false; |
| 1949 return NULL; | 1939 return NULL; |
| 1950 } | 1940 } |
| 1951 if (names) names->Add(name, zone()); | 1941 if (names) names->Add(name, zone()); |
| 1952 | 1942 |
| (...skipping 19 matching lines...) Expand all Loading... |
| 1972 // is *not* syntactic sugar for: | 1962 // is *not* syntactic sugar for: |
| 1973 // | 1963 // |
| 1974 // const c; c = x; | 1964 // const c; c = x; |
| 1975 // | 1965 // |
| 1976 // The "variable" c initialized to x is the same as the declared | 1966 // The "variable" c initialized to x is the same as the declared |
| 1977 // one - there is no re-lookup (see the last parameter of the | 1967 // one - there is no re-lookup (see the last parameter of the |
| 1978 // Declare() call above). | 1968 // Declare() call above). |
| 1979 | 1969 |
| 1980 Scope* initialization_scope = is_const ? declaration_scope : top_scope_; | 1970 Scope* initialization_scope = is_const ? declaration_scope : top_scope_; |
| 1981 Expression* value = NULL; | 1971 Expression* value = NULL; |
| 1982 int position = -1; | 1972 int pos = -1; |
| 1983 // Harmony consts have non-optional initializers. | 1973 // Harmony consts have non-optional initializers. |
| 1984 if (peek() == Token::ASSIGN || mode == CONST_HARMONY) { | 1974 if (peek() == Token::ASSIGN || mode == CONST_HARMONY) { |
| 1985 Expect(Token::ASSIGN, CHECK_OK); | 1975 Expect(Token::ASSIGN, CHECK_OK); |
| 1986 position = scanner().location().beg_pos; | 1976 pos = position(); |
| 1987 value = ParseAssignmentExpression(var_context != kForStatement, CHECK_OK); | 1977 value = ParseAssignmentExpression(var_context != kForStatement, CHECK_OK); |
| 1988 // Don't infer if it is "a = function(){...}();"-like expression. | 1978 // Don't infer if it is "a = function(){...}();"-like expression. |
| 1989 if (fni_ != NULL && | 1979 if (fni_ != NULL && |
| 1990 value->AsCall() == NULL && | 1980 value->AsCall() == NULL && |
| 1991 value->AsCallNew() == NULL) { | 1981 value->AsCallNew() == NULL) { |
| 1992 fni_->Infer(); | 1982 fni_->Infer(); |
| 1993 } else { | 1983 } else { |
| 1994 fni_->RemoveLastFunction(); | 1984 fni_->RemoveLastFunction(); |
| 1995 } | 1985 } |
| 1996 if (decl_props != NULL) *decl_props = kHasInitializers; | 1986 if (decl_props != NULL) *decl_props = kHasInitializers; |
| 1997 } | 1987 } |
| 1998 | 1988 |
| 1999 // Record the end position of the initializer. | 1989 // Record the end position of the initializer. |
| 2000 if (proxy->var() != NULL) { | 1990 if (proxy->var() != NULL) { |
| 2001 proxy->var()->set_initializer_position(scanner().location().end_pos); | 1991 proxy->var()->set_initializer_position(position()); |
| 2002 } | 1992 } |
| 2003 | 1993 |
| 2004 // Make sure that 'const x' and 'let x' initialize 'x' to undefined. | 1994 // Make sure that 'const x' and 'let x' initialize 'x' to undefined. |
| 2005 if (value == NULL && needs_init) { | 1995 if (value == NULL && needs_init) { |
| 2006 value = GetLiteralUndefined(); | 1996 value = GetLiteralUndefined(position()); |
| 2007 } | 1997 } |
| 2008 | 1998 |
| 2009 // Global variable declarations must be compiled in a specific | 1999 // Global variable declarations must be compiled in a specific |
| 2010 // way. When the script containing the global variable declaration | 2000 // way. When the script containing the global variable declaration |
| 2011 // is entered, the global variable must be declared, so that if it | 2001 // is entered, the global variable must be declared, so that if it |
| 2012 // doesn't exist (on the global object itself, see ES5 errata) it | 2002 // doesn't exist (on the global object itself, see ES5 errata) it |
| 2013 // gets created with an initial undefined value. This is handled | 2003 // gets created with an initial undefined value. This is handled |
| 2014 // by the declarations part of the function representing the | 2004 // by the declarations part of the function representing the |
| 2015 // top-level global code; see Runtime::DeclareGlobalVariable. If | 2005 // top-level global code; see Runtime::DeclareGlobalVariable. If |
| 2016 // it already exists (in the object or in a prototype), it is | 2006 // it already exists (in the object or in a prototype), it is |
| 2017 // *not* touched until the variable declaration statement is | 2007 // *not* touched until the variable declaration statement is |
| 2018 // executed. | 2008 // executed. |
| 2019 // | 2009 // |
| 2020 // Executing the variable declaration statement will always | 2010 // Executing the variable declaration statement will always |
| 2021 // guarantee to give the global object a "local" variable; a | 2011 // guarantee to give the global object a "local" variable; a |
| 2022 // variable defined in the global object and not in any | 2012 // variable defined in the global object and not in any |
| 2023 // prototype. This way, global variable declarations can shadow | 2013 // prototype. This way, global variable declarations can shadow |
| 2024 // properties in the prototype chain, but only after the variable | 2014 // properties in the prototype chain, but only after the variable |
| 2025 // declaration statement has been executed. This is important in | 2015 // declaration statement has been executed. This is important in |
| 2026 // browsers where the global object (window) has lots of | 2016 // browsers where the global object (window) has lots of |
| 2027 // properties defined in prototype objects. | 2017 // properties defined in prototype objects. |
| 2028 if (initialization_scope->is_global_scope() && | 2018 if (initialization_scope->is_global_scope() && |
| 2029 !IsLexicalVariableMode(mode)) { | 2019 !IsLexicalVariableMode(mode)) { |
| 2030 // Compute the arguments for the runtime call. | 2020 // Compute the arguments for the runtime call. |
| 2031 ZoneList<Expression*>* arguments = | 2021 ZoneList<Expression*>* arguments = |
| 2032 new(zone()) ZoneList<Expression*>(3, zone()); | 2022 new(zone()) ZoneList<Expression*>(3, zone()); |
| 2033 // We have at least 1 parameter. | 2023 // We have at least 1 parameter. |
| 2034 arguments->Add(factory()->NewLiteral(name), zone()); | 2024 arguments->Add(factory()->NewLiteral(name, pos), zone()); |
| 2035 CallRuntime* initialize; | 2025 CallRuntime* initialize; |
| 2036 | 2026 |
| 2037 if (is_const) { | 2027 if (is_const) { |
| 2038 arguments->Add(value, zone()); | 2028 arguments->Add(value, zone()); |
| 2039 value = NULL; // zap the value to avoid the unnecessary assignment | 2029 value = NULL; // zap the value to avoid the unnecessary assignment |
| 2040 | 2030 |
| 2041 // Construct the call to Runtime_InitializeConstGlobal | 2031 // Construct the call to Runtime_InitializeConstGlobal |
| 2042 // and add it to the initialization statement block. | 2032 // and add it to the initialization statement block. |
| 2043 // Note that the function does different things depending on | 2033 // Note that the function does different things depending on |
| 2044 // the number of arguments (1 or 2). | 2034 // the number of arguments (1 or 2). |
| 2045 initialize = factory()->NewCallRuntime( | 2035 initialize = factory()->NewCallRuntime( |
| 2046 isolate()->factory()->InitializeConstGlobal_string(), | 2036 isolate()->factory()->InitializeConstGlobal_string(), |
| 2047 Runtime::FunctionForId(Runtime::kInitializeConstGlobal), | 2037 Runtime::FunctionForId(Runtime::kInitializeConstGlobal), |
| 2048 arguments); | 2038 arguments, pos); |
| 2049 } else { | 2039 } else { |
| 2050 // Add strict mode. | 2040 // Add strict mode. |
| 2051 // We may want to pass singleton to avoid Literal allocations. | 2041 // We may want to pass singleton to avoid Literal allocations. |
| 2052 LanguageMode language_mode = initialization_scope->language_mode(); | 2042 LanguageMode language_mode = initialization_scope->language_mode(); |
| 2053 arguments->Add(factory()->NewNumberLiteral(language_mode), zone()); | 2043 arguments->Add(factory()->NewNumberLiteral(language_mode, pos), zone()); |
| 2054 | 2044 |
| 2055 // Be careful not to assign a value to the global variable if | 2045 // Be careful not to assign a value to the global variable if |
| 2056 // we're in a with. The initialization value should not | 2046 // we're in a with. The initialization value should not |
| 2057 // necessarily be stored in the global object in that case, | 2047 // necessarily be stored in the global object in that case, |
| 2058 // which is why we need to generate a separate assignment node. | 2048 // which is why we need to generate a separate assignment node. |
| 2059 if (value != NULL && !inside_with()) { | 2049 if (value != NULL && !inside_with()) { |
| 2060 arguments->Add(value, zone()); | 2050 arguments->Add(value, zone()); |
| 2061 value = NULL; // zap the value to avoid the unnecessary assignment | 2051 value = NULL; // zap the value to avoid the unnecessary assignment |
| 2062 } | 2052 } |
| 2063 | 2053 |
| 2064 // Construct the call to Runtime_InitializeVarGlobal | 2054 // Construct the call to Runtime_InitializeVarGlobal |
| 2065 // and add it to the initialization statement block. | 2055 // and add it to the initialization statement block. |
| 2066 // Note that the function does different things depending on | 2056 // Note that the function does different things depending on |
| 2067 // the number of arguments (2 or 3). | 2057 // the number of arguments (2 or 3). |
| 2068 initialize = factory()->NewCallRuntime( | 2058 initialize = factory()->NewCallRuntime( |
| 2069 isolate()->factory()->InitializeVarGlobal_string(), | 2059 isolate()->factory()->InitializeVarGlobal_string(), |
| 2070 Runtime::FunctionForId(Runtime::kInitializeVarGlobal), | 2060 Runtime::FunctionForId(Runtime::kInitializeVarGlobal), |
| 2071 arguments); | 2061 arguments, pos); |
| 2072 } | 2062 } |
| 2073 | 2063 |
| 2074 block->AddStatement(factory()->NewExpressionStatement(initialize), | 2064 block->AddStatement( |
| 2075 zone()); | 2065 factory()->NewExpressionStatement(initialize, RelocInfo::kNoPosition), |
| 2066 zone()); |
| 2076 } else if (needs_init) { | 2067 } else if (needs_init) { |
| 2077 // Constant initializations always assign to the declared constant which | 2068 // Constant initializations always assign to the declared constant which |
| 2078 // is always at the function scope level. This is only relevant for | 2069 // is always at the function scope level. This is only relevant for |
| 2079 // dynamically looked-up variables and constants (the start context for | 2070 // dynamically looked-up variables and constants (the start context for |
| 2080 // constant lookups is always the function context, while it is the top | 2071 // constant lookups is always the function context, while it is the top |
| 2081 // context for var declared variables). Sigh... | 2072 // context for var declared variables). Sigh... |
| 2082 // For 'let' and 'const' declared variables in harmony mode the | 2073 // For 'let' and 'const' declared variables in harmony mode the |
| 2083 // initialization also always assigns to the declared variable. | 2074 // initialization also always assigns to the declared variable. |
| 2084 ASSERT(proxy != NULL); | 2075 ASSERT(proxy != NULL); |
| 2085 ASSERT(proxy->var() != NULL); | 2076 ASSERT(proxy->var() != NULL); |
| 2086 ASSERT(value != NULL); | 2077 ASSERT(value != NULL); |
| 2087 Assignment* assignment = | 2078 Assignment* assignment = |
| 2088 factory()->NewAssignment(init_op, proxy, value, position); | 2079 factory()->NewAssignment(init_op, proxy, value, pos); |
| 2089 block->AddStatement(factory()->NewExpressionStatement(assignment), | 2080 block->AddStatement( |
| 2090 zone()); | 2081 factory()->NewExpressionStatement(assignment, RelocInfo::kNoPosition), |
| 2082 zone()); |
| 2091 value = NULL; | 2083 value = NULL; |
| 2092 } | 2084 } |
| 2093 | 2085 |
| 2094 // Add an assignment node to the initialization statement block if we still | 2086 // Add an assignment node to the initialization statement block if we still |
| 2095 // have a pending initialization value. | 2087 // have a pending initialization value. |
| 2096 if (value != NULL) { | 2088 if (value != NULL) { |
| 2097 ASSERT(mode == VAR); | 2089 ASSERT(mode == VAR); |
| 2098 // 'var' initializations are simply assignments (with all the consequences | 2090 // 'var' initializations are simply assignments (with all the consequences |
| 2099 // if they are inside a 'with' statement - they may change a 'with' object | 2091 // if they are inside a 'with' statement - they may change a 'with' object |
| 2100 // property). | 2092 // property). |
| 2101 VariableProxy* proxy = | 2093 VariableProxy* proxy = |
| 2102 initialization_scope->NewUnresolved(factory(), name, interface); | 2094 initialization_scope->NewUnresolved(factory(), name, interface); |
| 2103 Assignment* assignment = | 2095 Assignment* assignment = |
| 2104 factory()->NewAssignment(init_op, proxy, value, position); | 2096 factory()->NewAssignment(init_op, proxy, value, pos); |
| 2105 block->AddStatement(factory()->NewExpressionStatement(assignment), | 2097 block->AddStatement( |
| 2106 zone()); | 2098 factory()->NewExpressionStatement(assignment, RelocInfo::kNoPosition), |
| 2099 zone()); |
| 2107 } | 2100 } |
| 2108 | 2101 |
| 2109 if (fni_ != NULL) fni_->Leave(); | 2102 if (fni_ != NULL) fni_->Leave(); |
| 2110 } while (peek() == Token::COMMA); | 2103 } while (peek() == Token::COMMA); |
| 2111 | 2104 |
| 2112 // If there was a single non-const declaration, return it in the output | 2105 // If there was a single non-const declaration, return it in the output |
| 2113 // parameter for possible use by for/in. | 2106 // parameter for possible use by for/in. |
| 2114 if (nvars == 1 && !is_const) { | 2107 if (nvars == 1 && !is_const) { |
| 2115 *out = name; | 2108 *out = name; |
| 2116 } | 2109 } |
| (...skipping 11 matching lines...) Expand all Loading... |
| 2128 | 2121 |
| 2129 return false; | 2122 return false; |
| 2130 } | 2123 } |
| 2131 | 2124 |
| 2132 | 2125 |
| 2133 Statement* Parser::ParseExpressionOrLabelledStatement(ZoneStringList* labels, | 2126 Statement* Parser::ParseExpressionOrLabelledStatement(ZoneStringList* labels, |
| 2134 bool* ok) { | 2127 bool* ok) { |
| 2135 // ExpressionStatement | LabelledStatement :: | 2128 // ExpressionStatement | LabelledStatement :: |
| 2136 // Expression ';' | 2129 // Expression ';' |
| 2137 // Identifier ':' Statement | 2130 // Identifier ':' Statement |
| 2131 int pos = peek_position(); |
| 2138 bool starts_with_idenfifier = peek_any_identifier(); | 2132 bool starts_with_idenfifier = peek_any_identifier(); |
| 2139 Expression* expr = ParseExpression(true, CHECK_OK); | 2133 Expression* expr = ParseExpression(true, CHECK_OK); |
| 2140 if (peek() == Token::COLON && starts_with_idenfifier && expr != NULL && | 2134 if (peek() == Token::COLON && starts_with_idenfifier && expr != NULL && |
| 2141 expr->AsVariableProxy() != NULL && | 2135 expr->AsVariableProxy() != NULL && |
| 2142 !expr->AsVariableProxy()->is_this()) { | 2136 !expr->AsVariableProxy()->is_this()) { |
| 2143 // Expression is a single identifier, and not, e.g., a parenthesized | 2137 // Expression is a single identifier, and not, e.g., a parenthesized |
| 2144 // identifier. | 2138 // identifier. |
| 2145 VariableProxy* var = expr->AsVariableProxy(); | 2139 VariableProxy* var = expr->AsVariableProxy(); |
| 2146 Handle<String> label = var->name(); | 2140 Handle<String> label = var->name(); |
| 2147 // TODO(1240780): We don't check for redeclaration of labels | 2141 // TODO(1240780): We don't check for redeclaration of labels |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2187 // Only expect semicolon in the former case. | 2181 // Only expect semicolon in the former case. |
| 2188 if (!FLAG_harmony_modules || | 2182 if (!FLAG_harmony_modules || |
| 2189 peek() != Token::IDENTIFIER || | 2183 peek() != Token::IDENTIFIER || |
| 2190 scanner().HasAnyLineTerminatorBeforeNext() || | 2184 scanner().HasAnyLineTerminatorBeforeNext() || |
| 2191 expr->AsVariableProxy() == NULL || | 2185 expr->AsVariableProxy() == NULL || |
| 2192 !expr->AsVariableProxy()->name()->Equals( | 2186 !expr->AsVariableProxy()->name()->Equals( |
| 2193 isolate()->heap()->module_string()) || | 2187 isolate()->heap()->module_string()) || |
| 2194 scanner().literal_contains_escapes()) { | 2188 scanner().literal_contains_escapes()) { |
| 2195 ExpectSemicolon(CHECK_OK); | 2189 ExpectSemicolon(CHECK_OK); |
| 2196 } | 2190 } |
| 2197 return factory()->NewExpressionStatement(expr); | 2191 return factory()->NewExpressionStatement(expr, pos); |
| 2198 } | 2192 } |
| 2199 | 2193 |
| 2200 | 2194 |
| 2201 IfStatement* Parser::ParseIfStatement(ZoneStringList* labels, bool* ok) { | 2195 IfStatement* Parser::ParseIfStatement(ZoneStringList* labels, bool* ok) { |
| 2202 // IfStatement :: | 2196 // IfStatement :: |
| 2203 // 'if' '(' Expression ')' Statement ('else' Statement)? | 2197 // 'if' '(' Expression ')' Statement ('else' Statement)? |
| 2204 | 2198 |
| 2199 int pos = peek_position(); |
| 2205 Expect(Token::IF, CHECK_OK); | 2200 Expect(Token::IF, CHECK_OK); |
| 2206 Expect(Token::LPAREN, CHECK_OK); | 2201 Expect(Token::LPAREN, CHECK_OK); |
| 2207 Expression* condition = ParseExpression(true, CHECK_OK); | 2202 Expression* condition = ParseExpression(true, CHECK_OK); |
| 2208 Expect(Token::RPAREN, CHECK_OK); | 2203 Expect(Token::RPAREN, CHECK_OK); |
| 2209 Statement* then_statement = ParseStatement(labels, CHECK_OK); | 2204 Statement* then_statement = ParseStatement(labels, CHECK_OK); |
| 2210 Statement* else_statement = NULL; | 2205 Statement* else_statement = NULL; |
| 2211 if (peek() == Token::ELSE) { | 2206 if (peek() == Token::ELSE) { |
| 2212 Next(); | 2207 Next(); |
| 2213 else_statement = ParseStatement(labels, CHECK_OK); | 2208 else_statement = ParseStatement(labels, CHECK_OK); |
| 2214 } else { | 2209 } else { |
| 2215 else_statement = factory()->NewEmptyStatement(); | 2210 else_statement = factory()->NewEmptyStatement(RelocInfo::kNoPosition); |
| 2216 } | 2211 } |
| 2217 return factory()->NewIfStatement(condition, then_statement, else_statement); | 2212 return factory()->NewIfStatement( |
| 2213 condition, then_statement, else_statement, pos); |
| 2218 } | 2214 } |
| 2219 | 2215 |
| 2220 | 2216 |
| 2221 Statement* Parser::ParseContinueStatement(bool* ok) { | 2217 Statement* Parser::ParseContinueStatement(bool* ok) { |
| 2222 // ContinueStatement :: | 2218 // ContinueStatement :: |
| 2223 // 'continue' Identifier? ';' | 2219 // 'continue' Identifier? ';' |
| 2224 | 2220 |
| 2221 int pos = peek_position(); |
| 2225 Expect(Token::CONTINUE, CHECK_OK); | 2222 Expect(Token::CONTINUE, CHECK_OK); |
| 2226 Handle<String> label = Handle<String>::null(); | 2223 Handle<String> label = Handle<String>::null(); |
| 2227 Token::Value tok = peek(); | 2224 Token::Value tok = peek(); |
| 2228 if (!scanner().HasAnyLineTerminatorBeforeNext() && | 2225 if (!scanner().HasAnyLineTerminatorBeforeNext() && |
| 2229 tok != Token::SEMICOLON && tok != Token::RBRACE && tok != Token::EOS) { | 2226 tok != Token::SEMICOLON && tok != Token::RBRACE && tok != Token::EOS) { |
| 2230 label = ParseIdentifier(CHECK_OK); | 2227 label = ParseIdentifier(CHECK_OK); |
| 2231 } | 2228 } |
| 2232 IterationStatement* target = NULL; | 2229 IterationStatement* target = NULL; |
| 2233 target = LookupContinueTarget(label, CHECK_OK); | 2230 target = LookupContinueTarget(label, CHECK_OK); |
| 2234 if (target == NULL) { | 2231 if (target == NULL) { |
| 2235 // Illegal continue statement. | 2232 // Illegal continue statement. |
| 2236 const char* message = "illegal_continue"; | 2233 const char* message = "illegal_continue"; |
| 2237 Vector<Handle<String> > args; | 2234 Vector<Handle<String> > args; |
| 2238 if (!label.is_null()) { | 2235 if (!label.is_null()) { |
| 2239 message = "unknown_label"; | 2236 message = "unknown_label"; |
| 2240 args = Vector<Handle<String> >(&label, 1); | 2237 args = Vector<Handle<String> >(&label, 1); |
| 2241 } | 2238 } |
| 2242 ReportMessageAt(scanner().location(), message, args); | 2239 ReportMessageAt(scanner().location(), message, args); |
| 2243 *ok = false; | 2240 *ok = false; |
| 2244 return NULL; | 2241 return NULL; |
| 2245 } | 2242 } |
| 2246 ExpectSemicolon(CHECK_OK); | 2243 ExpectSemicolon(CHECK_OK); |
| 2247 return factory()->NewContinueStatement(target); | 2244 return factory()->NewContinueStatement(target, pos); |
| 2248 } | 2245 } |
| 2249 | 2246 |
| 2250 | 2247 |
| 2251 Statement* Parser::ParseBreakStatement(ZoneStringList* labels, bool* ok) { | 2248 Statement* Parser::ParseBreakStatement(ZoneStringList* labels, bool* ok) { |
| 2252 // BreakStatement :: | 2249 // BreakStatement :: |
| 2253 // 'break' Identifier? ';' | 2250 // 'break' Identifier? ';' |
| 2254 | 2251 |
| 2252 int pos = peek_position(); |
| 2255 Expect(Token::BREAK, CHECK_OK); | 2253 Expect(Token::BREAK, CHECK_OK); |
| 2256 Handle<String> label; | 2254 Handle<String> label; |
| 2257 Token::Value tok = peek(); | 2255 Token::Value tok = peek(); |
| 2258 if (!scanner().HasAnyLineTerminatorBeforeNext() && | 2256 if (!scanner().HasAnyLineTerminatorBeforeNext() && |
| 2259 tok != Token::SEMICOLON && tok != Token::RBRACE && tok != Token::EOS) { | 2257 tok != Token::SEMICOLON && tok != Token::RBRACE && tok != Token::EOS) { |
| 2260 label = ParseIdentifier(CHECK_OK); | 2258 label = ParseIdentifier(CHECK_OK); |
| 2261 } | 2259 } |
| 2262 // Parse labeled break statements that target themselves into | 2260 // Parse labeled break statements that target themselves into |
| 2263 // empty statements, e.g. 'l1: l2: l3: break l2;' | 2261 // empty statements, e.g. 'l1: l2: l3: break l2;' |
| 2264 if (!label.is_null() && ContainsLabel(labels, label)) { | 2262 if (!label.is_null() && ContainsLabel(labels, label)) { |
| 2265 ExpectSemicolon(CHECK_OK); | 2263 ExpectSemicolon(CHECK_OK); |
| 2266 return factory()->NewEmptyStatement(); | 2264 return factory()->NewEmptyStatement(pos); |
| 2267 } | 2265 } |
| 2268 BreakableStatement* target = NULL; | 2266 BreakableStatement* target = NULL; |
| 2269 target = LookupBreakTarget(label, CHECK_OK); | 2267 target = LookupBreakTarget(label, CHECK_OK); |
| 2270 if (target == NULL) { | 2268 if (target == NULL) { |
| 2271 // Illegal break statement. | 2269 // Illegal break statement. |
| 2272 const char* message = "illegal_break"; | 2270 const char* message = "illegal_break"; |
| 2273 Vector<Handle<String> > args; | 2271 Vector<Handle<String> > args; |
| 2274 if (!label.is_null()) { | 2272 if (!label.is_null()) { |
| 2275 message = "unknown_label"; | 2273 message = "unknown_label"; |
| 2276 args = Vector<Handle<String> >(&label, 1); | 2274 args = Vector<Handle<String> >(&label, 1); |
| 2277 } | 2275 } |
| 2278 ReportMessageAt(scanner().location(), message, args); | 2276 ReportMessageAt(scanner().location(), message, args); |
| 2279 *ok = false; | 2277 *ok = false; |
| 2280 return NULL; | 2278 return NULL; |
| 2281 } | 2279 } |
| 2282 ExpectSemicolon(CHECK_OK); | 2280 ExpectSemicolon(CHECK_OK); |
| 2283 return factory()->NewBreakStatement(target); | 2281 return factory()->NewBreakStatement(target, pos); |
| 2284 } | 2282 } |
| 2285 | 2283 |
| 2286 | 2284 |
| 2287 Statement* Parser::ParseReturnStatement(bool* ok) { | 2285 Statement* Parser::ParseReturnStatement(bool* ok) { |
| 2288 // ReturnStatement :: | 2286 // ReturnStatement :: |
| 2289 // 'return' Expression? ';' | 2287 // 'return' Expression? ';' |
| 2290 | 2288 |
| 2291 // Consume the return token. It is necessary to do the before | 2289 // Consume the return token. It is necessary to do that before |
| 2292 // reporting any errors on it, because of the way errors are | 2290 // reporting any errors on it, because of the way errors are |
| 2293 // reported (underlining). | 2291 // reported (underlining). |
| 2294 Expect(Token::RETURN, CHECK_OK); | 2292 Expect(Token::RETURN, CHECK_OK); |
| 2293 int pos = position(); |
| 2295 | 2294 |
| 2296 Token::Value tok = peek(); | 2295 Token::Value tok = peek(); |
| 2297 Statement* result; | 2296 Statement* result; |
| 2298 Expression* return_value; | 2297 Expression* return_value; |
| 2299 if (scanner().HasAnyLineTerminatorBeforeNext() || | 2298 if (scanner().HasAnyLineTerminatorBeforeNext() || |
| 2300 tok == Token::SEMICOLON || | 2299 tok == Token::SEMICOLON || |
| 2301 tok == Token::RBRACE || | 2300 tok == Token::RBRACE || |
| 2302 tok == Token::EOS) { | 2301 tok == Token::EOS) { |
| 2303 return_value = GetLiteralUndefined(); | 2302 return_value = GetLiteralUndefined(position()); |
| 2304 } else { | 2303 } else { |
| 2305 return_value = ParseExpression(true, CHECK_OK); | 2304 return_value = ParseExpression(true, CHECK_OK); |
| 2306 } | 2305 } |
| 2307 ExpectSemicolon(CHECK_OK); | 2306 ExpectSemicolon(CHECK_OK); |
| 2308 if (is_generator()) { | 2307 if (is_generator()) { |
| 2309 Expression* generator = factory()->NewVariableProxy( | 2308 Expression* generator = factory()->NewVariableProxy( |
| 2310 current_function_state_->generator_object_variable()); | 2309 current_function_state_->generator_object_variable()); |
| 2311 Expression* yield = factory()->NewYield( | 2310 Expression* yield = factory()->NewYield( |
| 2312 generator, return_value, Yield::FINAL, RelocInfo::kNoPosition); | 2311 generator, return_value, Yield::FINAL, pos); |
| 2313 result = factory()->NewExpressionStatement(yield); | 2312 result = factory()->NewExpressionStatement(yield, pos); |
| 2314 } else { | 2313 } else { |
| 2315 result = factory()->NewReturnStatement(return_value); | 2314 result = factory()->NewReturnStatement(return_value, pos); |
| 2316 } | 2315 } |
| 2317 | 2316 |
| 2318 // An ECMAScript program is considered syntactically incorrect if it | 2317 // An ECMAScript program is considered syntactically incorrect if it |
| 2319 // contains a return statement that is not within the body of a | 2318 // contains a return statement that is not within the body of a |
| 2320 // function. See ECMA-262, section 12.9, page 67. | 2319 // function. See ECMA-262, section 12.9, page 67. |
| 2321 // | 2320 // |
| 2322 // To be consistent with KJS we report the syntax error at runtime. | 2321 // To be consistent with KJS we report the syntax error at runtime. |
| 2323 Scope* declaration_scope = top_scope_->DeclarationScope(); | 2322 Scope* declaration_scope = top_scope_->DeclarationScope(); |
| 2324 if (declaration_scope->is_global_scope() || | 2323 if (declaration_scope->is_global_scope() || |
| 2325 declaration_scope->is_eval_scope()) { | 2324 declaration_scope->is_eval_scope()) { |
| 2326 Handle<String> message = isolate()->factory()->illegal_return_string(); | 2325 Handle<String> message = isolate()->factory()->illegal_return_string(); |
| 2327 Expression* throw_error = | 2326 Expression* throw_error = |
| 2328 NewThrowSyntaxError(message, Handle<Object>::null()); | 2327 NewThrowSyntaxError(message, Handle<Object>::null()); |
| 2329 return factory()->NewExpressionStatement(throw_error); | 2328 return factory()->NewExpressionStatement(throw_error, pos); |
| 2330 } | 2329 } |
| 2331 return result; | 2330 return result; |
| 2332 } | 2331 } |
| 2333 | 2332 |
| 2334 | 2333 |
| 2335 Statement* Parser::ParseWithStatement(ZoneStringList* labels, bool* ok) { | 2334 Statement* Parser::ParseWithStatement(ZoneStringList* labels, bool* ok) { |
| 2336 // WithStatement :: | 2335 // WithStatement :: |
| 2337 // 'with' '(' Expression ')' Statement | 2336 // 'with' '(' Expression ')' Statement |
| 2338 | 2337 |
| 2339 Expect(Token::WITH, CHECK_OK); | 2338 Expect(Token::WITH, CHECK_OK); |
| 2339 int pos = position(); |
| 2340 | 2340 |
| 2341 if (!top_scope_->is_classic_mode()) { | 2341 if (!top_scope_->is_classic_mode()) { |
| 2342 ReportMessage("strict_mode_with", Vector<const char*>::empty()); | 2342 ReportMessage("strict_mode_with", Vector<const char*>::empty()); |
| 2343 *ok = false; | 2343 *ok = false; |
| 2344 return NULL; | 2344 return NULL; |
| 2345 } | 2345 } |
| 2346 | 2346 |
| 2347 Expect(Token::LPAREN, CHECK_OK); | 2347 Expect(Token::LPAREN, CHECK_OK); |
| 2348 Expression* expr = ParseExpression(true, CHECK_OK); | 2348 Expression* expr = ParseExpression(true, CHECK_OK); |
| 2349 Expect(Token::RPAREN, CHECK_OK); | 2349 Expect(Token::RPAREN, CHECK_OK); |
| 2350 | 2350 |
| 2351 top_scope_->DeclarationScope()->RecordWithStatement(); | 2351 top_scope_->DeclarationScope()->RecordWithStatement(); |
| 2352 Scope* with_scope = NewScope(top_scope_, WITH_SCOPE); | 2352 Scope* with_scope = NewScope(top_scope_, WITH_SCOPE); |
| 2353 Statement* stmt; | 2353 Statement* stmt; |
| 2354 { BlockState block_state(this, with_scope); | 2354 { BlockState block_state(this, with_scope); |
| 2355 with_scope->set_start_position(scanner().peek_location().beg_pos); | 2355 with_scope->set_start_position(scanner().peek_location().beg_pos); |
| 2356 stmt = ParseStatement(labels, CHECK_OK); | 2356 stmt = ParseStatement(labels, CHECK_OK); |
| 2357 with_scope->set_end_position(scanner().location().end_pos); | 2357 with_scope->set_end_position(scanner().location().end_pos); |
| 2358 } | 2358 } |
| 2359 return factory()->NewWithStatement(with_scope, expr, stmt); | 2359 return factory()->NewWithStatement(with_scope, expr, stmt, pos); |
| 2360 } | 2360 } |
| 2361 | 2361 |
| 2362 | 2362 |
| 2363 CaseClause* Parser::ParseCaseClause(bool* default_seen_ptr, bool* ok) { | 2363 CaseClause* Parser::ParseCaseClause(bool* default_seen_ptr, bool* ok) { |
| 2364 // CaseClause :: | 2364 // CaseClause :: |
| 2365 // 'case' Expression ':' Statement* | 2365 // 'case' Expression ':' Statement* |
| 2366 // 'default' ':' Statement* | 2366 // 'default' ':' Statement* |
| 2367 | 2367 |
| 2368 Expression* label = NULL; // NULL expression indicates default case | 2368 Expression* label = NULL; // NULL expression indicates default case |
| 2369 if (peek() == Token::CASE) { | 2369 if (peek() == Token::CASE) { |
| 2370 Expect(Token::CASE, CHECK_OK); | 2370 Expect(Token::CASE, CHECK_OK); |
| 2371 label = ParseExpression(true, CHECK_OK); | 2371 label = ParseExpression(true, CHECK_OK); |
| 2372 } else { | 2372 } else { |
| 2373 Expect(Token::DEFAULT, CHECK_OK); | 2373 Expect(Token::DEFAULT, CHECK_OK); |
| 2374 if (*default_seen_ptr) { | 2374 if (*default_seen_ptr) { |
| 2375 ReportMessage("multiple_defaults_in_switch", | 2375 ReportMessage("multiple_defaults_in_switch", |
| 2376 Vector<const char*>::empty()); | 2376 Vector<const char*>::empty()); |
| 2377 *ok = false; | 2377 *ok = false; |
| 2378 return NULL; | 2378 return NULL; |
| 2379 } | 2379 } |
| 2380 *default_seen_ptr = true; | 2380 *default_seen_ptr = true; |
| 2381 } | 2381 } |
| 2382 Expect(Token::COLON, CHECK_OK); | 2382 Expect(Token::COLON, CHECK_OK); |
| 2383 int pos = scanner().location().beg_pos; | 2383 int pos = position(); |
| 2384 ZoneList<Statement*>* statements = | 2384 ZoneList<Statement*>* statements = |
| 2385 new(zone()) ZoneList<Statement*>(5, zone()); | 2385 new(zone()) ZoneList<Statement*>(5, zone()); |
| 2386 while (peek() != Token::CASE && | 2386 while (peek() != Token::CASE && |
| 2387 peek() != Token::DEFAULT && | 2387 peek() != Token::DEFAULT && |
| 2388 peek() != Token::RBRACE) { | 2388 peek() != Token::RBRACE) { |
| 2389 Statement* stat = ParseStatement(NULL, CHECK_OK); | 2389 Statement* stat = ParseStatement(NULL, CHECK_OK); |
| 2390 statements->Add(stat, zone()); | 2390 statements->Add(stat, zone()); |
| 2391 } | 2391 } |
| 2392 | 2392 |
| 2393 return new(zone()) CaseClause(isolate(), label, statements, pos); | 2393 return factory()->NewCaseClause(label, statements, pos); |
| 2394 } | 2394 } |
| 2395 | 2395 |
| 2396 | 2396 |
| 2397 SwitchStatement* Parser::ParseSwitchStatement(ZoneStringList* labels, | 2397 SwitchStatement* Parser::ParseSwitchStatement(ZoneStringList* labels, |
| 2398 bool* ok) { | 2398 bool* ok) { |
| 2399 // SwitchStatement :: | 2399 // SwitchStatement :: |
| 2400 // 'switch' '(' Expression ')' '{' CaseClause* '}' | 2400 // 'switch' '(' Expression ')' '{' CaseClause* '}' |
| 2401 | 2401 |
| 2402 SwitchStatement* statement = factory()->NewSwitchStatement(labels); | 2402 SwitchStatement* statement = |
| 2403 factory()->NewSwitchStatement(labels, peek_position()); |
| 2403 Target target(&this->target_stack_, statement); | 2404 Target target(&this->target_stack_, statement); |
| 2404 | 2405 |
| 2405 Expect(Token::SWITCH, CHECK_OK); | 2406 Expect(Token::SWITCH, CHECK_OK); |
| 2406 Expect(Token::LPAREN, CHECK_OK); | 2407 Expect(Token::LPAREN, CHECK_OK); |
| 2407 Expression* tag = ParseExpression(true, CHECK_OK); | 2408 Expression* tag = ParseExpression(true, CHECK_OK); |
| 2408 Expect(Token::RPAREN, CHECK_OK); | 2409 Expect(Token::RPAREN, CHECK_OK); |
| 2409 | 2410 |
| 2410 bool default_seen = false; | 2411 bool default_seen = false; |
| 2411 ZoneList<CaseClause*>* cases = new(zone()) ZoneList<CaseClause*>(4, zone()); | 2412 ZoneList<CaseClause*>* cases = new(zone()) ZoneList<CaseClause*>(4, zone()); |
| 2412 Expect(Token::LBRACE, CHECK_OK); | 2413 Expect(Token::LBRACE, CHECK_OK); |
| 2413 while (peek() != Token::RBRACE) { | 2414 while (peek() != Token::RBRACE) { |
| 2414 CaseClause* clause = ParseCaseClause(&default_seen, CHECK_OK); | 2415 CaseClause* clause = ParseCaseClause(&default_seen, CHECK_OK); |
| 2415 cases->Add(clause, zone()); | 2416 cases->Add(clause, zone()); |
| 2416 } | 2417 } |
| 2417 Expect(Token::RBRACE, CHECK_OK); | 2418 Expect(Token::RBRACE, CHECK_OK); |
| 2418 | 2419 |
| 2419 if (statement) statement->Initialize(tag, cases); | 2420 if (statement) statement->Initialize(tag, cases); |
| 2420 return statement; | 2421 return statement; |
| 2421 } | 2422 } |
| 2422 | 2423 |
| 2423 | 2424 |
| 2424 Statement* Parser::ParseThrowStatement(bool* ok) { | 2425 Statement* Parser::ParseThrowStatement(bool* ok) { |
| 2425 // ThrowStatement :: | 2426 // ThrowStatement :: |
| 2426 // 'throw' Expression ';' | 2427 // 'throw' Expression ';' |
| 2427 | 2428 |
| 2428 Expect(Token::THROW, CHECK_OK); | 2429 Expect(Token::THROW, CHECK_OK); |
| 2429 int pos = scanner().location().beg_pos; | 2430 int pos = position(); |
| 2430 if (scanner().HasAnyLineTerminatorBeforeNext()) { | 2431 if (scanner().HasAnyLineTerminatorBeforeNext()) { |
| 2431 ReportMessage("newline_after_throw", Vector<const char*>::empty()); | 2432 ReportMessage("newline_after_throw", Vector<const char*>::empty()); |
| 2432 *ok = false; | 2433 *ok = false; |
| 2433 return NULL; | 2434 return NULL; |
| 2434 } | 2435 } |
| 2435 Expression* exception = ParseExpression(true, CHECK_OK); | 2436 Expression* exception = ParseExpression(true, CHECK_OK); |
| 2436 ExpectSemicolon(CHECK_OK); | 2437 ExpectSemicolon(CHECK_OK); |
| 2437 | 2438 |
| 2438 return factory()->NewExpressionStatement(factory()->NewThrow(exception, pos)); | 2439 return factory()->NewExpressionStatement( |
| 2440 factory()->NewThrow(exception, pos), pos); |
| 2439 } | 2441 } |
| 2440 | 2442 |
| 2441 | 2443 |
| 2442 TryStatement* Parser::ParseTryStatement(bool* ok) { | 2444 TryStatement* Parser::ParseTryStatement(bool* ok) { |
| 2443 // TryStatement :: | 2445 // TryStatement :: |
| 2444 // 'try' Block Catch | 2446 // 'try' Block Catch |
| 2445 // 'try' Block Finally | 2447 // 'try' Block Finally |
| 2446 // 'try' Block Catch Finally | 2448 // 'try' Block Catch Finally |
| 2447 // | 2449 // |
| 2448 // Catch :: | 2450 // Catch :: |
| 2449 // 'catch' '(' Identifier ')' Block | 2451 // 'catch' '(' Identifier ')' Block |
| 2450 // | 2452 // |
| 2451 // Finally :: | 2453 // Finally :: |
| 2452 // 'finally' Block | 2454 // 'finally' Block |
| 2453 | 2455 |
| 2454 Expect(Token::TRY, CHECK_OK); | 2456 Expect(Token::TRY, CHECK_OK); |
| 2457 int pos = position(); |
| 2455 | 2458 |
| 2456 TargetCollector try_collector(zone()); | 2459 TargetCollector try_collector(zone()); |
| 2457 Block* try_block; | 2460 Block* try_block; |
| 2458 | 2461 |
| 2459 { Target target(&this->target_stack_, &try_collector); | 2462 { Target target(&this->target_stack_, &try_collector); |
| 2460 try_block = ParseBlock(NULL, CHECK_OK); | 2463 try_block = ParseBlock(NULL, CHECK_OK); |
| 2461 } | 2464 } |
| 2462 | 2465 |
| 2463 Token::Value tok = peek(); | 2466 Token::Value tok = peek(); |
| 2464 if (tok != Token::CATCH && tok != Token::FINALLY) { | 2467 if (tok != Token::CATCH && tok != Token::FINALLY) { |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2516 // Simplify the AST nodes by converting: | 2519 // Simplify the AST nodes by converting: |
| 2517 // 'try B0 catch B1 finally B2' | 2520 // 'try B0 catch B1 finally B2' |
| 2518 // to: | 2521 // to: |
| 2519 // 'try { try B0 catch B1 } finally B2' | 2522 // 'try { try B0 catch B1 } finally B2' |
| 2520 | 2523 |
| 2521 if (catch_block != NULL && finally_block != NULL) { | 2524 if (catch_block != NULL && finally_block != NULL) { |
| 2522 // If we have both, create an inner try/catch. | 2525 // If we have both, create an inner try/catch. |
| 2523 ASSERT(catch_scope != NULL && catch_variable != NULL); | 2526 ASSERT(catch_scope != NULL && catch_variable != NULL); |
| 2524 int index = current_function_state_->NextHandlerIndex(); | 2527 int index = current_function_state_->NextHandlerIndex(); |
| 2525 TryCatchStatement* statement = factory()->NewTryCatchStatement( | 2528 TryCatchStatement* statement = factory()->NewTryCatchStatement( |
| 2526 index, try_block, catch_scope, catch_variable, catch_block); | 2529 index, try_block, catch_scope, catch_variable, catch_block, |
| 2530 RelocInfo::kNoPosition); |
| 2527 statement->set_escaping_targets(try_collector.targets()); | 2531 statement->set_escaping_targets(try_collector.targets()); |
| 2528 try_block = factory()->NewBlock(NULL, 1, false); | 2532 try_block = factory()->NewBlock(NULL, 1, false, RelocInfo::kNoPosition); |
| 2529 try_block->AddStatement(statement, zone()); | 2533 try_block->AddStatement(statement, zone()); |
| 2530 catch_block = NULL; // Clear to indicate it's been handled. | 2534 catch_block = NULL; // Clear to indicate it's been handled. |
| 2531 } | 2535 } |
| 2532 | 2536 |
| 2533 TryStatement* result = NULL; | 2537 TryStatement* result = NULL; |
| 2534 if (catch_block != NULL) { | 2538 if (catch_block != NULL) { |
| 2535 ASSERT(finally_block == NULL); | 2539 ASSERT(finally_block == NULL); |
| 2536 ASSERT(catch_scope != NULL && catch_variable != NULL); | 2540 ASSERT(catch_scope != NULL && catch_variable != NULL); |
| 2537 int index = current_function_state_->NextHandlerIndex(); | 2541 int index = current_function_state_->NextHandlerIndex(); |
| 2538 result = factory()->NewTryCatchStatement( | 2542 result = factory()->NewTryCatchStatement( |
| 2539 index, try_block, catch_scope, catch_variable, catch_block); | 2543 index, try_block, catch_scope, catch_variable, catch_block, pos); |
| 2540 } else { | 2544 } else { |
| 2541 ASSERT(finally_block != NULL); | 2545 ASSERT(finally_block != NULL); |
| 2542 int index = current_function_state_->NextHandlerIndex(); | 2546 int index = current_function_state_->NextHandlerIndex(); |
| 2543 result = factory()->NewTryFinallyStatement(index, try_block, finally_block); | 2547 result = factory()->NewTryFinallyStatement( |
| 2548 index, try_block, finally_block, pos); |
| 2544 // Combine the jump targets of the try block and the possible catch block. | 2549 // Combine the jump targets of the try block and the possible catch block. |
| 2545 try_collector.targets()->AddAll(*catch_collector.targets(), zone()); | 2550 try_collector.targets()->AddAll(*catch_collector.targets(), zone()); |
| 2546 } | 2551 } |
| 2547 | 2552 |
| 2548 result->set_escaping_targets(try_collector.targets()); | 2553 result->set_escaping_targets(try_collector.targets()); |
| 2549 return result; | 2554 return result; |
| 2550 } | 2555 } |
| 2551 | 2556 |
| 2552 | 2557 |
| 2553 DoWhileStatement* Parser::ParseDoWhileStatement(ZoneStringList* labels, | 2558 DoWhileStatement* Parser::ParseDoWhileStatement(ZoneStringList* labels, |
| 2554 bool* ok) { | 2559 bool* ok) { |
| 2555 // DoStatement :: | 2560 // DoStatement :: |
| 2556 // 'do' Statement 'while' '(' Expression ')' ';' | 2561 // 'do' Statement 'while' '(' Expression ')' ';' |
| 2557 | 2562 |
| 2558 DoWhileStatement* loop = factory()->NewDoWhileStatement(labels); | 2563 DoWhileStatement* loop = |
| 2564 factory()->NewDoWhileStatement(labels, peek_position()); |
| 2559 Target target(&this->target_stack_, loop); | 2565 Target target(&this->target_stack_, loop); |
| 2560 | 2566 |
| 2561 Expect(Token::DO, CHECK_OK); | 2567 Expect(Token::DO, CHECK_OK); |
| 2562 Statement* body = ParseStatement(NULL, CHECK_OK); | 2568 Statement* body = ParseStatement(NULL, CHECK_OK); |
| 2563 Expect(Token::WHILE, CHECK_OK); | 2569 Expect(Token::WHILE, CHECK_OK); |
| 2564 Expect(Token::LPAREN, CHECK_OK); | 2570 Expect(Token::LPAREN, CHECK_OK); |
| 2565 | 2571 |
| 2566 if (loop != NULL) { | |
| 2567 int position = scanner().location().beg_pos; | |
| 2568 loop->set_condition_position(position); | |
| 2569 } | |
| 2570 | |
| 2571 Expression* cond = ParseExpression(true, CHECK_OK); | 2572 Expression* cond = ParseExpression(true, CHECK_OK); |
| 2572 Expect(Token::RPAREN, CHECK_OK); | 2573 Expect(Token::RPAREN, CHECK_OK); |
| 2573 | 2574 |
| 2574 // Allow do-statements to be terminated with and without | 2575 // Allow do-statements to be terminated with and without |
| 2575 // semi-colons. This allows code such as 'do;while(0)return' to | 2576 // semi-colons. This allows code such as 'do;while(0)return' to |
| 2576 // parse, which would not be the case if we had used the | 2577 // parse, which would not be the case if we had used the |
| 2577 // ExpectSemicolon() functionality here. | 2578 // ExpectSemicolon() functionality here. |
| 2578 if (peek() == Token::SEMICOLON) Consume(Token::SEMICOLON); | 2579 if (peek() == Token::SEMICOLON) Consume(Token::SEMICOLON); |
| 2579 | 2580 |
| 2580 if (loop != NULL) loop->Initialize(cond, body); | 2581 if (loop != NULL) loop->Initialize(cond, body); |
| 2581 return loop; | 2582 return loop; |
| 2582 } | 2583 } |
| 2583 | 2584 |
| 2584 | 2585 |
| 2585 WhileStatement* Parser::ParseWhileStatement(ZoneStringList* labels, bool* ok) { | 2586 WhileStatement* Parser::ParseWhileStatement(ZoneStringList* labels, bool* ok) { |
| 2586 // WhileStatement :: | 2587 // WhileStatement :: |
| 2587 // 'while' '(' Expression ')' Statement | 2588 // 'while' '(' Expression ')' Statement |
| 2588 | 2589 |
| 2589 WhileStatement* loop = factory()->NewWhileStatement(labels); | 2590 WhileStatement* loop = factory()->NewWhileStatement(labels, peek_position()); |
| 2590 Target target(&this->target_stack_, loop); | 2591 Target target(&this->target_stack_, loop); |
| 2591 | 2592 |
| 2592 Expect(Token::WHILE, CHECK_OK); | 2593 Expect(Token::WHILE, CHECK_OK); |
| 2593 Expect(Token::LPAREN, CHECK_OK); | 2594 Expect(Token::LPAREN, CHECK_OK); |
| 2594 Expression* cond = ParseExpression(true, CHECK_OK); | 2595 Expression* cond = ParseExpression(true, CHECK_OK); |
| 2595 Expect(Token::RPAREN, CHECK_OK); | 2596 Expect(Token::RPAREN, CHECK_OK); |
| 2596 Statement* body = ParseStatement(NULL, CHECK_OK); | 2597 Statement* body = ParseStatement(NULL, CHECK_OK); |
| 2597 | 2598 |
| 2598 if (loop != NULL) loop->Initialize(cond, body); | 2599 if (loop != NULL) loop->Initialize(cond, body); |
| 2599 return loop; | 2600 return loop; |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2638 // var iterator = iterable; | 2639 // var iterator = iterable; |
| 2639 { | 2640 { |
| 2640 Expression* iterator_proxy = factory()->NewVariableProxy(iterator); | 2641 Expression* iterator_proxy = factory()->NewVariableProxy(iterator); |
| 2641 assign_iterator = factory()->NewAssignment( | 2642 assign_iterator = factory()->NewAssignment( |
| 2642 Token::ASSIGN, iterator_proxy, subject, RelocInfo::kNoPosition); | 2643 Token::ASSIGN, iterator_proxy, subject, RelocInfo::kNoPosition); |
| 2643 } | 2644 } |
| 2644 | 2645 |
| 2645 // var result = iterator.next(); | 2646 // var result = iterator.next(); |
| 2646 { | 2647 { |
| 2647 Expression* iterator_proxy = factory()->NewVariableProxy(iterator); | 2648 Expression* iterator_proxy = factory()->NewVariableProxy(iterator); |
| 2648 Expression* next_literal = | 2649 Expression* next_literal = factory()->NewLiteral( |
| 2649 factory()->NewLiteral(heap_factory->next_string()); | 2650 heap_factory->next_string(), RelocInfo::kNoPosition); |
| 2650 Expression* next_property = factory()->NewProperty( | 2651 Expression* next_property = factory()->NewProperty( |
| 2651 iterator_proxy, next_literal, RelocInfo::kNoPosition); | 2652 iterator_proxy, next_literal, RelocInfo::kNoPosition); |
| 2652 ZoneList<Expression*>* next_arguments = | 2653 ZoneList<Expression*>* next_arguments = |
| 2653 new(zone()) ZoneList<Expression*>(0, zone()); | 2654 new(zone()) ZoneList<Expression*>(0, zone()); |
| 2654 Expression* next_call = factory()->NewCall( | 2655 Expression* next_call = factory()->NewCall( |
| 2655 next_property, next_arguments, RelocInfo::kNoPosition); | 2656 next_property, next_arguments, RelocInfo::kNoPosition); |
| 2656 Expression* result_proxy = factory()->NewVariableProxy(result); | 2657 Expression* result_proxy = factory()->NewVariableProxy(result); |
| 2657 next_result = factory()->NewAssignment( | 2658 next_result = factory()->NewAssignment( |
| 2658 Token::ASSIGN, result_proxy, next_call, RelocInfo::kNoPosition); | 2659 Token::ASSIGN, result_proxy, next_call, RelocInfo::kNoPosition); |
| 2659 } | 2660 } |
| 2660 | 2661 |
| 2661 // result.done | 2662 // result.done |
| 2662 { | 2663 { |
| 2663 Expression* done_literal = | 2664 Expression* done_literal = factory()->NewLiteral( |
| 2664 factory()->NewLiteral(heap_factory->done_string()); | 2665 heap_factory->done_string(), RelocInfo::kNoPosition); |
| 2665 Expression* result_proxy = factory()->NewVariableProxy(result); | 2666 Expression* result_proxy = factory()->NewVariableProxy(result); |
| 2666 result_done = factory()->NewProperty( | 2667 result_done = factory()->NewProperty( |
| 2667 result_proxy, done_literal, RelocInfo::kNoPosition); | 2668 result_proxy, done_literal, RelocInfo::kNoPosition); |
| 2668 } | 2669 } |
| 2669 | 2670 |
| 2670 // each = result.value | 2671 // each = result.value |
| 2671 { | 2672 { |
| 2672 Expression* value_literal = | 2673 Expression* value_literal = factory()->NewLiteral( |
| 2673 factory()->NewLiteral(heap_factory->value_string()); | 2674 heap_factory->value_string(), RelocInfo::kNoPosition); |
| 2674 Expression* result_proxy = factory()->NewVariableProxy(result); | 2675 Expression* result_proxy = factory()->NewVariableProxy(result); |
| 2675 Expression* result_value = factory()->NewProperty( | 2676 Expression* result_value = factory()->NewProperty( |
| 2676 result_proxy, value_literal, RelocInfo::kNoPosition); | 2677 result_proxy, value_literal, RelocInfo::kNoPosition); |
| 2677 assign_each = factory()->NewAssignment( | 2678 assign_each = factory()->NewAssignment( |
| 2678 Token::ASSIGN, each, result_value, RelocInfo::kNoPosition); | 2679 Token::ASSIGN, each, result_value, RelocInfo::kNoPosition); |
| 2679 } | 2680 } |
| 2680 | 2681 |
| 2681 for_of->Initialize(each, subject, body, | 2682 for_of->Initialize(each, subject, body, |
| 2682 assign_iterator, next_result, result_done, assign_each); | 2683 assign_iterator, next_result, result_done, assign_each); |
| 2683 } else { | 2684 } else { |
| 2684 stmt->Initialize(each, subject, body); | 2685 stmt->Initialize(each, subject, body); |
| 2685 } | 2686 } |
| 2686 } | 2687 } |
| 2687 | 2688 |
| 2688 | 2689 |
| 2689 Statement* Parser::ParseForStatement(ZoneStringList* labels, bool* ok) { | 2690 Statement* Parser::ParseForStatement(ZoneStringList* labels, bool* ok) { |
| 2690 // ForStatement :: | 2691 // ForStatement :: |
| 2691 // 'for' '(' Expression? ';' Expression? ';' Expression? ')' Statement | 2692 // 'for' '(' Expression? ';' Expression? ';' Expression? ')' Statement |
| 2692 | 2693 |
| 2694 int pos = peek_position(); |
| 2693 Statement* init = NULL; | 2695 Statement* init = NULL; |
| 2694 | 2696 |
| 2695 // Create an in-between scope for let-bound iteration variables. | 2697 // Create an in-between scope for let-bound iteration variables. |
| 2696 Scope* saved_scope = top_scope_; | 2698 Scope* saved_scope = top_scope_; |
| 2697 Scope* for_scope = NewScope(top_scope_, BLOCK_SCOPE); | 2699 Scope* for_scope = NewScope(top_scope_, BLOCK_SCOPE); |
| 2698 top_scope_ = for_scope; | 2700 top_scope_ = for_scope; |
| 2699 | 2701 |
| 2700 Expect(Token::FOR, CHECK_OK); | 2702 Expect(Token::FOR, CHECK_OK); |
| 2701 Expect(Token::LPAREN, CHECK_OK); | 2703 Expect(Token::LPAREN, CHECK_OK); |
| 2702 for_scope->set_start_position(scanner().location().beg_pos); | 2704 for_scope->set_start_position(scanner().location().beg_pos); |
| 2703 if (peek() != Token::SEMICOLON) { | 2705 if (peek() != Token::SEMICOLON) { |
| 2704 if (peek() == Token::VAR || peek() == Token::CONST) { | 2706 if (peek() == Token::VAR || peek() == Token::CONST) { |
| 2705 bool is_const = peek() == Token::CONST; | 2707 bool is_const = peek() == Token::CONST; |
| 2706 Handle<String> name; | 2708 Handle<String> name; |
| 2707 VariableDeclarationProperties decl_props = kHasNoInitializers; | 2709 VariableDeclarationProperties decl_props = kHasNoInitializers; |
| 2708 Block* variable_statement = | 2710 Block* variable_statement = |
| 2709 ParseVariableDeclarations(kForStatement, &decl_props, NULL, &name, | 2711 ParseVariableDeclarations(kForStatement, &decl_props, NULL, &name, |
| 2710 CHECK_OK); | 2712 CHECK_OK); |
| 2711 bool accept_OF = decl_props == kHasNoInitializers; | 2713 bool accept_OF = decl_props == kHasNoInitializers; |
| 2712 ForEachStatement::VisitMode mode; | 2714 ForEachStatement::VisitMode mode; |
| 2713 | 2715 |
| 2714 if (!name.is_null() && CheckInOrOf(accept_OF, &mode)) { | 2716 if (!name.is_null() && CheckInOrOf(accept_OF, &mode)) { |
| 2715 Interface* interface = | 2717 Interface* interface = |
| 2716 is_const ? Interface::NewConst() : Interface::NewValue(); | 2718 is_const ? Interface::NewConst() : Interface::NewValue(); |
| 2717 ForEachStatement* loop = factory()->NewForEachStatement(mode, labels); | 2719 ForEachStatement* loop = |
| 2720 factory()->NewForEachStatement(mode, labels, pos); |
| 2718 Target target(&this->target_stack_, loop); | 2721 Target target(&this->target_stack_, loop); |
| 2719 | 2722 |
| 2720 Expression* enumerable = ParseExpression(true, CHECK_OK); | 2723 Expression* enumerable = ParseExpression(true, CHECK_OK); |
| 2721 Expect(Token::RPAREN, CHECK_OK); | 2724 Expect(Token::RPAREN, CHECK_OK); |
| 2722 | 2725 |
| 2723 VariableProxy* each = | 2726 VariableProxy* each = |
| 2724 top_scope_->NewUnresolved(factory(), name, interface); | 2727 top_scope_->NewUnresolved(factory(), name, interface); |
| 2725 Statement* body = ParseStatement(NULL, CHECK_OK); | 2728 Statement* body = ParseStatement(NULL, CHECK_OK); |
| 2726 InitializeForEachStatement(loop, each, enumerable, body); | 2729 InitializeForEachStatement(loop, each, enumerable, body); |
| 2727 Block* result = factory()->NewBlock(NULL, 2, false); | 2730 Block* result = |
| 2731 factory()->NewBlock(NULL, 2, false, RelocInfo::kNoPosition); |
| 2728 result->AddStatement(variable_statement, zone()); | 2732 result->AddStatement(variable_statement, zone()); |
| 2729 result->AddStatement(loop, zone()); | 2733 result->AddStatement(loop, zone()); |
| 2730 top_scope_ = saved_scope; | 2734 top_scope_ = saved_scope; |
| 2731 for_scope->set_end_position(scanner().location().end_pos); | 2735 for_scope->set_end_position(scanner().location().end_pos); |
| 2732 for_scope = for_scope->FinalizeBlockScope(); | 2736 for_scope = for_scope->FinalizeBlockScope(); |
| 2733 ASSERT(for_scope == NULL); | 2737 ASSERT(for_scope == NULL); |
| 2734 // Parsed for-in loop w/ variable/const declaration. | 2738 // Parsed for-in loop w/ variable/const declaration. |
| 2735 return result; | 2739 return result; |
| 2736 } else { | 2740 } else { |
| 2737 init = variable_statement; | 2741 init = variable_statement; |
| (...skipping 23 matching lines...) Expand all Loading... |
| 2761 // } | 2765 // } |
| 2762 | 2766 |
| 2763 // TODO(keuchel): Move the temporary variable to the block scope, after | 2767 // TODO(keuchel): Move the temporary variable to the block scope, after |
| 2764 // implementing stack allocated block scoped variables. | 2768 // implementing stack allocated block scoped variables. |
| 2765 Factory* heap_factory = isolate()->factory(); | 2769 Factory* heap_factory = isolate()->factory(); |
| 2766 Handle<String> tempstr = | 2770 Handle<String> tempstr = |
| 2767 heap_factory->NewConsString(heap_factory->dot_for_string(), name); | 2771 heap_factory->NewConsString(heap_factory->dot_for_string(), name); |
| 2768 Handle<String> tempname = heap_factory->InternalizeString(tempstr); | 2772 Handle<String> tempname = heap_factory->InternalizeString(tempstr); |
| 2769 Variable* temp = top_scope_->DeclarationScope()->NewTemporary(tempname); | 2773 Variable* temp = top_scope_->DeclarationScope()->NewTemporary(tempname); |
| 2770 VariableProxy* temp_proxy = factory()->NewVariableProxy(temp); | 2774 VariableProxy* temp_proxy = factory()->NewVariableProxy(temp); |
| 2771 ForEachStatement* loop = factory()->NewForEachStatement(mode, labels); | 2775 ForEachStatement* loop = |
| 2776 factory()->NewForEachStatement(mode, labels, pos); |
| 2772 Target target(&this->target_stack_, loop); | 2777 Target target(&this->target_stack_, loop); |
| 2773 | 2778 |
| 2774 // The expression does not see the loop variable. | 2779 // The expression does not see the loop variable. |
| 2775 top_scope_ = saved_scope; | 2780 top_scope_ = saved_scope; |
| 2776 Expression* enumerable = ParseExpression(true, CHECK_OK); | 2781 Expression* enumerable = ParseExpression(true, CHECK_OK); |
| 2777 top_scope_ = for_scope; | 2782 top_scope_ = for_scope; |
| 2778 Expect(Token::RPAREN, CHECK_OK); | 2783 Expect(Token::RPAREN, CHECK_OK); |
| 2779 | 2784 |
| 2780 VariableProxy* each = | 2785 VariableProxy* each = |
| 2781 top_scope_->NewUnresolved(factory(), name, Interface::NewValue()); | 2786 top_scope_->NewUnresolved(factory(), name, Interface::NewValue()); |
| 2782 Statement* body = ParseStatement(NULL, CHECK_OK); | 2787 Statement* body = ParseStatement(NULL, CHECK_OK); |
| 2783 Block* body_block = factory()->NewBlock(NULL, 3, false); | 2788 Block* body_block = |
| 2789 factory()->NewBlock(NULL, 3, false, RelocInfo::kNoPosition); |
| 2784 Assignment* assignment = factory()->NewAssignment( | 2790 Assignment* assignment = factory()->NewAssignment( |
| 2785 Token::ASSIGN, each, temp_proxy, RelocInfo::kNoPosition); | 2791 Token::ASSIGN, each, temp_proxy, RelocInfo::kNoPosition); |
| 2786 Statement* assignment_statement = | 2792 Statement* assignment_statement = factory()->NewExpressionStatement( |
| 2787 factory()->NewExpressionStatement(assignment); | 2793 assignment, RelocInfo::kNoPosition); |
| 2788 body_block->AddStatement(variable_statement, zone()); | 2794 body_block->AddStatement(variable_statement, zone()); |
| 2789 body_block->AddStatement(assignment_statement, zone()); | 2795 body_block->AddStatement(assignment_statement, zone()); |
| 2790 body_block->AddStatement(body, zone()); | 2796 body_block->AddStatement(body, zone()); |
| 2791 InitializeForEachStatement(loop, temp_proxy, enumerable, body_block); | 2797 InitializeForEachStatement(loop, temp_proxy, enumerable, body_block); |
| 2792 top_scope_ = saved_scope; | 2798 top_scope_ = saved_scope; |
| 2793 for_scope->set_end_position(scanner().location().end_pos); | 2799 for_scope->set_end_position(scanner().location().end_pos); |
| 2794 for_scope = for_scope->FinalizeBlockScope(); | 2800 for_scope = for_scope->FinalizeBlockScope(); |
| 2795 body_block->set_scope(for_scope); | 2801 body_block->set_scope(for_scope); |
| 2796 // Parsed for-in loop w/ let declaration. | 2802 // Parsed for-in loop w/ let declaration. |
| 2797 return loop; | 2803 return loop; |
| 2798 | 2804 |
| 2799 } else { | 2805 } else { |
| 2800 init = variable_statement; | 2806 init = variable_statement; |
| 2801 } | 2807 } |
| 2802 } else { | 2808 } else { |
| 2803 Expression* expression = ParseExpression(false, CHECK_OK); | 2809 Expression* expression = ParseExpression(false, CHECK_OK); |
| 2804 ForEachStatement::VisitMode mode; | 2810 ForEachStatement::VisitMode mode; |
| 2805 bool accept_OF = expression->AsVariableProxy(); | 2811 bool accept_OF = expression->AsVariableProxy(); |
| 2806 | 2812 |
| 2807 if (CheckInOrOf(accept_OF, &mode)) { | 2813 if (CheckInOrOf(accept_OF, &mode)) { |
| 2808 // Signal a reference error if the expression is an invalid | 2814 // Signal a reference error if the expression is an invalid |
| 2809 // left-hand side expression. We could report this as a syntax | 2815 // left-hand side expression. We could report this as a syntax |
| 2810 // error here but for compatibility with JSC we choose to report | 2816 // error here but for compatibility with JSC we choose to report |
| 2811 // the error at runtime. | 2817 // the error at runtime. |
| 2812 if (expression == NULL || !expression->IsValidLeftHandSide()) { | 2818 if (expression == NULL || !expression->IsValidLeftHandSide()) { |
| 2813 Handle<String> message = | 2819 Handle<String> message = |
| 2814 isolate()->factory()->invalid_lhs_in_for_in_string(); | 2820 isolate()->factory()->invalid_lhs_in_for_in_string(); |
| 2815 expression = NewThrowReferenceError(message); | 2821 expression = NewThrowReferenceError(message); |
| 2816 } | 2822 } |
| 2817 ForEachStatement* loop = factory()->NewForEachStatement(mode, labels); | 2823 ForEachStatement* loop = |
| 2824 factory()->NewForEachStatement(mode, labels, pos); |
| 2818 Target target(&this->target_stack_, loop); | 2825 Target target(&this->target_stack_, loop); |
| 2819 | 2826 |
| 2820 Expression* enumerable = ParseExpression(true, CHECK_OK); | 2827 Expression* enumerable = ParseExpression(true, CHECK_OK); |
| 2821 Expect(Token::RPAREN, CHECK_OK); | 2828 Expect(Token::RPAREN, CHECK_OK); |
| 2822 | 2829 |
| 2823 Statement* body = ParseStatement(NULL, CHECK_OK); | 2830 Statement* body = ParseStatement(NULL, CHECK_OK); |
| 2824 InitializeForEachStatement(loop, expression, enumerable, body); | 2831 InitializeForEachStatement(loop, expression, enumerable, body); |
| 2825 top_scope_ = saved_scope; | 2832 top_scope_ = saved_scope; |
| 2826 for_scope->set_end_position(scanner().location().end_pos); | 2833 for_scope->set_end_position(scanner().location().end_pos); |
| 2827 for_scope = for_scope->FinalizeBlockScope(); | 2834 for_scope = for_scope->FinalizeBlockScope(); |
| 2828 ASSERT(for_scope == NULL); | 2835 ASSERT(for_scope == NULL); |
| 2829 // Parsed for-in loop. | 2836 // Parsed for-in loop. |
| 2830 return loop; | 2837 return loop; |
| 2831 | 2838 |
| 2832 } else { | 2839 } else { |
| 2833 init = factory()->NewExpressionStatement(expression); | 2840 init = factory()->NewExpressionStatement( |
| 2841 expression, RelocInfo::kNoPosition); |
| 2834 } | 2842 } |
| 2835 } | 2843 } |
| 2836 } | 2844 } |
| 2837 | 2845 |
| 2838 // Standard 'for' loop | 2846 // Standard 'for' loop |
| 2839 ForStatement* loop = factory()->NewForStatement(labels); | 2847 ForStatement* loop = factory()->NewForStatement(labels, pos); |
| 2840 Target target(&this->target_stack_, loop); | 2848 Target target(&this->target_stack_, loop); |
| 2841 | 2849 |
| 2842 // Parsed initializer at this point. | 2850 // Parsed initializer at this point. |
| 2843 Expect(Token::SEMICOLON, CHECK_OK); | 2851 Expect(Token::SEMICOLON, CHECK_OK); |
| 2844 | 2852 |
| 2845 Expression* cond = NULL; | 2853 Expression* cond = NULL; |
| 2846 if (peek() != Token::SEMICOLON) { | 2854 if (peek() != Token::SEMICOLON) { |
| 2847 cond = ParseExpression(true, CHECK_OK); | 2855 cond = ParseExpression(true, CHECK_OK); |
| 2848 } | 2856 } |
| 2849 Expect(Token::SEMICOLON, CHECK_OK); | 2857 Expect(Token::SEMICOLON, CHECK_OK); |
| 2850 | 2858 |
| 2851 Statement* next = NULL; | 2859 Statement* next = NULL; |
| 2852 if (peek() != Token::RPAREN) { | 2860 if (peek() != Token::RPAREN) { |
| 2853 Expression* exp = ParseExpression(true, CHECK_OK); | 2861 Expression* exp = ParseExpression(true, CHECK_OK); |
| 2854 next = factory()->NewExpressionStatement(exp); | 2862 next = factory()->NewExpressionStatement(exp, RelocInfo::kNoPosition); |
| 2855 } | 2863 } |
| 2856 Expect(Token::RPAREN, CHECK_OK); | 2864 Expect(Token::RPAREN, CHECK_OK); |
| 2857 | 2865 |
| 2858 Statement* body = ParseStatement(NULL, CHECK_OK); | 2866 Statement* body = ParseStatement(NULL, CHECK_OK); |
| 2859 top_scope_ = saved_scope; | 2867 top_scope_ = saved_scope; |
| 2860 for_scope->set_end_position(scanner().location().end_pos); | 2868 for_scope->set_end_position(scanner().location().end_pos); |
| 2861 for_scope = for_scope->FinalizeBlockScope(); | 2869 for_scope = for_scope->FinalizeBlockScope(); |
| 2862 if (for_scope != NULL) { | 2870 if (for_scope != NULL) { |
| 2863 // Rewrite a for statement of the form | 2871 // Rewrite a for statement of the form |
| 2864 // | 2872 // |
| 2865 // for (let x = i; c; n) b | 2873 // for (let x = i; c; n) b |
| 2866 // | 2874 // |
| 2867 // into | 2875 // into |
| 2868 // | 2876 // |
| 2869 // { | 2877 // { |
| 2870 // let x = i; | 2878 // let x = i; |
| 2871 // for (; c; n) b | 2879 // for (; c; n) b |
| 2872 // } | 2880 // } |
| 2873 ASSERT(init != NULL); | 2881 ASSERT(init != NULL); |
| 2874 Block* result = factory()->NewBlock(NULL, 2, false); | 2882 Block* result = factory()->NewBlock(NULL, 2, false, RelocInfo::kNoPosition); |
| 2875 result->AddStatement(init, zone()); | 2883 result->AddStatement(init, zone()); |
| 2876 result->AddStatement(loop, zone()); | 2884 result->AddStatement(loop, zone()); |
| 2877 result->set_scope(for_scope); | 2885 result->set_scope(for_scope); |
| 2878 loop->Initialize(NULL, cond, next, body); | 2886 loop->Initialize(NULL, cond, next, body); |
| 2879 return result; | 2887 return result; |
| 2880 } else { | 2888 } else { |
| 2881 loop->Initialize(init, cond, next, body); | 2889 loop->Initialize(init, cond, next, body); |
| 2882 return loop; | 2890 return loop; |
| 2883 } | 2891 } |
| 2884 } | 2892 } |
| 2885 | 2893 |
| 2886 | 2894 |
| 2887 // Precedence = 1 | 2895 // Precedence = 1 |
| 2888 Expression* Parser::ParseExpression(bool accept_IN, bool* ok) { | 2896 Expression* Parser::ParseExpression(bool accept_IN, bool* ok) { |
| 2889 // Expression :: | 2897 // Expression :: |
| 2890 // AssignmentExpression | 2898 // AssignmentExpression |
| 2891 // Expression ',' AssignmentExpression | 2899 // Expression ',' AssignmentExpression |
| 2892 | 2900 |
| 2893 Expression* result = ParseAssignmentExpression(accept_IN, CHECK_OK); | 2901 Expression* result = ParseAssignmentExpression(accept_IN, CHECK_OK); |
| 2894 while (peek() == Token::COMMA) { | 2902 while (peek() == Token::COMMA) { |
| 2895 Expect(Token::COMMA, CHECK_OK); | 2903 Expect(Token::COMMA, CHECK_OK); |
| 2896 int position = scanner().location().beg_pos; | 2904 int pos = position(); |
| 2897 Expression* right = ParseAssignmentExpression(accept_IN, CHECK_OK); | 2905 Expression* right = ParseAssignmentExpression(accept_IN, CHECK_OK); |
| 2898 result = | 2906 result = factory()->NewBinaryOperation(Token::COMMA, result, right, pos); |
| 2899 factory()->NewBinaryOperation(Token::COMMA, result, right, position); | |
| 2900 } | 2907 } |
| 2901 return result; | 2908 return result; |
| 2902 } | 2909 } |
| 2903 | 2910 |
| 2904 | 2911 |
| 2905 // Precedence = 2 | 2912 // Precedence = 2 |
| 2906 Expression* Parser::ParseAssignmentExpression(bool accept_IN, bool* ok) { | 2913 Expression* Parser::ParseAssignmentExpression(bool accept_IN, bool* ok) { |
| 2907 // AssignmentExpression :: | 2914 // AssignmentExpression :: |
| 2908 // ConditionalExpression | 2915 // ConditionalExpression |
| 2909 // YieldExpression | 2916 // YieldExpression |
| (...skipping 23 matching lines...) Expand all Loading... |
| 2933 expression = NewThrowReferenceError(message); | 2940 expression = NewThrowReferenceError(message); |
| 2934 } | 2941 } |
| 2935 | 2942 |
| 2936 if (!top_scope_->is_classic_mode()) { | 2943 if (!top_scope_->is_classic_mode()) { |
| 2937 // Assignment to eval or arguments is disallowed in strict mode. | 2944 // Assignment to eval or arguments is disallowed in strict mode. |
| 2938 CheckStrictModeLValue(expression, "strict_lhs_assignment", CHECK_OK); | 2945 CheckStrictModeLValue(expression, "strict_lhs_assignment", CHECK_OK); |
| 2939 } | 2946 } |
| 2940 MarkAsLValue(expression); | 2947 MarkAsLValue(expression); |
| 2941 | 2948 |
| 2942 Token::Value op = Next(); // Get assignment operator. | 2949 Token::Value op = Next(); // Get assignment operator. |
| 2943 int pos = scanner().location().beg_pos; | 2950 int pos = position(); |
| 2944 Expression* right = ParseAssignmentExpression(accept_IN, CHECK_OK); | 2951 Expression* right = ParseAssignmentExpression(accept_IN, CHECK_OK); |
| 2945 | 2952 |
| 2946 // TODO(1231235): We try to estimate the set of properties set by | 2953 // TODO(1231235): We try to estimate the set of properties set by |
| 2947 // constructors. We define a new property whenever there is an | 2954 // constructors. We define a new property whenever there is an |
| 2948 // assignment to a property of 'this'. We should probably only add | 2955 // assignment to a property of 'this'. We should probably only add |
| 2949 // properties if we haven't seen them before. Otherwise we'll | 2956 // properties if we haven't seen them before. Otherwise we'll |
| 2950 // probably overestimate the number of properties. | 2957 // probably overestimate the number of properties. |
| 2951 Property* property = expression ? expression->AsProperty() : NULL; | 2958 Property* property = expression ? expression->AsProperty() : NULL; |
| 2952 if (op == Token::ASSIGN && | 2959 if (op == Token::ASSIGN && |
| 2953 property != NULL && | 2960 property != NULL && |
| (...skipping 23 matching lines...) Expand all Loading... |
| 2977 fni_->Leave(); | 2984 fni_->Leave(); |
| 2978 } | 2985 } |
| 2979 | 2986 |
| 2980 return factory()->NewAssignment(op, expression, right, pos); | 2987 return factory()->NewAssignment(op, expression, right, pos); |
| 2981 } | 2988 } |
| 2982 | 2989 |
| 2983 | 2990 |
| 2984 Expression* Parser::ParseYieldExpression(bool* ok) { | 2991 Expression* Parser::ParseYieldExpression(bool* ok) { |
| 2985 // YieldExpression :: | 2992 // YieldExpression :: |
| 2986 // 'yield' '*'? AssignmentExpression | 2993 // 'yield' '*'? AssignmentExpression |
| 2987 int position = scanner().peek_location().beg_pos; | 2994 int pos = peek_position(); |
| 2988 Expect(Token::YIELD, CHECK_OK); | 2995 Expect(Token::YIELD, CHECK_OK); |
| 2989 Yield::Kind kind = | 2996 Yield::Kind kind = |
| 2990 Check(Token::MUL) ? Yield::DELEGATING : Yield::SUSPEND; | 2997 Check(Token::MUL) ? Yield::DELEGATING : Yield::SUSPEND; |
| 2991 Expression* generator_object = factory()->NewVariableProxy( | 2998 Expression* generator_object = factory()->NewVariableProxy( |
| 2992 current_function_state_->generator_object_variable()); | 2999 current_function_state_->generator_object_variable()); |
| 2993 Expression* expression = ParseAssignmentExpression(false, CHECK_OK); | 3000 Expression* expression = ParseAssignmentExpression(false, CHECK_OK); |
| 2994 Yield* yield = | 3001 Yield* yield = factory()->NewYield(generator_object, expression, kind, pos); |
| 2995 factory()->NewYield(generator_object, expression, kind, position); | |
| 2996 if (kind == Yield::DELEGATING) { | 3002 if (kind == Yield::DELEGATING) { |
| 2997 yield->set_index(current_function_state_->NextHandlerIndex()); | 3003 yield->set_index(current_function_state_->NextHandlerIndex()); |
| 2998 } | 3004 } |
| 2999 return yield; | 3005 return yield; |
| 3000 } | 3006 } |
| 3001 | 3007 |
| 3002 | 3008 |
| 3003 // Precedence = 3 | 3009 // Precedence = 3 |
| 3004 Expression* Parser::ParseConditionalExpression(bool accept_IN, bool* ok) { | 3010 Expression* Parser::ParseConditionalExpression(bool accept_IN, bool* ok) { |
| 3005 // ConditionalExpression :: | 3011 // ConditionalExpression :: |
| 3006 // LogicalOrExpression | 3012 // LogicalOrExpression |
| 3007 // LogicalOrExpression '?' AssignmentExpression ':' AssignmentExpression | 3013 // LogicalOrExpression '?' AssignmentExpression ':' AssignmentExpression |
| 3008 | 3014 |
| 3015 int pos = peek_position(); |
| 3009 // We start using the binary expression parser for prec >= 4 only! | 3016 // We start using the binary expression parser for prec >= 4 only! |
| 3010 Expression* expression = ParseBinaryExpression(4, accept_IN, CHECK_OK); | 3017 Expression* expression = ParseBinaryExpression(4, accept_IN, CHECK_OK); |
| 3011 if (peek() != Token::CONDITIONAL) return expression; | 3018 if (peek() != Token::CONDITIONAL) return expression; |
| 3012 Consume(Token::CONDITIONAL); | 3019 Consume(Token::CONDITIONAL); |
| 3013 // In parsing the first assignment expression in conditional | 3020 // In parsing the first assignment expression in conditional |
| 3014 // expressions we always accept the 'in' keyword; see ECMA-262, | 3021 // expressions we always accept the 'in' keyword; see ECMA-262, |
| 3015 // section 11.12, page 58. | 3022 // section 11.12, page 58. |
| 3016 int left_position = scanner().peek_location().beg_pos; | |
| 3017 Expression* left = ParseAssignmentExpression(true, CHECK_OK); | 3023 Expression* left = ParseAssignmentExpression(true, CHECK_OK); |
| 3018 Expect(Token::COLON, CHECK_OK); | 3024 Expect(Token::COLON, CHECK_OK); |
| 3019 int right_position = scanner().peek_location().beg_pos; | |
| 3020 Expression* right = ParseAssignmentExpression(accept_IN, CHECK_OK); | 3025 Expression* right = ParseAssignmentExpression(accept_IN, CHECK_OK); |
| 3021 return factory()->NewConditional( | 3026 return factory()->NewConditional(expression, left, right, pos); |
| 3022 expression, left, right, left_position, right_position); | |
| 3023 } | 3027 } |
| 3024 | 3028 |
| 3025 | 3029 |
| 3026 static int Precedence(Token::Value tok, bool accept_IN) { | 3030 int ParserBase::Precedence(Token::Value tok, bool accept_IN) { |
| 3027 if (tok == Token::IN && !accept_IN) | 3031 if (tok == Token::IN && !accept_IN) |
| 3028 return 0; // 0 precedence will terminate binary expression parsing | 3032 return 0; // 0 precedence will terminate binary expression parsing |
| 3029 | 3033 |
| 3030 return Token::Precedence(tok); | 3034 return Token::Precedence(tok); |
| 3031 } | 3035 } |
| 3032 | 3036 |
| 3033 | 3037 |
| 3034 // Precedence >= 4 | 3038 // Precedence >= 4 |
| 3035 Expression* Parser::ParseBinaryExpression(int prec, bool accept_IN, bool* ok) { | 3039 Expression* Parser::ParseBinaryExpression(int prec, bool accept_IN, bool* ok) { |
| 3036 ASSERT(prec >= 4); | 3040 ASSERT(prec >= 4); |
| 3037 Expression* x = ParseUnaryExpression(CHECK_OK); | 3041 Expression* x = ParseUnaryExpression(CHECK_OK); |
| 3038 for (int prec1 = Precedence(peek(), accept_IN); prec1 >= prec; prec1--) { | 3042 for (int prec1 = Precedence(peek(), accept_IN); prec1 >= prec; prec1--) { |
| 3039 // prec1 >= 4 | 3043 // prec1 >= 4 |
| 3040 while (Precedence(peek(), accept_IN) == prec1) { | 3044 while (Precedence(peek(), accept_IN) == prec1) { |
| 3041 Token::Value op = Next(); | 3045 Token::Value op = Next(); |
| 3042 int position = scanner().location().beg_pos; | 3046 int pos = position(); |
| 3043 Expression* y = ParseBinaryExpression(prec1 + 1, accept_IN, CHECK_OK); | 3047 Expression* y = ParseBinaryExpression(prec1 + 1, accept_IN, CHECK_OK); |
| 3044 | 3048 |
| 3045 // Compute some expressions involving only number literals. | 3049 // Compute some expressions involving only number literals. |
| 3046 if (x && x->AsLiteral() && x->AsLiteral()->value()->IsNumber() && | 3050 if (x && x->AsLiteral() && x->AsLiteral()->value()->IsNumber() && |
| 3047 y && y->AsLiteral() && y->AsLiteral()->value()->IsNumber()) { | 3051 y && y->AsLiteral() && y->AsLiteral()->value()->IsNumber()) { |
| 3048 double x_val = x->AsLiteral()->value()->Number(); | 3052 double x_val = x->AsLiteral()->value()->Number(); |
| 3049 double y_val = y->AsLiteral()->value()->Number(); | 3053 double y_val = y->AsLiteral()->value()->Number(); |
| 3050 | 3054 |
| 3051 switch (op) { | 3055 switch (op) { |
| 3052 case Token::ADD: | 3056 case Token::ADD: |
| 3053 x = factory()->NewNumberLiteral(x_val + y_val); | 3057 x = factory()->NewNumberLiteral(x_val + y_val, pos); |
| 3054 continue; | 3058 continue; |
| 3055 case Token::SUB: | 3059 case Token::SUB: |
| 3056 x = factory()->NewNumberLiteral(x_val - y_val); | 3060 x = factory()->NewNumberLiteral(x_val - y_val, pos); |
| 3057 continue; | 3061 continue; |
| 3058 case Token::MUL: | 3062 case Token::MUL: |
| 3059 x = factory()->NewNumberLiteral(x_val * y_val); | 3063 x = factory()->NewNumberLiteral(x_val * y_val, pos); |
| 3060 continue; | 3064 continue; |
| 3061 case Token::DIV: | 3065 case Token::DIV: |
| 3062 x = factory()->NewNumberLiteral(x_val / y_val); | 3066 x = factory()->NewNumberLiteral(x_val / y_val, pos); |
| 3063 continue; | 3067 continue; |
| 3064 case Token::BIT_OR: { | 3068 case Token::BIT_OR: { |
| 3065 int value = DoubleToInt32(x_val) | DoubleToInt32(y_val); | 3069 int value = DoubleToInt32(x_val) | DoubleToInt32(y_val); |
| 3066 x = factory()->NewNumberLiteral(value); | 3070 x = factory()->NewNumberLiteral(value, pos); |
| 3067 continue; | 3071 continue; |
| 3068 } | 3072 } |
| 3069 case Token::BIT_AND: { | 3073 case Token::BIT_AND: { |
| 3070 int value = DoubleToInt32(x_val) & DoubleToInt32(y_val); | 3074 int value = DoubleToInt32(x_val) & DoubleToInt32(y_val); |
| 3071 x = factory()->NewNumberLiteral(value); | 3075 x = factory()->NewNumberLiteral(value, pos); |
| 3072 continue; | 3076 continue; |
| 3073 } | 3077 } |
| 3074 case Token::BIT_XOR: { | 3078 case Token::BIT_XOR: { |
| 3075 int value = DoubleToInt32(x_val) ^ DoubleToInt32(y_val); | 3079 int value = DoubleToInt32(x_val) ^ DoubleToInt32(y_val); |
| 3076 x = factory()->NewNumberLiteral(value); | 3080 x = factory()->NewNumberLiteral(value, pos); |
| 3077 continue; | 3081 continue; |
| 3078 } | 3082 } |
| 3079 case Token::SHL: { | 3083 case Token::SHL: { |
| 3080 int value = DoubleToInt32(x_val) << (DoubleToInt32(y_val) & 0x1f); | 3084 int value = DoubleToInt32(x_val) << (DoubleToInt32(y_val) & 0x1f); |
| 3081 x = factory()->NewNumberLiteral(value); | 3085 x = factory()->NewNumberLiteral(value, pos); |
| 3082 continue; | 3086 continue; |
| 3083 } | 3087 } |
| 3084 case Token::SHR: { | 3088 case Token::SHR: { |
| 3085 uint32_t shift = DoubleToInt32(y_val) & 0x1f; | 3089 uint32_t shift = DoubleToInt32(y_val) & 0x1f; |
| 3086 uint32_t value = DoubleToUint32(x_val) >> shift; | 3090 uint32_t value = DoubleToUint32(x_val) >> shift; |
| 3087 x = factory()->NewNumberLiteral(value); | 3091 x = factory()->NewNumberLiteral(value, pos); |
| 3088 continue; | 3092 continue; |
| 3089 } | 3093 } |
| 3090 case Token::SAR: { | 3094 case Token::SAR: { |
| 3091 uint32_t shift = DoubleToInt32(y_val) & 0x1f; | 3095 uint32_t shift = DoubleToInt32(y_val) & 0x1f; |
| 3092 int value = ArithmeticShiftRight(DoubleToInt32(x_val), shift); | 3096 int value = ArithmeticShiftRight(DoubleToInt32(x_val), shift); |
| 3093 x = factory()->NewNumberLiteral(value); | 3097 x = factory()->NewNumberLiteral(value, pos); |
| 3094 continue; | 3098 continue; |
| 3095 } | 3099 } |
| 3096 default: | 3100 default: |
| 3097 break; | 3101 break; |
| 3098 } | 3102 } |
| 3099 } | 3103 } |
| 3100 | 3104 |
| 3101 // For now we distinguish between comparisons and other binary | 3105 // For now we distinguish between comparisons and other binary |
| 3102 // operations. (We could combine the two and get rid of this | 3106 // operations. (We could combine the two and get rid of this |
| 3103 // code and AST node eventually.) | 3107 // code and AST node eventually.) |
| 3104 if (Token::IsCompareOp(op)) { | 3108 if (Token::IsCompareOp(op)) { |
| 3105 // We have a comparison. | 3109 // We have a comparison. |
| 3106 Token::Value cmp = op; | 3110 Token::Value cmp = op; |
| 3107 switch (op) { | 3111 switch (op) { |
| 3108 case Token::NE: cmp = Token::EQ; break; | 3112 case Token::NE: cmp = Token::EQ; break; |
| 3109 case Token::NE_STRICT: cmp = Token::EQ_STRICT; break; | 3113 case Token::NE_STRICT: cmp = Token::EQ_STRICT; break; |
| 3110 default: break; | 3114 default: break; |
| 3111 } | 3115 } |
| 3112 x = factory()->NewCompareOperation(cmp, x, y, position); | 3116 x = factory()->NewCompareOperation(cmp, x, y, pos); |
| 3113 if (cmp != op) { | 3117 if (cmp != op) { |
| 3114 // The comparison was negated - add a NOT. | 3118 // The comparison was negated - add a NOT. |
| 3115 x = factory()->NewUnaryOperation(Token::NOT, x, position); | 3119 x = factory()->NewUnaryOperation(Token::NOT, x, pos); |
| 3116 } | 3120 } |
| 3117 | 3121 |
| 3118 } else { | 3122 } else { |
| 3119 // We have a "normal" binary operation. | 3123 // We have a "normal" binary operation. |
| 3120 x = factory()->NewBinaryOperation(op, x, y, position); | 3124 x = factory()->NewBinaryOperation(op, x, y, pos); |
| 3121 } | 3125 } |
| 3122 } | 3126 } |
| 3123 } | 3127 } |
| 3124 return x; | 3128 return x; |
| 3125 } | 3129 } |
| 3126 | 3130 |
| 3127 | 3131 |
| 3128 Expression* Parser::ParseUnaryExpression(bool* ok) { | 3132 Expression* Parser::ParseUnaryExpression(bool* ok) { |
| 3129 // UnaryExpression :: | 3133 // UnaryExpression :: |
| 3130 // PostfixExpression | 3134 // PostfixExpression |
| 3131 // 'delete' UnaryExpression | 3135 // 'delete' UnaryExpression |
| 3132 // 'void' UnaryExpression | 3136 // 'void' UnaryExpression |
| 3133 // 'typeof' UnaryExpression | 3137 // 'typeof' UnaryExpression |
| 3134 // '++' UnaryExpression | 3138 // '++' UnaryExpression |
| 3135 // '--' UnaryExpression | 3139 // '--' UnaryExpression |
| 3136 // '+' UnaryExpression | 3140 // '+' UnaryExpression |
| 3137 // '-' UnaryExpression | 3141 // '-' UnaryExpression |
| 3138 // '~' UnaryExpression | 3142 // '~' UnaryExpression |
| 3139 // '!' UnaryExpression | 3143 // '!' UnaryExpression |
| 3140 | 3144 |
| 3141 Token::Value op = peek(); | 3145 Token::Value op = peek(); |
| 3142 if (Token::IsUnaryOp(op)) { | 3146 if (Token::IsUnaryOp(op)) { |
| 3143 op = Next(); | 3147 op = Next(); |
| 3144 int position = scanner().location().beg_pos; | 3148 int pos = position(); |
| 3145 Expression* expression = ParseUnaryExpression(CHECK_OK); | 3149 Expression* expression = ParseUnaryExpression(CHECK_OK); |
| 3146 | 3150 |
| 3147 if (expression != NULL && (expression->AsLiteral() != NULL)) { | 3151 if (expression != NULL && (expression->AsLiteral() != NULL)) { |
| 3148 Handle<Object> literal = expression->AsLiteral()->value(); | 3152 Handle<Object> literal = expression->AsLiteral()->value(); |
| 3149 if (op == Token::NOT) { | 3153 if (op == Token::NOT) { |
| 3150 // Convert the literal to a boolean condition and negate it. | 3154 // Convert the literal to a boolean condition and negate it. |
| 3151 bool condition = literal->BooleanValue(); | 3155 bool condition = literal->BooleanValue(); |
| 3152 Handle<Object> result = isolate()->factory()->ToBoolean(!condition); | 3156 Handle<Object> result = isolate()->factory()->ToBoolean(!condition); |
| 3153 return factory()->NewLiteral(result); | 3157 return factory()->NewLiteral(result, pos); |
| 3154 } else if (literal->IsNumber()) { | 3158 } else if (literal->IsNumber()) { |
| 3155 // Compute some expressions involving only number literals. | 3159 // Compute some expressions involving only number literals. |
| 3156 double value = literal->Number(); | 3160 double value = literal->Number(); |
| 3157 switch (op) { | 3161 switch (op) { |
| 3158 case Token::ADD: | 3162 case Token::ADD: |
| 3159 return expression; | 3163 return expression; |
| 3160 case Token::SUB: | 3164 case Token::SUB: |
| 3161 return factory()->NewNumberLiteral(-value); | 3165 return factory()->NewNumberLiteral(-value, pos); |
| 3162 case Token::BIT_NOT: | 3166 case Token::BIT_NOT: |
| 3163 return factory()->NewNumberLiteral(~DoubleToInt32(value)); | 3167 return factory()->NewNumberLiteral(~DoubleToInt32(value), pos); |
| 3164 default: | 3168 default: |
| 3165 break; | 3169 break; |
| 3166 } | 3170 } |
| 3167 } | 3171 } |
| 3168 } | 3172 } |
| 3169 | 3173 |
| 3170 // "delete identifier" is a syntax error in strict mode. | 3174 // "delete identifier" is a syntax error in strict mode. |
| 3171 if (op == Token::DELETE && !top_scope_->is_classic_mode()) { | 3175 if (op == Token::DELETE && !top_scope_->is_classic_mode()) { |
| 3172 VariableProxy* operand = expression->AsVariableProxy(); | 3176 VariableProxy* operand = expression->AsVariableProxy(); |
| 3173 if (operand != NULL && !operand->is_this()) { | 3177 if (operand != NULL && !operand->is_this()) { |
| 3174 ReportMessage("strict_delete", Vector<const char*>::empty()); | 3178 ReportMessage("strict_delete", Vector<const char*>::empty()); |
| 3175 *ok = false; | 3179 *ok = false; |
| 3176 return NULL; | 3180 return NULL; |
| 3177 } | 3181 } |
| 3178 } | 3182 } |
| 3179 | 3183 |
| 3180 // Desugar '+foo' into 'foo*1', this enables the collection of type feedback | 3184 // Desugar '+foo' into 'foo*1', this enables the collection of type feedback |
| 3181 // without any special stub and the multiplication is removed later in | 3185 // without any special stub and the multiplication is removed later in |
| 3182 // Crankshaft's canonicalization pass. | 3186 // Crankshaft's canonicalization pass. |
| 3183 if (op == Token::ADD) { | 3187 if (op == Token::ADD) { |
| 3184 return factory()->NewBinaryOperation(Token::MUL, | 3188 return factory()->NewBinaryOperation(Token::MUL, |
| 3185 expression, | 3189 expression, |
| 3186 factory()->NewNumberLiteral(1), | 3190 factory()->NewNumberLiteral(1, pos), |
| 3187 position); | 3191 pos); |
| 3188 } | 3192 } |
| 3189 // The same idea for '-foo' => 'foo*(-1)'. | 3193 // The same idea for '-foo' => 'foo*(-1)'. |
| 3190 if (op == Token::SUB) { | 3194 if (op == Token::SUB) { |
| 3191 return factory()->NewBinaryOperation(Token::MUL, | 3195 return factory()->NewBinaryOperation(Token::MUL, |
| 3192 expression, | 3196 expression, |
| 3193 factory()->NewNumberLiteral(-1), | 3197 factory()->NewNumberLiteral(-1, pos), |
| 3194 position); | 3198 pos); |
| 3195 } | 3199 } |
| 3196 // ...and one more time for '~foo' => 'foo^(~0)'. | 3200 // ...and one more time for '~foo' => 'foo^(~0)'. |
| 3197 if (op == Token::BIT_NOT) { | 3201 if (op == Token::BIT_NOT) { |
| 3198 return factory()->NewBinaryOperation(Token::BIT_XOR, | 3202 return factory()->NewBinaryOperation(Token::BIT_XOR, |
| 3199 expression, | 3203 expression, |
| 3200 factory()->NewNumberLiteral(~0), | 3204 factory()->NewNumberLiteral(~0, pos), |
| 3201 position); | 3205 pos); |
| 3202 } | 3206 } |
| 3203 | 3207 |
| 3204 return factory()->NewUnaryOperation(op, expression, position); | 3208 return factory()->NewUnaryOperation(op, expression, pos); |
| 3205 | 3209 |
| 3206 } else if (Token::IsCountOp(op)) { | 3210 } else if (Token::IsCountOp(op)) { |
| 3207 op = Next(); | 3211 op = Next(); |
| 3208 Expression* expression = ParseUnaryExpression(CHECK_OK); | 3212 Expression* expression = ParseUnaryExpression(CHECK_OK); |
| 3209 // Signal a reference error if the expression is an invalid | 3213 // Signal a reference error if the expression is an invalid |
| 3210 // left-hand side expression. We could report this as a syntax | 3214 // left-hand side expression. We could report this as a syntax |
| 3211 // error here but for compatibility with JSC we choose to report the | 3215 // error here but for compatibility with JSC we choose to report the |
| 3212 // error at runtime. | 3216 // error at runtime. |
| 3213 if (expression == NULL || !expression->IsValidLeftHandSide()) { | 3217 if (expression == NULL || !expression->IsValidLeftHandSide()) { |
| 3214 Handle<String> message = | 3218 Handle<String> message = |
| 3215 isolate()->factory()->invalid_lhs_in_prefix_op_string(); | 3219 isolate()->factory()->invalid_lhs_in_prefix_op_string(); |
| 3216 expression = NewThrowReferenceError(message); | 3220 expression = NewThrowReferenceError(message); |
| 3217 } | 3221 } |
| 3218 | 3222 |
| 3219 if (!top_scope_->is_classic_mode()) { | 3223 if (!top_scope_->is_classic_mode()) { |
| 3220 // Prefix expression operand in strict mode may not be eval or arguments. | 3224 // Prefix expression operand in strict mode may not be eval or arguments. |
| 3221 CheckStrictModeLValue(expression, "strict_lhs_prefix", CHECK_OK); | 3225 CheckStrictModeLValue(expression, "strict_lhs_prefix", CHECK_OK); |
| 3222 } | 3226 } |
| 3223 MarkAsLValue(expression); | 3227 MarkAsLValue(expression); |
| 3224 | 3228 |
| 3225 int position = scanner().location().beg_pos; | |
| 3226 return factory()->NewCountOperation(op, | 3229 return factory()->NewCountOperation(op, |
| 3227 true /* prefix */, | 3230 true /* prefix */, |
| 3228 expression, | 3231 expression, |
| 3229 position); | 3232 position()); |
| 3230 | 3233 |
| 3231 } else { | 3234 } else { |
| 3232 return ParsePostfixExpression(ok); | 3235 return ParsePostfixExpression(ok); |
| 3233 } | 3236 } |
| 3234 } | 3237 } |
| 3235 | 3238 |
| 3236 | 3239 |
| 3237 Expression* Parser::ParsePostfixExpression(bool* ok) { | 3240 Expression* Parser::ParsePostfixExpression(bool* ok) { |
| 3238 // PostfixExpression :: | 3241 // PostfixExpression :: |
| 3239 // LeftHandSideExpression ('++' | '--')? | 3242 // LeftHandSideExpression ('++' | '--')? |
| (...skipping 11 matching lines...) Expand all Loading... |
| 3251 expression = NewThrowReferenceError(message); | 3254 expression = NewThrowReferenceError(message); |
| 3252 } | 3255 } |
| 3253 | 3256 |
| 3254 if (!top_scope_->is_classic_mode()) { | 3257 if (!top_scope_->is_classic_mode()) { |
| 3255 // Postfix expression operand in strict mode may not be eval or arguments. | 3258 // Postfix expression operand in strict mode may not be eval or arguments. |
| 3256 CheckStrictModeLValue(expression, "strict_lhs_prefix", CHECK_OK); | 3259 CheckStrictModeLValue(expression, "strict_lhs_prefix", CHECK_OK); |
| 3257 } | 3260 } |
| 3258 MarkAsLValue(expression); | 3261 MarkAsLValue(expression); |
| 3259 | 3262 |
| 3260 Token::Value next = Next(); | 3263 Token::Value next = Next(); |
| 3261 int position = scanner().location().beg_pos; | |
| 3262 expression = | 3264 expression = |
| 3263 factory()->NewCountOperation(next, | 3265 factory()->NewCountOperation(next, |
| 3264 false /* postfix */, | 3266 false /* postfix */, |
| 3265 expression, | 3267 expression, |
| 3266 position); | 3268 position()); |
| 3267 } | 3269 } |
| 3268 return expression; | 3270 return expression; |
| 3269 } | 3271 } |
| 3270 | 3272 |
| 3271 | 3273 |
| 3272 Expression* Parser::ParseLeftHandSideExpression(bool* ok) { | 3274 Expression* Parser::ParseLeftHandSideExpression(bool* ok) { |
| 3273 // LeftHandSideExpression :: | 3275 // LeftHandSideExpression :: |
| 3274 // (NewExpression | MemberExpression) ... | 3276 // (NewExpression | MemberExpression) ... |
| 3275 | 3277 |
| 3276 Expression* result; | 3278 Expression* result; |
| 3277 if (peek() == Token::NEW) { | 3279 if (peek() == Token::NEW) { |
| 3278 result = ParseNewExpression(CHECK_OK); | 3280 result = ParseNewExpression(CHECK_OK); |
| 3279 } else { | 3281 } else { |
| 3280 result = ParseMemberExpression(CHECK_OK); | 3282 result = ParseMemberExpression(CHECK_OK); |
| 3281 } | 3283 } |
| 3282 | 3284 |
| 3283 while (true) { | 3285 while (true) { |
| 3284 switch (peek()) { | 3286 switch (peek()) { |
| 3285 case Token::LBRACK: { | 3287 case Token::LBRACK: { |
| 3286 Consume(Token::LBRACK); | 3288 Consume(Token::LBRACK); |
| 3287 int pos = scanner().location().beg_pos; | 3289 int pos = position(); |
| 3288 Expression* index = ParseExpression(true, CHECK_OK); | 3290 Expression* index = ParseExpression(true, CHECK_OK); |
| 3289 result = factory()->NewProperty(result, index, pos); | 3291 result = factory()->NewProperty(result, index, pos); |
| 3290 Expect(Token::RBRACK, CHECK_OK); | 3292 Expect(Token::RBRACK, CHECK_OK); |
| 3291 break; | 3293 break; |
| 3292 } | 3294 } |
| 3293 | 3295 |
| 3294 case Token::LPAREN: { | 3296 case Token::LPAREN: { |
| 3295 int pos; | 3297 int pos; |
| 3296 if (scanner().current_token() == Token::IDENTIFIER) { | 3298 if (scanner().current_token() == Token::IDENTIFIER) { |
| 3297 // For call of an identifier we want to report position of | 3299 // For call of an identifier we want to report position of |
| 3298 // the identifier as position of the call in the stack trace. | 3300 // the identifier as position of the call in the stack trace. |
| 3299 pos = scanner().location().beg_pos; | 3301 pos = position(); |
| 3300 } else { | 3302 } else { |
| 3301 // For other kinds of calls we record position of the parenthesis as | 3303 // For other kinds of calls we record position of the parenthesis as |
| 3302 // position of the call. Note that this is extremely important for | 3304 // position of the call. Note that this is extremely important for |
| 3303 // expressions of the form function(){...}() for which call position | 3305 // expressions of the form function(){...}() for which call position |
| 3304 // should not point to the closing brace otherwise it will intersect | 3306 // should not point to the closing brace otherwise it will intersect |
| 3305 // with positions recorded for function literal and confuse debugger. | 3307 // with positions recorded for function literal and confuse debugger. |
| 3306 pos = scanner().peek_location().beg_pos; | 3308 pos = peek_position(); |
| 3307 // Also the trailing parenthesis are a hint that the function will | 3309 // Also the trailing parenthesis are a hint that the function will |
| 3308 // be called immediately. If we happen to have parsed a preceding | 3310 // be called immediately. If we happen to have parsed a preceding |
| 3309 // function literal eagerly, we can also compile it eagerly. | 3311 // function literal eagerly, we can also compile it eagerly. |
| 3310 if (result->IsFunctionLiteral() && mode() == PARSE_EAGERLY) { | 3312 if (result->IsFunctionLiteral() && mode() == PARSE_EAGERLY) { |
| 3311 result->AsFunctionLiteral()->set_parenthesized(); | 3313 result->AsFunctionLiteral()->set_parenthesized(); |
| 3312 } | 3314 } |
| 3313 } | 3315 } |
| 3314 ZoneList<Expression*>* args = ParseArguments(CHECK_OK); | 3316 ZoneList<Expression*>* args = ParseArguments(CHECK_OK); |
| 3315 | 3317 |
| 3316 // Keep track of eval() calls since they disable all local variable | 3318 // Keep track of eval() calls since they disable all local variable |
| 3317 // optimizations. | 3319 // optimizations. |
| 3318 // The calls that need special treatment are the | 3320 // The calls that need special treatment are the |
| 3319 // direct eval calls. These calls are all of the form eval(...), with | 3321 // direct eval calls. These calls are all of the form eval(...), with |
| 3320 // no explicit receiver. | 3322 // no explicit receiver. |
| 3321 // These calls are marked as potentially direct eval calls. Whether | 3323 // These calls are marked as potentially direct eval calls. Whether |
| 3322 // they are actually direct calls to eval is determined at run time. | 3324 // they are actually direct calls to eval is determined at run time. |
| 3323 VariableProxy* callee = result->AsVariableProxy(); | 3325 VariableProxy* callee = result->AsVariableProxy(); |
| 3324 if (callee != NULL && | 3326 if (callee != NULL && |
| 3325 callee->IsVariable(isolate()->factory()->eval_string())) { | 3327 callee->IsVariable(isolate()->factory()->eval_string())) { |
| 3326 top_scope_->DeclarationScope()->RecordEvalCall(); | 3328 top_scope_->DeclarationScope()->RecordEvalCall(); |
| 3327 } | 3329 } |
| 3328 result = factory()->NewCall(result, args, pos); | 3330 result = factory()->NewCall(result, args, pos); |
| 3329 if (fni_ != NULL) fni_->RemoveLastFunction(); | 3331 if (fni_ != NULL) fni_->RemoveLastFunction(); |
| 3330 break; | 3332 break; |
| 3331 } | 3333 } |
| 3332 | 3334 |
| 3333 case Token::PERIOD: { | 3335 case Token::PERIOD: { |
| 3334 Consume(Token::PERIOD); | 3336 Consume(Token::PERIOD); |
| 3335 int pos = scanner().location().beg_pos; | 3337 int pos = position(); |
| 3336 Handle<String> name = ParseIdentifierName(CHECK_OK); | 3338 Handle<String> name = ParseIdentifierName(CHECK_OK); |
| 3337 result = | 3339 result = factory()->NewProperty( |
| 3338 factory()->NewProperty(result, factory()->NewLiteral(name), pos); | 3340 result, factory()->NewLiteral(name, pos), pos); |
| 3339 if (fni_ != NULL) fni_->PushLiteralName(name); | 3341 if (fni_ != NULL) fni_->PushLiteralName(name); |
| 3340 break; | 3342 break; |
| 3341 } | 3343 } |
| 3342 | 3344 |
| 3343 default: | 3345 default: |
| 3344 return result; | 3346 return result; |
| 3345 } | 3347 } |
| 3346 } | 3348 } |
| 3347 } | 3349 } |
| 3348 | 3350 |
| 3349 | 3351 |
| 3350 Expression* Parser::ParseNewPrefix(PositionStack* stack, bool* ok) { | 3352 Expression* Parser::ParseNewPrefix(PositionStack* stack, bool* ok) { |
| 3351 // NewExpression :: | 3353 // NewExpression :: |
| 3352 // ('new')+ MemberExpression | 3354 // ('new')+ MemberExpression |
| 3353 | 3355 |
| 3354 // The grammar for new expressions is pretty warped. The keyword | 3356 // The grammar for new expressions is pretty warped. The keyword |
| 3355 // 'new' can either be a part of the new expression (where it isn't | 3357 // 'new' can either be a part of the new expression (where it isn't |
| 3356 // followed by an argument list) or a part of the member expression, | 3358 // followed by an argument list) or a part of the member expression, |
| 3357 // where it must be followed by an argument list. To accommodate | 3359 // where it must be followed by an argument list. To accommodate |
| 3358 // this, we parse the 'new' keywords greedily and keep track of how | 3360 // this, we parse the 'new' keywords greedily and keep track of how |
| 3359 // many we have parsed. This information is then passed on to the | 3361 // many we have parsed. This information is then passed on to the |
| 3360 // member expression parser, which is only allowed to match argument | 3362 // member expression parser, which is only allowed to match argument |
| 3361 // lists as long as it has 'new' prefixes left | 3363 // lists as long as it has 'new' prefixes left |
| 3362 Expect(Token::NEW, CHECK_OK); | 3364 Expect(Token::NEW, CHECK_OK); |
| 3363 PositionStack::Element pos(stack, scanner().location().beg_pos); | 3365 PositionStack::Element pos(stack, position()); |
| 3364 | 3366 |
| 3365 Expression* result; | 3367 Expression* result; |
| 3366 if (peek() == Token::NEW) { | 3368 if (peek() == Token::NEW) { |
| 3367 result = ParseNewPrefix(stack, CHECK_OK); | 3369 result = ParseNewPrefix(stack, CHECK_OK); |
| 3368 } else { | 3370 } else { |
| 3369 result = ParseMemberWithNewPrefixesExpression(stack, CHECK_OK); | 3371 result = ParseMemberWithNewPrefixesExpression(stack, CHECK_OK); |
| 3370 } | 3372 } |
| 3371 | 3373 |
| 3372 if (!stack->is_empty()) { | 3374 if (!stack->is_empty()) { |
| 3373 int last = stack->pop(); | 3375 int last = stack->pop(); |
| (...skipping 18 matching lines...) Expand all Loading... |
| 3392 Expression* Parser::ParseMemberWithNewPrefixesExpression(PositionStack* stack, | 3394 Expression* Parser::ParseMemberWithNewPrefixesExpression(PositionStack* stack, |
| 3393 bool* ok) { | 3395 bool* ok) { |
| 3394 // MemberExpression :: | 3396 // MemberExpression :: |
| 3395 // (PrimaryExpression | FunctionLiteral) | 3397 // (PrimaryExpression | FunctionLiteral) |
| 3396 // ('[' Expression ']' | '.' Identifier | Arguments)* | 3398 // ('[' Expression ']' | '.' Identifier | Arguments)* |
| 3397 | 3399 |
| 3398 // Parse the initial primary or function expression. | 3400 // Parse the initial primary or function expression. |
| 3399 Expression* result = NULL; | 3401 Expression* result = NULL; |
| 3400 if (peek() == Token::FUNCTION) { | 3402 if (peek() == Token::FUNCTION) { |
| 3401 Expect(Token::FUNCTION, CHECK_OK); | 3403 Expect(Token::FUNCTION, CHECK_OK); |
| 3402 int function_token_position = scanner().location().beg_pos; | 3404 int function_token_position = position(); |
| 3403 bool is_generator = allow_generators() && Check(Token::MUL); | 3405 bool is_generator = allow_generators() && Check(Token::MUL); |
| 3404 Handle<String> name; | 3406 Handle<String> name; |
| 3405 bool is_strict_reserved_name = false; | 3407 bool is_strict_reserved_name = false; |
| 3406 if (peek_any_identifier()) { | 3408 if (peek_any_identifier()) { |
| 3407 name = ParseIdentifierOrStrictReservedWord(&is_strict_reserved_name, | 3409 name = ParseIdentifierOrStrictReservedWord(&is_strict_reserved_name, |
| 3408 CHECK_OK); | 3410 CHECK_OK); |
| 3409 } | 3411 } |
| 3410 FunctionLiteral::FunctionType function_type = name.is_null() | 3412 FunctionLiteral::FunctionType function_type = name.is_null() |
| 3411 ? FunctionLiteral::ANONYMOUS_EXPRESSION | 3413 ? FunctionLiteral::ANONYMOUS_EXPRESSION |
| 3412 : FunctionLiteral::NAMED_EXPRESSION; | 3414 : FunctionLiteral::NAMED_EXPRESSION; |
| 3413 result = ParseFunctionLiteral(name, | 3415 result = ParseFunctionLiteral(name, |
| 3414 is_strict_reserved_name, | 3416 is_strict_reserved_name, |
| 3415 is_generator, | 3417 is_generator, |
| 3416 function_token_position, | 3418 function_token_position, |
| 3417 function_type, | 3419 function_type, |
| 3418 CHECK_OK); | 3420 CHECK_OK); |
| 3419 } else { | 3421 } else { |
| 3420 result = ParsePrimaryExpression(CHECK_OK); | 3422 result = ParsePrimaryExpression(CHECK_OK); |
| 3421 } | 3423 } |
| 3422 | 3424 |
| 3423 while (true) { | 3425 while (true) { |
| 3424 switch (peek()) { | 3426 switch (peek()) { |
| 3425 case Token::LBRACK: { | 3427 case Token::LBRACK: { |
| 3426 Consume(Token::LBRACK); | 3428 Consume(Token::LBRACK); |
| 3427 int pos = scanner().location().beg_pos; | 3429 int pos = position(); |
| 3428 Expression* index = ParseExpression(true, CHECK_OK); | 3430 Expression* index = ParseExpression(true, CHECK_OK); |
| 3429 result = factory()->NewProperty(result, index, pos); | 3431 result = factory()->NewProperty(result, index, pos); |
| 3430 if (fni_ != NULL) { | 3432 if (fni_ != NULL) { |
| 3431 if (index->IsPropertyName()) { | 3433 if (index->IsPropertyName()) { |
| 3432 fni_->PushLiteralName(index->AsLiteral()->AsPropertyName()); | 3434 fni_->PushLiteralName(index->AsLiteral()->AsPropertyName()); |
| 3433 } else { | 3435 } else { |
| 3434 fni_->PushLiteralName( | 3436 fni_->PushLiteralName( |
| 3435 isolate()->factory()->anonymous_function_string()); | 3437 isolate()->factory()->anonymous_function_string()); |
| 3436 } | 3438 } |
| 3437 } | 3439 } |
| 3438 Expect(Token::RBRACK, CHECK_OK); | 3440 Expect(Token::RBRACK, CHECK_OK); |
| 3439 break; | 3441 break; |
| 3440 } | 3442 } |
| 3441 case Token::PERIOD: { | 3443 case Token::PERIOD: { |
| 3442 Consume(Token::PERIOD); | 3444 Consume(Token::PERIOD); |
| 3443 int pos = scanner().location().beg_pos; | 3445 int pos = position(); |
| 3444 Handle<String> name = ParseIdentifierName(CHECK_OK); | 3446 Handle<String> name = ParseIdentifierName(CHECK_OK); |
| 3445 result = | 3447 result = factory()->NewProperty( |
| 3446 factory()->NewProperty(result, factory()->NewLiteral(name), pos); | 3448 result, factory()->NewLiteral(name, pos), pos); |
| 3447 if (fni_ != NULL) fni_->PushLiteralName(name); | 3449 if (fni_ != NULL) fni_->PushLiteralName(name); |
| 3448 break; | 3450 break; |
| 3449 } | 3451 } |
| 3450 case Token::LPAREN: { | 3452 case Token::LPAREN: { |
| 3451 if ((stack == NULL) || stack->is_empty()) return result; | 3453 if ((stack == NULL) || stack->is_empty()) return result; |
| 3452 // Consume one of the new prefixes (already parsed). | 3454 // Consume one of the new prefixes (already parsed). |
| 3453 ZoneList<Expression*>* args = ParseArguments(CHECK_OK); | 3455 ZoneList<Expression*>* args = ParseArguments(CHECK_OK); |
| 3454 int last = stack->pop(); | 3456 int pos = stack->pop(); |
| 3455 result = factory()->NewCallNew(result, args, last); | 3457 result = factory()->NewCallNew(result, args, pos); |
| 3456 break; | 3458 break; |
| 3457 } | 3459 } |
| 3458 default: | 3460 default: |
| 3459 return result; | 3461 return result; |
| 3460 } | 3462 } |
| 3461 } | 3463 } |
| 3462 } | 3464 } |
| 3463 | 3465 |
| 3464 | 3466 |
| 3465 DebuggerStatement* Parser::ParseDebuggerStatement(bool* ok) { | 3467 DebuggerStatement* Parser::ParseDebuggerStatement(bool* ok) { |
| 3466 // In ECMA-262 'debugger' is defined as a reserved keyword. In some browser | 3468 // In ECMA-262 'debugger' is defined as a reserved keyword. In some browser |
| 3467 // contexts this is used as a statement which invokes the debugger as i a | 3469 // contexts this is used as a statement which invokes the debugger as i a |
| 3468 // break point is present. | 3470 // break point is present. |
| 3469 // DebuggerStatement :: | 3471 // DebuggerStatement :: |
| 3470 // 'debugger' ';' | 3472 // 'debugger' ';' |
| 3471 | 3473 |
| 3474 int pos = peek_position(); |
| 3472 Expect(Token::DEBUGGER, CHECK_OK); | 3475 Expect(Token::DEBUGGER, CHECK_OK); |
| 3473 ExpectSemicolon(CHECK_OK); | 3476 ExpectSemicolon(CHECK_OK); |
| 3474 return factory()->NewDebuggerStatement(); | 3477 return factory()->NewDebuggerStatement(pos); |
| 3475 } | 3478 } |
| 3476 | 3479 |
| 3477 | 3480 |
| 3478 void Parser::ReportUnexpectedToken(Token::Value token) { | 3481 void Parser::ReportUnexpectedToken(Token::Value token) { |
| 3479 // We don't report stack overflows here, to avoid increasing the | 3482 // We don't report stack overflows here, to avoid increasing the |
| 3480 // stack depth even further. Instead we report it after parsing is | 3483 // stack depth even further. Instead we report it after parsing is |
| 3481 // over, in ParseProgram/ParseJson. | 3484 // over, in ParseProgram/ParseJson. |
| 3482 if (token == Token::ILLEGAL && stack_overflow_) return; | 3485 if (token == Token::ILLEGAL && stack_overflow()) return; |
| 3483 // Four of the tokens are treated specially | 3486 // Four of the tokens are treated specially |
| 3484 switch (token) { | 3487 switch (token) { |
| 3485 case Token::EOS: | 3488 case Token::EOS: |
| 3486 return ReportMessage("unexpected_eos", Vector<const char*>::empty()); | 3489 return ReportMessage("unexpected_eos", Vector<const char*>::empty()); |
| 3487 case Token::NUMBER: | 3490 case Token::NUMBER: |
| 3488 return ReportMessage("unexpected_token_number", | 3491 return ReportMessage("unexpected_token_number", |
| 3489 Vector<const char*>::empty()); | 3492 Vector<const char*>::empty()); |
| 3490 case Token::STRING: | 3493 case Token::STRING: |
| 3491 return ReportMessage("unexpected_token_string", | 3494 return ReportMessage("unexpected_token_string", |
| 3492 Vector<const char*>::empty()); | 3495 Vector<const char*>::empty()); |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3526 // 'true' | 3529 // 'true' |
| 3527 // 'false' | 3530 // 'false' |
| 3528 // Identifier | 3531 // Identifier |
| 3529 // Number | 3532 // Number |
| 3530 // String | 3533 // String |
| 3531 // ArrayLiteral | 3534 // ArrayLiteral |
| 3532 // ObjectLiteral | 3535 // ObjectLiteral |
| 3533 // RegExpLiteral | 3536 // RegExpLiteral |
| 3534 // '(' Expression ')' | 3537 // '(' Expression ')' |
| 3535 | 3538 |
| 3539 int pos = peek_position(); |
| 3536 Expression* result = NULL; | 3540 Expression* result = NULL; |
| 3537 switch (peek()) { | 3541 switch (peek()) { |
| 3538 case Token::THIS: { | 3542 case Token::THIS: { |
| 3539 Consume(Token::THIS); | 3543 Consume(Token::THIS); |
| 3540 result = factory()->NewVariableProxy(top_scope_->receiver()); | 3544 result = factory()->NewVariableProxy(top_scope_->receiver()); |
| 3541 break; | 3545 break; |
| 3542 } | 3546 } |
| 3543 | 3547 |
| 3544 case Token::NULL_LITERAL: | 3548 case Token::NULL_LITERAL: |
| 3545 Consume(Token::NULL_LITERAL); | 3549 Consume(Token::NULL_LITERAL); |
| 3546 result = factory()->NewLiteral(isolate()->factory()->null_value()); | 3550 result = factory()->NewLiteral(isolate()->factory()->null_value(), pos); |
| 3547 break; | 3551 break; |
| 3548 | 3552 |
| 3549 case Token::TRUE_LITERAL: | 3553 case Token::TRUE_LITERAL: |
| 3550 Consume(Token::TRUE_LITERAL); | 3554 Consume(Token::TRUE_LITERAL); |
| 3551 result = factory()->NewLiteral(isolate()->factory()->true_value()); | 3555 result = factory()->NewLiteral(isolate()->factory()->true_value(), pos); |
| 3552 break; | 3556 break; |
| 3553 | 3557 |
| 3554 case Token::FALSE_LITERAL: | 3558 case Token::FALSE_LITERAL: |
| 3555 Consume(Token::FALSE_LITERAL); | 3559 Consume(Token::FALSE_LITERAL); |
| 3556 result = factory()->NewLiteral(isolate()->factory()->false_value()); | 3560 result = factory()->NewLiteral(isolate()->factory()->false_value(), pos); |
| 3557 break; | 3561 break; |
| 3558 | 3562 |
| 3559 case Token::IDENTIFIER: | 3563 case Token::IDENTIFIER: |
| 3560 case Token::YIELD: | 3564 case Token::YIELD: |
| 3561 case Token::FUTURE_STRICT_RESERVED_WORD: { | 3565 case Token::FUTURE_STRICT_RESERVED_WORD: { |
| 3562 Handle<String> name = ParseIdentifier(CHECK_OK); | 3566 Handle<String> name = ParseIdentifier(CHECK_OK); |
| 3563 if (fni_ != NULL) fni_->PushVariableName(name); | 3567 if (fni_ != NULL) fni_->PushVariableName(name); |
| 3564 // The name may refer to a module instance object, so its type is unknown. | 3568 // The name may refer to a module instance object, so its type is unknown. |
| 3565 #ifdef DEBUG | 3569 #ifdef DEBUG |
| 3566 if (FLAG_print_interface_details) | 3570 if (FLAG_print_interface_details) |
| 3567 PrintF("# Variable %s ", name->ToAsciiArray()); | 3571 PrintF("# Variable %s ", name->ToAsciiArray()); |
| 3568 #endif | 3572 #endif |
| 3569 Interface* interface = Interface::NewUnknown(zone()); | 3573 Interface* interface = Interface::NewUnknown(zone()); |
| 3570 result = top_scope_->NewUnresolved( | 3574 result = top_scope_->NewUnresolved(factory(), name, interface, pos); |
| 3571 factory(), name, interface, scanner().location().beg_pos); | |
| 3572 break; | 3575 break; |
| 3573 } | 3576 } |
| 3574 | 3577 |
| 3575 case Token::NUMBER: { | 3578 case Token::NUMBER: { |
| 3576 Consume(Token::NUMBER); | 3579 Consume(Token::NUMBER); |
| 3577 ASSERT(scanner().is_literal_ascii()); | 3580 ASSERT(scanner().is_literal_ascii()); |
| 3578 double value = StringToDouble(isolate()->unicode_cache(), | 3581 double value = StringToDouble(isolate()->unicode_cache(), |
| 3579 scanner().literal_ascii_string(), | 3582 scanner().literal_ascii_string(), |
| 3580 ALLOW_HEX | ALLOW_OCTAL | | 3583 ALLOW_HEX | ALLOW_OCTAL | |
| 3581 ALLOW_IMPLICIT_OCTAL | ALLOW_BINARY); | 3584 ALLOW_IMPLICIT_OCTAL | ALLOW_BINARY); |
| 3582 result = factory()->NewNumberLiteral(value); | 3585 result = factory()->NewNumberLiteral(value, pos); |
| 3583 break; | 3586 break; |
| 3584 } | 3587 } |
| 3585 | 3588 |
| 3586 case Token::STRING: { | 3589 case Token::STRING: { |
| 3587 Consume(Token::STRING); | 3590 Consume(Token::STRING); |
| 3588 Handle<String> symbol = GetSymbol(); | 3591 Handle<String> symbol = GetSymbol(); |
| 3589 result = factory()->NewLiteral(symbol); | 3592 result = factory()->NewLiteral(symbol, pos); |
| 3590 if (fni_ != NULL) fni_->PushLiteralName(symbol); | 3593 if (fni_ != NULL) fni_->PushLiteralName(symbol); |
| 3591 break; | 3594 break; |
| 3592 } | 3595 } |
| 3593 | 3596 |
| 3594 case Token::ASSIGN_DIV: | 3597 case Token::ASSIGN_DIV: |
| 3595 result = ParseRegExpLiteral(true, CHECK_OK); | 3598 result = ParseRegExpLiteral(true, CHECK_OK); |
| 3596 break; | 3599 break; |
| 3597 | 3600 |
| 3598 case Token::DIV: | 3601 case Token::DIV: |
| 3599 result = ParseRegExpLiteral(false, CHECK_OK); | 3602 result = ParseRegExpLiteral(false, CHECK_OK); |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3633 } | 3636 } |
| 3634 | 3637 |
| 3635 return result; | 3638 return result; |
| 3636 } | 3639 } |
| 3637 | 3640 |
| 3638 | 3641 |
| 3639 Expression* Parser::ParseArrayLiteral(bool* ok) { | 3642 Expression* Parser::ParseArrayLiteral(bool* ok) { |
| 3640 // ArrayLiteral :: | 3643 // ArrayLiteral :: |
| 3641 // '[' Expression? (',' Expression?)* ']' | 3644 // '[' Expression? (',' Expression?)* ']' |
| 3642 | 3645 |
| 3646 int pos = peek_position(); |
| 3643 ZoneList<Expression*>* values = new(zone()) ZoneList<Expression*>(4, zone()); | 3647 ZoneList<Expression*>* values = new(zone()) ZoneList<Expression*>(4, zone()); |
| 3644 Expect(Token::LBRACK, CHECK_OK); | 3648 Expect(Token::LBRACK, CHECK_OK); |
| 3645 while (peek() != Token::RBRACK) { | 3649 while (peek() != Token::RBRACK) { |
| 3646 Expression* elem; | 3650 Expression* elem; |
| 3647 if (peek() == Token::COMMA) { | 3651 if (peek() == Token::COMMA) { |
| 3648 elem = GetLiteralTheHole(); | 3652 elem = GetLiteralTheHole(peek_position()); |
| 3649 } else { | 3653 } else { |
| 3650 elem = ParseAssignmentExpression(true, CHECK_OK); | 3654 elem = ParseAssignmentExpression(true, CHECK_OK); |
| 3651 } | 3655 } |
| 3652 values->Add(elem, zone()); | 3656 values->Add(elem, zone()); |
| 3653 if (peek() != Token::RBRACK) { | 3657 if (peek() != Token::RBRACK) { |
| 3654 Expect(Token::COMMA, CHECK_OK); | 3658 Expect(Token::COMMA, CHECK_OK); |
| 3655 } | 3659 } |
| 3656 } | 3660 } |
| 3657 Expect(Token::RBRACK, CHECK_OK); | 3661 Expect(Token::RBRACK, CHECK_OK); |
| 3658 | 3662 |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3700 // in a 2-element FixedArray. | 3704 // in a 2-element FixedArray. |
| 3701 Handle<FixedArray> literals = isolate()->factory()->NewFixedArray(2, TENURED); | 3705 Handle<FixedArray> literals = isolate()->factory()->NewFixedArray(2, TENURED); |
| 3702 | 3706 |
| 3703 ElementsKind kind = array->GetElementsKind(); | 3707 ElementsKind kind = array->GetElementsKind(); |
| 3704 kind = is_holey ? GetHoleyElementsKind(kind) : GetPackedElementsKind(kind); | 3708 kind = is_holey ? GetHoleyElementsKind(kind) : GetPackedElementsKind(kind); |
| 3705 | 3709 |
| 3706 literals->set(0, Smi::FromInt(kind)); | 3710 literals->set(0, Smi::FromInt(kind)); |
| 3707 literals->set(1, *element_values); | 3711 literals->set(1, *element_values); |
| 3708 | 3712 |
| 3709 return factory()->NewArrayLiteral( | 3713 return factory()->NewArrayLiteral( |
| 3710 literals, values, literal_index, is_simple, depth); | 3714 literals, values, literal_index, is_simple, depth, pos); |
| 3711 } | 3715 } |
| 3712 | 3716 |
| 3713 | 3717 |
| 3714 bool Parser::IsBoilerplateProperty(ObjectLiteral::Property* property) { | 3718 bool Parser::IsBoilerplateProperty(ObjectLiteral::Property* property) { |
| 3715 return property != NULL && | 3719 return property != NULL && |
| 3716 property->kind() != ObjectLiteral::Property::PROTOTYPE; | 3720 property->kind() != ObjectLiteral::Property::PROTOTYPE; |
| 3717 } | 3721 } |
| 3718 | 3722 |
| 3719 | 3723 |
| 3720 bool CompileTimeValue::IsCompileTimeValue(Expression* expression) { | 3724 bool CompileTimeValue::IsCompileTimeValue(Expression* expression) { |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3764 if (expression->AsLiteral() != NULL) { | 3768 if (expression->AsLiteral() != NULL) { |
| 3765 return expression->AsLiteral()->value(); | 3769 return expression->AsLiteral()->value(); |
| 3766 } | 3770 } |
| 3767 if (CompileTimeValue::IsCompileTimeValue(expression)) { | 3771 if (CompileTimeValue::IsCompileTimeValue(expression)) { |
| 3768 return CompileTimeValue::GetValue(isolate(), expression); | 3772 return CompileTimeValue::GetValue(isolate(), expression); |
| 3769 } | 3773 } |
| 3770 return isolate()->factory()->uninitialized_value(); | 3774 return isolate()->factory()->uninitialized_value(); |
| 3771 } | 3775 } |
| 3772 | 3776 |
| 3773 | 3777 |
| 3774 // Validation per 11.1.5 Object Initialiser | |
| 3775 class ObjectLiteralPropertyChecker { | |
| 3776 public: | |
| 3777 ObjectLiteralPropertyChecker(Parser* parser, LanguageMode language_mode) : | |
| 3778 props_(Literal::Match), | |
| 3779 parser_(parser), | |
| 3780 language_mode_(language_mode) { | |
| 3781 } | |
| 3782 | |
| 3783 void CheckProperty( | |
| 3784 ObjectLiteral::Property* property, | |
| 3785 Scanner::Location loc, | |
| 3786 bool* ok); | |
| 3787 | |
| 3788 private: | |
| 3789 enum PropertyKind { | |
| 3790 kGetAccessor = 0x01, | |
| 3791 kSetAccessor = 0x02, | |
| 3792 kAccessor = kGetAccessor | kSetAccessor, | |
| 3793 kData = 0x04 | |
| 3794 }; | |
| 3795 | |
| 3796 static intptr_t GetPropertyKind(ObjectLiteral::Property* property) { | |
| 3797 switch (property->kind()) { | |
| 3798 case ObjectLiteral::Property::GETTER: | |
| 3799 return kGetAccessor; | |
| 3800 case ObjectLiteral::Property::SETTER: | |
| 3801 return kSetAccessor; | |
| 3802 default: | |
| 3803 return kData; | |
| 3804 } | |
| 3805 } | |
| 3806 | |
| 3807 HashMap props_; | |
| 3808 Parser* parser_; | |
| 3809 LanguageMode language_mode_; | |
| 3810 }; | |
| 3811 | |
| 3812 | |
| 3813 void ObjectLiteralPropertyChecker::CheckProperty( | |
| 3814 ObjectLiteral::Property* property, | |
| 3815 Scanner::Location loc, | |
| 3816 bool* ok) { | |
| 3817 ASSERT(property != NULL); | |
| 3818 Literal* literal = property->key(); | |
| 3819 HashMap::Entry* entry = props_.Lookup(literal, literal->Hash(), true); | |
| 3820 intptr_t prev = reinterpret_cast<intptr_t> (entry->value); | |
| 3821 intptr_t curr = GetPropertyKind(property); | |
| 3822 | |
| 3823 // Duplicate data properties are illegal in strict or extended mode. | |
| 3824 if (language_mode_ != CLASSIC_MODE && (curr & prev & kData) != 0) { | |
| 3825 parser_->ReportMessageAt(loc, "strict_duplicate_property", | |
| 3826 Vector<const char*>::empty()); | |
| 3827 *ok = false; | |
| 3828 return; | |
| 3829 } | |
| 3830 // Data property conflicting with an accessor. | |
| 3831 if (((curr & kData) && (prev & kAccessor)) || | |
| 3832 ((prev & kData) && (curr & kAccessor))) { | |
| 3833 parser_->ReportMessageAt(loc, "accessor_data_property", | |
| 3834 Vector<const char*>::empty()); | |
| 3835 *ok = false; | |
| 3836 return; | |
| 3837 } | |
| 3838 // Two accessors of the same type conflicting | |
| 3839 if ((curr & prev & kAccessor) != 0) { | |
| 3840 parser_->ReportMessageAt(loc, "accessor_get_set", | |
| 3841 Vector<const char*>::empty()); | |
| 3842 *ok = false; | |
| 3843 return; | |
| 3844 } | |
| 3845 | |
| 3846 // Update map | |
| 3847 entry->value = reinterpret_cast<void*> (prev | curr); | |
| 3848 *ok = true; | |
| 3849 } | |
| 3850 | |
| 3851 | |
| 3852 void Parser::BuildObjectLiteralConstantProperties( | 3778 void Parser::BuildObjectLiteralConstantProperties( |
| 3853 ZoneList<ObjectLiteral::Property*>* properties, | 3779 ZoneList<ObjectLiteral::Property*>* properties, |
| 3854 Handle<FixedArray> constant_properties, | 3780 Handle<FixedArray> constant_properties, |
| 3855 bool* is_simple, | 3781 bool* is_simple, |
| 3856 bool* fast_elements, | 3782 bool* fast_elements, |
| 3857 int* depth, | 3783 int* depth, |
| 3858 bool* may_store_doubles) { | 3784 bool* may_store_doubles) { |
| 3859 int position = 0; | 3785 int position = 0; |
| 3860 // Accumulate the value in local variables and store it at the end. | 3786 // Accumulate the value in local variables and store it at the end. |
| 3861 bool is_simple_acc = true; | 3787 bool is_simple_acc = true; |
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3914 constant_properties->set(position++, *key); | 3840 constant_properties->set(position++, *key); |
| 3915 constant_properties->set(position++, *value); | 3841 constant_properties->set(position++, *value); |
| 3916 } | 3842 } |
| 3917 *fast_elements = | 3843 *fast_elements = |
| 3918 (max_element_index <= 32) || ((2 * elements) >= max_element_index); | 3844 (max_element_index <= 32) || ((2 * elements) >= max_element_index); |
| 3919 *is_simple = is_simple_acc; | 3845 *is_simple = is_simple_acc; |
| 3920 *depth = depth_acc; | 3846 *depth = depth_acc; |
| 3921 } | 3847 } |
| 3922 | 3848 |
| 3923 | 3849 |
| 3924 ObjectLiteral::Property* Parser::ParseObjectLiteralGetSet(bool is_getter, | |
| 3925 bool* ok) { | |
| 3926 // Special handling of getter and setter syntax: | |
| 3927 // { ... , get foo() { ... }, ... , set foo(v) { ... v ... } , ... } | |
| 3928 // We have already read the "get" or "set" keyword. | |
| 3929 Token::Value next = Next(); | |
| 3930 bool is_keyword = Token::IsKeyword(next); | |
| 3931 if (next == Token::IDENTIFIER || next == Token::NUMBER || | |
| 3932 next == Token::FUTURE_RESERVED_WORD || | |
| 3933 next == Token::FUTURE_STRICT_RESERVED_WORD || | |
| 3934 next == Token::STRING || is_keyword) { | |
| 3935 Handle<String> name; | |
| 3936 if (is_keyword) { | |
| 3937 name = isolate_->factory()->InternalizeUtf8String(Token::String(next)); | |
| 3938 } else { | |
| 3939 name = GetSymbol(); | |
| 3940 } | |
| 3941 FunctionLiteral* value = | |
| 3942 ParseFunctionLiteral(name, | |
| 3943 false, // reserved words are allowed here | |
| 3944 false, // not a generator | |
| 3945 RelocInfo::kNoPosition, | |
| 3946 FunctionLiteral::ANONYMOUS_EXPRESSION, | |
| 3947 CHECK_OK); | |
| 3948 // Allow any number of parameters for compatibilty with JSC. | |
| 3949 // Specification only allows zero parameters for get and one for set. | |
| 3950 return factory()->NewObjectLiteralProperty(is_getter, value); | |
| 3951 } else { | |
| 3952 ReportUnexpectedToken(next); | |
| 3953 *ok = false; | |
| 3954 return NULL; | |
| 3955 } | |
| 3956 } | |
| 3957 | |
| 3958 | |
| 3959 Expression* Parser::ParseObjectLiteral(bool* ok) { | 3850 Expression* Parser::ParseObjectLiteral(bool* ok) { |
| 3960 // ObjectLiteral :: | 3851 // ObjectLiteral :: |
| 3961 // '{' ( | 3852 // '{' ( |
| 3962 // ((IdentifierName | String | Number) ':' AssignmentExpression) | 3853 // ((IdentifierName | String | Number) ':' AssignmentExpression) |
| 3963 // | (('get' | 'set') (IdentifierName | String | Number) FunctionLiteral) | 3854 // | (('get' | 'set') (IdentifierName | String | Number) FunctionLiteral) |
| 3964 // )*[','] '}' | 3855 // )*[','] '}' |
| 3965 | 3856 |
| 3857 int pos = peek_position(); |
| 3966 ZoneList<ObjectLiteral::Property*>* properties = | 3858 ZoneList<ObjectLiteral::Property*>* properties = |
| 3967 new(zone()) ZoneList<ObjectLiteral::Property*>(4, zone()); | 3859 new(zone()) ZoneList<ObjectLiteral::Property*>(4, zone()); |
| 3968 int number_of_boilerplate_properties = 0; | 3860 int number_of_boilerplate_properties = 0; |
| 3969 bool has_function = false; | 3861 bool has_function = false; |
| 3970 | 3862 |
| 3971 ObjectLiteralPropertyChecker checker(this, top_scope_->language_mode()); | 3863 ObjectLiteralChecker checker(this, top_scope_->language_mode()); |
| 3972 | 3864 |
| 3973 Expect(Token::LBRACE, CHECK_OK); | 3865 Expect(Token::LBRACE, CHECK_OK); |
| 3974 | 3866 |
| 3975 while (peek() != Token::RBRACE) { | 3867 while (peek() != Token::RBRACE) { |
| 3976 if (fni_ != NULL) fni_->Enter(); | 3868 if (fni_ != NULL) fni_->Enter(); |
| 3977 | 3869 |
| 3978 Literal* key = NULL; | 3870 Literal* key = NULL; |
| 3979 Token::Value next = peek(); | 3871 Token::Value next = peek(); |
| 3980 | 3872 int next_pos = peek_position(); |
| 3981 // Location of the property name token | |
| 3982 Scanner::Location loc = scanner().peek_location(); | |
| 3983 | 3873 |
| 3984 switch (next) { | 3874 switch (next) { |
| 3985 case Token::FUTURE_RESERVED_WORD: | 3875 case Token::FUTURE_RESERVED_WORD: |
| 3986 case Token::FUTURE_STRICT_RESERVED_WORD: | 3876 case Token::FUTURE_STRICT_RESERVED_WORD: |
| 3987 case Token::IDENTIFIER: { | 3877 case Token::IDENTIFIER: { |
| 3988 bool is_getter = false; | 3878 bool is_getter = false; |
| 3989 bool is_setter = false; | 3879 bool is_setter = false; |
| 3990 Handle<String> id = | 3880 Handle<String> id = |
| 3991 ParseIdentifierNameOrGetOrSet(&is_getter, &is_setter, CHECK_OK); | 3881 ParseIdentifierNameOrGetOrSet(&is_getter, &is_setter, CHECK_OK); |
| 3992 if (fni_ != NULL) fni_->PushLiteralName(id); | 3882 if (fni_ != NULL) fni_->PushLiteralName(id); |
| 3993 | 3883 |
| 3994 if ((is_getter || is_setter) && peek() != Token::COLON) { | 3884 if ((is_getter || is_setter) && peek() != Token::COLON) { |
| 3995 // Update loc to point to the identifier | 3885 // Special handling of getter and setter syntax: |
| 3996 loc = scanner().peek_location(); | 3886 // { ... , get foo() { ... }, ... , set foo(v) { ... v ... } , ... } |
| 3997 ObjectLiteral::Property* property = | 3887 // We have already read the "get" or "set" keyword. |
| 3998 ParseObjectLiteralGetSet(is_getter, CHECK_OK); | 3888 Token::Value next = Next(); |
| 3999 if (IsBoilerplateProperty(property)) { | 3889 bool is_keyword = Token::IsKeyword(next); |
| 4000 number_of_boilerplate_properties++; | 3890 if (next != i::Token::IDENTIFIER && |
| 4001 } | 3891 next != i::Token::FUTURE_RESERVED_WORD && |
| 4002 // Validate the property. | 3892 next != i::Token::FUTURE_STRICT_RESERVED_WORD && |
| 4003 checker.CheckProperty(property, loc, CHECK_OK); | 3893 next != i::Token::NUMBER && |
| 4004 properties->Add(property, zone()); | 3894 next != i::Token::STRING && |
| 4005 if (peek() != Token::RBRACE) Expect(Token::COMMA, CHECK_OK); | 3895 !is_keyword) { |
| 3896 // Unexpected token. |
| 3897 ReportUnexpectedToken(next); |
| 3898 *ok = false; |
| 3899 return NULL; |
| 3900 } |
| 3901 // Validate the property. |
| 3902 PropertyKind type = is_getter ? kGetterProperty : kSetterProperty; |
| 3903 checker.CheckProperty(next, type, CHECK_OK); |
| 3904 Handle<String> name = is_keyword |
| 3905 ? isolate_->factory()->InternalizeUtf8String(Token::String(next)) |
| 3906 : GetSymbol(); |
| 3907 FunctionLiteral* value = |
| 3908 ParseFunctionLiteral(name, |
| 3909 false, // reserved words are allowed here |
| 3910 false, // not a generator |
| 3911 RelocInfo::kNoPosition, |
| 3912 FunctionLiteral::ANONYMOUS_EXPRESSION, |
| 3913 CHECK_OK); |
| 3914 // Allow any number of parameters for compatibilty with JSC. |
| 3915 // Specification only allows zero parameters for get and one for set. |
| 3916 ObjectLiteral::Property* property = |
| 3917 factory()->NewObjectLiteralProperty(is_getter, value, next_pos); |
| 3918 if (IsBoilerplateProperty(property)) { |
| 3919 number_of_boilerplate_properties++; |
| 3920 } |
| 3921 properties->Add(property, zone()); |
| 3922 if (peek() != Token::RBRACE) Expect(Token::COMMA, CHECK_OK); |
| 4006 | 3923 |
| 4007 if (fni_ != NULL) { | 3924 if (fni_ != NULL) { |
| 4008 fni_->Infer(); | 3925 fni_->Infer(); |
| 4009 fni_->Leave(); | 3926 fni_->Leave(); |
| 4010 } | 3927 } |
| 4011 continue; // restart the while | 3928 continue; // restart the while |
| 4012 } | 3929 } |
| 4013 // Failed to parse as get/set property, so it's just a property | 3930 // Failed to parse as get/set property, so it's just a property |
| 4014 // called "get" or "set". | 3931 // called "get" or "set". |
| 4015 key = factory()->NewLiteral(id); | 3932 key = factory()->NewLiteral(id, next_pos); |
| 4016 break; | 3933 break; |
| 4017 } | 3934 } |
| 4018 case Token::STRING: { | 3935 case Token::STRING: { |
| 4019 Consume(Token::STRING); | 3936 Consume(Token::STRING); |
| 4020 Handle<String> string = GetSymbol(); | 3937 Handle<String> string = GetSymbol(); |
| 4021 if (fni_ != NULL) fni_->PushLiteralName(string); | 3938 if (fni_ != NULL) fni_->PushLiteralName(string); |
| 4022 uint32_t index; | 3939 uint32_t index; |
| 4023 if (!string.is_null() && string->AsArrayIndex(&index)) { | 3940 if (!string.is_null() && string->AsArrayIndex(&index)) { |
| 4024 key = factory()->NewNumberLiteral(index); | 3941 key = factory()->NewNumberLiteral(index, next_pos); |
| 4025 break; | 3942 break; |
| 4026 } | 3943 } |
| 4027 key = factory()->NewLiteral(string); | 3944 key = factory()->NewLiteral(string, next_pos); |
| 4028 break; | 3945 break; |
| 4029 } | 3946 } |
| 4030 case Token::NUMBER: { | 3947 case Token::NUMBER: { |
| 4031 Consume(Token::NUMBER); | 3948 Consume(Token::NUMBER); |
| 4032 ASSERT(scanner().is_literal_ascii()); | 3949 ASSERT(scanner().is_literal_ascii()); |
| 4033 double value = StringToDouble(isolate()->unicode_cache(), | 3950 double value = StringToDouble(isolate()->unicode_cache(), |
| 4034 scanner().literal_ascii_string(), | 3951 scanner().literal_ascii_string(), |
| 4035 ALLOW_HEX | ALLOW_OCTAL | | 3952 ALLOW_HEX | ALLOW_OCTAL | |
| 4036 ALLOW_IMPLICIT_OCTAL | ALLOW_BINARY); | 3953 ALLOW_IMPLICIT_OCTAL | ALLOW_BINARY); |
| 4037 key = factory()->NewNumberLiteral(value); | 3954 key = factory()->NewNumberLiteral(value, next_pos); |
| 4038 break; | 3955 break; |
| 4039 } | 3956 } |
| 4040 default: | 3957 default: |
| 4041 if (Token::IsKeyword(next)) { | 3958 if (Token::IsKeyword(next)) { |
| 4042 Consume(next); | 3959 Consume(next); |
| 4043 Handle<String> string = GetSymbol(); | 3960 Handle<String> string = GetSymbol(); |
| 4044 key = factory()->NewLiteral(string); | 3961 key = factory()->NewLiteral(string, next_pos); |
| 4045 } else { | 3962 } else { |
| 4046 // Unexpected token. | 3963 // Unexpected token. |
| 4047 Token::Value next = Next(); | 3964 Token::Value next = Next(); |
| 4048 ReportUnexpectedToken(next); | 3965 ReportUnexpectedToken(next); |
| 4049 *ok = false; | 3966 *ok = false; |
| 4050 return NULL; | 3967 return NULL; |
| 4051 } | 3968 } |
| 4052 } | 3969 } |
| 4053 | 3970 |
| 3971 // Validate the property |
| 3972 checker.CheckProperty(next, kValueProperty, CHECK_OK); |
| 3973 |
| 4054 Expect(Token::COLON, CHECK_OK); | 3974 Expect(Token::COLON, CHECK_OK); |
| 4055 Expression* value = ParseAssignmentExpression(true, CHECK_OK); | 3975 Expression* value = ParseAssignmentExpression(true, CHECK_OK); |
| 4056 | 3976 |
| 4057 ObjectLiteral::Property* property = | 3977 ObjectLiteral::Property* property = |
| 4058 new(zone()) ObjectLiteral::Property(key, value, isolate()); | 3978 new(zone()) ObjectLiteral::Property(key, value, isolate()); |
| 4059 | 3979 |
| 4060 // Mark top-level object literals that contain function literals and | 3980 // Mark top-level object literals that contain function literals and |
| 4061 // pretenure the literal so it can be added as a constant function | 3981 // pretenure the literal so it can be added as a constant function |
| 4062 // property. | 3982 // property. |
| 4063 if (top_scope_->DeclarationScope()->is_global_scope() && | 3983 if (top_scope_->DeclarationScope()->is_global_scope() && |
| 4064 value->AsFunctionLiteral() != NULL) { | 3984 value->AsFunctionLiteral() != NULL) { |
| 4065 has_function = true; | 3985 has_function = true; |
| 4066 value->AsFunctionLiteral()->set_pretenure(); | 3986 value->AsFunctionLiteral()->set_pretenure(); |
| 4067 } | 3987 } |
| 4068 | 3988 |
| 4069 // Count CONSTANT or COMPUTED properties to maintain the enumeration order. | 3989 // Count CONSTANT or COMPUTED properties to maintain the enumeration order. |
| 4070 if (IsBoilerplateProperty(property)) number_of_boilerplate_properties++; | 3990 if (IsBoilerplateProperty(property)) number_of_boilerplate_properties++; |
| 4071 // Validate the property | |
| 4072 checker.CheckProperty(property, loc, CHECK_OK); | |
| 4073 properties->Add(property, zone()); | 3991 properties->Add(property, zone()); |
| 4074 | 3992 |
| 4075 // TODO(1240767): Consider allowing trailing comma. | 3993 // TODO(1240767): Consider allowing trailing comma. |
| 4076 if (peek() != Token::RBRACE) Expect(Token::COMMA, CHECK_OK); | 3994 if (peek() != Token::RBRACE) Expect(Token::COMMA, CHECK_OK); |
| 4077 | 3995 |
| 4078 if (fni_ != NULL) { | 3996 if (fni_ != NULL) { |
| 4079 fni_->Infer(); | 3997 fni_->Infer(); |
| 4080 fni_->Leave(); | 3998 fni_->Leave(); |
| 4081 } | 3999 } |
| 4082 } | 4000 } |
| (...skipping 15 matching lines...) Expand all Loading... |
| 4098 &fast_elements, | 4016 &fast_elements, |
| 4099 &depth, | 4017 &depth, |
| 4100 &may_store_doubles); | 4018 &may_store_doubles); |
| 4101 return factory()->NewObjectLiteral(constant_properties, | 4019 return factory()->NewObjectLiteral(constant_properties, |
| 4102 properties, | 4020 properties, |
| 4103 literal_index, | 4021 literal_index, |
| 4104 is_simple, | 4022 is_simple, |
| 4105 fast_elements, | 4023 fast_elements, |
| 4106 depth, | 4024 depth, |
| 4107 may_store_doubles, | 4025 may_store_doubles, |
| 4108 has_function); | 4026 has_function, |
| 4027 pos); |
| 4109 } | 4028 } |
| 4110 | 4029 |
| 4111 | 4030 |
| 4112 Expression* Parser::ParseRegExpLiteral(bool seen_equal, bool* ok) { | 4031 Expression* Parser::ParseRegExpLiteral(bool seen_equal, bool* ok) { |
| 4032 int pos = peek_position(); |
| 4113 if (!scanner().ScanRegExpPattern(seen_equal)) { | 4033 if (!scanner().ScanRegExpPattern(seen_equal)) { |
| 4114 Next(); | 4034 Next(); |
| 4115 ReportMessage("unterminated_regexp", Vector<const char*>::empty()); | 4035 ReportMessage("unterminated_regexp", Vector<const char*>::empty()); |
| 4116 *ok = false; | 4036 *ok = false; |
| 4117 return NULL; | 4037 return NULL; |
| 4118 } | 4038 } |
| 4119 | 4039 |
| 4120 int literal_index = current_function_state_->NextMaterializedLiteralIndex(); | 4040 int literal_index = current_function_state_->NextMaterializedLiteralIndex(); |
| 4121 | 4041 |
| 4122 Handle<String> js_pattern = NextLiteralString(TENURED); | 4042 Handle<String> js_pattern = NextLiteralString(TENURED); |
| 4123 scanner().ScanRegExpFlags(); | 4043 scanner().ScanRegExpFlags(); |
| 4124 Handle<String> js_flags = NextLiteralString(TENURED); | 4044 Handle<String> js_flags = NextLiteralString(TENURED); |
| 4125 Next(); | 4045 Next(); |
| 4126 | 4046 |
| 4127 return factory()->NewRegExpLiteral(js_pattern, js_flags, literal_index); | 4047 return factory()->NewRegExpLiteral(js_pattern, js_flags, literal_index, pos); |
| 4128 } | 4048 } |
| 4129 | 4049 |
| 4130 | 4050 |
| 4131 ZoneList<Expression*>* Parser::ParseArguments(bool* ok) { | 4051 ZoneList<Expression*>* Parser::ParseArguments(bool* ok) { |
| 4132 // Arguments :: | 4052 // Arguments :: |
| 4133 // '(' (AssignmentExpression)*[','] ')' | 4053 // '(' (AssignmentExpression)*[','] ')' |
| 4134 | 4054 |
| 4135 ZoneList<Expression*>* result = new(zone()) ZoneList<Expression*>(4, zone()); | 4055 ZoneList<Expression*>* result = new(zone()) ZoneList<Expression*>(4, zone()); |
| 4136 Expect(Token::LPAREN, CHECK_OK); | 4056 Expect(Token::LPAREN, CHECK_OK); |
| 4137 bool done = (peek() == Token::RPAREN); | 4057 bool done = (peek() == Token::RPAREN); |
| (...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4242 // For error messages. | 4162 // For error messages. |
| 4243 const char* message_; | 4163 const char* message_; |
| 4244 const char* argument_opt_; | 4164 const char* argument_opt_; |
| 4245 }; | 4165 }; |
| 4246 | 4166 |
| 4247 | 4167 |
| 4248 FunctionLiteral* Parser::ParseFunctionLiteral( | 4168 FunctionLiteral* Parser::ParseFunctionLiteral( |
| 4249 Handle<String> function_name, | 4169 Handle<String> function_name, |
| 4250 bool name_is_strict_reserved, | 4170 bool name_is_strict_reserved, |
| 4251 bool is_generator, | 4171 bool is_generator, |
| 4252 int function_token_position, | 4172 int function_token_pos, |
| 4253 FunctionLiteral::FunctionType function_type, | 4173 FunctionLiteral::FunctionType function_type, |
| 4254 bool* ok) { | 4174 bool* ok) { |
| 4255 // Function :: | 4175 // Function :: |
| 4256 // '(' FormalParameterList? ')' '{' FunctionBody '}' | 4176 // '(' FormalParameterList? ')' '{' FunctionBody '}' |
| 4257 | 4177 |
| 4178 int pos = function_token_pos == RelocInfo::kNoPosition |
| 4179 ? peek_position() : function_token_pos; |
| 4180 |
| 4258 // Anonymous functions were passed either the empty symbol or a null | 4181 // Anonymous functions were passed either the empty symbol or a null |
| 4259 // handle as the function name. Remember if we were passed a non-empty | 4182 // handle as the function name. Remember if we were passed a non-empty |
| 4260 // handle to decide whether to invoke function name inference. | 4183 // handle to decide whether to invoke function name inference. |
| 4261 bool should_infer_name = function_name.is_null(); | 4184 bool should_infer_name = function_name.is_null(); |
| 4262 | 4185 |
| 4263 // We want a non-null handle as the function name. | 4186 // We want a non-null handle as the function name. |
| 4264 if (should_infer_name) { | 4187 if (should_infer_name) { |
| 4265 function_name = isolate()->factory()->empty_string(); | 4188 function_name = isolate()->factory()->empty_string(); |
| 4266 } | 4189 } |
| 4267 | 4190 |
| (...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4385 // instead of Variables and Proxis as is the case now. | 4308 // instead of Variables and Proxis as is the case now. |
| 4386 Variable* fvar = NULL; | 4309 Variable* fvar = NULL; |
| 4387 Token::Value fvar_init_op = Token::INIT_CONST; | 4310 Token::Value fvar_init_op = Token::INIT_CONST; |
| 4388 if (function_type == FunctionLiteral::NAMED_EXPRESSION) { | 4311 if (function_type == FunctionLiteral::NAMED_EXPRESSION) { |
| 4389 if (is_extended_mode()) fvar_init_op = Token::INIT_CONST_HARMONY; | 4312 if (is_extended_mode()) fvar_init_op = Token::INIT_CONST_HARMONY; |
| 4390 VariableMode fvar_mode = is_extended_mode() ? CONST_HARMONY : CONST; | 4313 VariableMode fvar_mode = is_extended_mode() ? CONST_HARMONY : CONST; |
| 4391 fvar = new(zone()) Variable(top_scope_, | 4314 fvar = new(zone()) Variable(top_scope_, |
| 4392 function_name, fvar_mode, true /* is valid LHS */, | 4315 function_name, fvar_mode, true /* is valid LHS */, |
| 4393 Variable::NORMAL, kCreatedInitialized, Interface::NewConst()); | 4316 Variable::NORMAL, kCreatedInitialized, Interface::NewConst()); |
| 4394 VariableProxy* proxy = factory()->NewVariableProxy(fvar); | 4317 VariableProxy* proxy = factory()->NewVariableProxy(fvar); |
| 4395 VariableDeclaration* fvar_declaration = | 4318 VariableDeclaration* fvar_declaration = factory()->NewVariableDeclaration( |
| 4396 factory()->NewVariableDeclaration(proxy, fvar_mode, top_scope_); | 4319 proxy, fvar_mode, top_scope_, RelocInfo::kNoPosition); |
| 4397 top_scope_->DeclareFunctionVar(fvar_declaration); | 4320 top_scope_->DeclareFunctionVar(fvar_declaration); |
| 4398 } | 4321 } |
| 4399 | 4322 |
| 4400 // Determine whether the function will be lazily compiled. | 4323 // Determine whether the function will be lazily compiled. |
| 4401 // The heuristics are: | 4324 // The heuristics are: |
| 4402 // - It must not have been prohibited by the caller to Parse (some callers | 4325 // - It must not have been prohibited by the caller to Parse (some callers |
| 4403 // need a full AST). | 4326 // need a full AST). |
| 4404 // - The outer scope must allow lazy compilation of inner functions. | 4327 // - The outer scope must allow lazy compilation of inner functions. |
| 4405 // - The function mustn't be a function expression with an open parenthesis | 4328 // - The function mustn't be a function expression with an open parenthesis |
| 4406 // before; we consider that a hint that the function will be called | 4329 // before; we consider that a hint that the function will be called |
| 4407 // immediately, and it would be a waste of time to make it lazily | 4330 // immediately, and it would be a waste of time to make it lazily |
| 4408 // compiled. | 4331 // compiled. |
| 4409 // These are all things we can know at this point, without looking at the | 4332 // These are all things we can know at this point, without looking at the |
| 4410 // function itself. | 4333 // function itself. |
| 4411 bool is_lazily_compiled = (mode() == PARSE_LAZILY && | 4334 bool is_lazily_compiled = (mode() == PARSE_LAZILY && |
| 4412 top_scope_->AllowsLazyCompilation() && | 4335 top_scope_->AllowsLazyCompilation() && |
| 4413 !parenthesized_function_); | 4336 !parenthesized_function_); |
| 4414 parenthesized_function_ = false; // The bit was set for this function only. | 4337 parenthesized_function_ = false; // The bit was set for this function only. |
| 4415 | 4338 |
| 4416 if (is_lazily_compiled) { | 4339 if (is_lazily_compiled) { |
| 4417 int function_block_pos = scanner().location().beg_pos; | 4340 int function_block_pos = position(); |
| 4418 FunctionEntry entry; | 4341 FunctionEntry entry; |
| 4419 if (pre_parse_data_ != NULL) { | 4342 if (pre_parse_data_ != NULL) { |
| 4420 // If we have pre_parse_data_, we use it to skip parsing the function | 4343 // If we have pre_parse_data_, we use it to skip parsing the function |
| 4421 // body. The preparser data contains the information we need to | 4344 // body. The preparser data contains the information we need to |
| 4422 // construct the lazy function. | 4345 // construct the lazy function. |
| 4423 entry = pre_parse_data()->GetFunctionEntry(function_block_pos); | 4346 entry = pre_parse_data()->GetFunctionEntry(function_block_pos); |
| 4424 if (entry.is_valid()) { | 4347 if (entry.is_valid()) { |
| 4425 if (entry.end_pos() <= function_block_pos) { | 4348 if (entry.end_pos() <= function_block_pos) { |
| 4426 // End position greater than end of stream is safe, and hard | 4349 // End position greater than end of stream is safe, and hard |
| 4427 // to check. | 4350 // to check. |
| 4428 ReportInvalidPreparseData(function_name, CHECK_OK); | 4351 ReportInvalidPreparseData(function_name, CHECK_OK); |
| 4429 } | 4352 } |
| 4430 scanner().SeekForward(entry.end_pos() - 1); | 4353 scanner().SeekForward(entry.end_pos() - 1); |
| 4431 | 4354 |
| 4432 scope->set_end_position(entry.end_pos()); | 4355 scope->set_end_position(entry.end_pos()); |
| 4433 Expect(Token::RBRACE, CHECK_OK); | 4356 Expect(Token::RBRACE, CHECK_OK); |
| 4434 isolate()->counters()->total_preparse_skipped()->Increment( | 4357 isolate()->counters()->total_preparse_skipped()->Increment( |
| 4435 scope->end_position() - function_block_pos); | 4358 scope->end_position() - function_block_pos); |
| 4436 materialized_literal_count = entry.literal_count(); | 4359 materialized_literal_count = entry.literal_count(); |
| 4437 expected_property_count = entry.property_count(); | 4360 expected_property_count = entry.property_count(); |
| 4438 top_scope_->SetLanguageMode(entry.language_mode()); | 4361 top_scope_->SetLanguageMode(entry.language_mode()); |
| 4439 } else { | 4362 } else { |
| 4440 is_lazily_compiled = false; | 4363 is_lazily_compiled = false; |
| 4441 } | 4364 } |
| 4442 } else { | 4365 } else { |
| 4443 // With no preparser data, we partially parse the function, without | 4366 // With no preparser data, we partially parse the function, without |
| 4444 // building an AST. This gathers the data needed to build a lazy | 4367 // building an AST. This gathers the data needed to build a lazy |
| 4445 // function. | 4368 // function. |
| 4446 SingletonLogger logger; | 4369 SingletonLogger logger; |
| 4447 preparser::PreParser::PreParseResult result = | 4370 PreParser::PreParseResult result = LazyParseFunctionLiteral(&logger); |
| 4448 LazyParseFunctionLiteral(&logger); | 4371 if (result == PreParser::kPreParseStackOverflow) { |
| 4449 if (result == preparser::PreParser::kPreParseStackOverflow) { | |
| 4450 // Propagate stack overflow. | 4372 // Propagate stack overflow. |
| 4451 stack_overflow_ = true; | 4373 set_stack_overflow(); |
| 4452 *ok = false; | 4374 *ok = false; |
| 4453 return NULL; | 4375 return NULL; |
| 4454 } | 4376 } |
| 4455 if (logger.has_error()) { | 4377 if (logger.has_error()) { |
| 4456 const char* arg = logger.argument_opt(); | 4378 const char* arg = logger.argument_opt(); |
| 4457 Vector<const char*> args; | 4379 Vector<const char*> args; |
| 4458 if (arg != NULL) { | 4380 if (arg != NULL) { |
| 4459 args = Vector<const char*>(&arg, 1); | 4381 args = Vector<const char*>(&arg, 1); |
| 4460 } | 4382 } |
| 4461 ReportMessageAt(Scanner::Location(logger.start(), logger.end()), | 4383 ReportMessageAt(Scanner::Location(logger.start(), logger.end()), |
| (...skipping 14 matching lines...) Expand all Loading... |
| 4476 if (!is_lazily_compiled) { | 4398 if (!is_lazily_compiled) { |
| 4477 ParsingModeScope parsing_mode(this, PARSE_EAGERLY); | 4399 ParsingModeScope parsing_mode(this, PARSE_EAGERLY); |
| 4478 body = new(zone()) ZoneList<Statement*>(8, zone()); | 4400 body = new(zone()) ZoneList<Statement*>(8, zone()); |
| 4479 if (fvar != NULL) { | 4401 if (fvar != NULL) { |
| 4480 VariableProxy* fproxy = top_scope_->NewUnresolved( | 4402 VariableProxy* fproxy = top_scope_->NewUnresolved( |
| 4481 factory(), function_name, Interface::NewConst()); | 4403 factory(), function_name, Interface::NewConst()); |
| 4482 fproxy->BindTo(fvar); | 4404 fproxy->BindTo(fvar); |
| 4483 body->Add(factory()->NewExpressionStatement( | 4405 body->Add(factory()->NewExpressionStatement( |
| 4484 factory()->NewAssignment(fvar_init_op, | 4406 factory()->NewAssignment(fvar_init_op, |
| 4485 fproxy, | 4407 fproxy, |
| 4486 factory()->NewThisFunction(), | 4408 factory()->NewThisFunction(pos), |
| 4487 RelocInfo::kNoPosition)), | 4409 RelocInfo::kNoPosition), |
| 4488 zone()); | 4410 RelocInfo::kNoPosition), zone()); |
| 4489 } | 4411 } |
| 4490 | 4412 |
| 4491 // For generators, allocate and yield an iterator on function entry. | 4413 // For generators, allocate and yield an iterator on function entry. |
| 4492 if (is_generator) { | 4414 if (is_generator) { |
| 4493 ZoneList<Expression*>* arguments = | 4415 ZoneList<Expression*>* arguments = |
| 4494 new(zone()) ZoneList<Expression*>(0, zone()); | 4416 new(zone()) ZoneList<Expression*>(0, zone()); |
| 4495 CallRuntime* allocation = factory()->NewCallRuntime( | 4417 CallRuntime* allocation = factory()->NewCallRuntime( |
| 4496 isolate()->factory()->empty_string(), | 4418 isolate()->factory()->empty_string(), |
| 4497 Runtime::FunctionForId(Runtime::kCreateJSGeneratorObject), | 4419 Runtime::FunctionForId(Runtime::kCreateJSGeneratorObject), |
| 4498 arguments); | 4420 arguments, pos); |
| 4499 VariableProxy* init_proxy = factory()->NewVariableProxy( | 4421 VariableProxy* init_proxy = factory()->NewVariableProxy( |
| 4500 current_function_state_->generator_object_variable()); | 4422 current_function_state_->generator_object_variable()); |
| 4501 Assignment* assignment = factory()->NewAssignment( | 4423 Assignment* assignment = factory()->NewAssignment( |
| 4502 Token::INIT_VAR, init_proxy, allocation, RelocInfo::kNoPosition); | 4424 Token::INIT_VAR, init_proxy, allocation, RelocInfo::kNoPosition); |
| 4503 VariableProxy* get_proxy = factory()->NewVariableProxy( | 4425 VariableProxy* get_proxy = factory()->NewVariableProxy( |
| 4504 current_function_state_->generator_object_variable()); | 4426 current_function_state_->generator_object_variable()); |
| 4505 Yield* yield = factory()->NewYield( | 4427 Yield* yield = factory()->NewYield( |
| 4506 get_proxy, assignment, Yield::INITIAL, RelocInfo::kNoPosition); | 4428 get_proxy, assignment, Yield::INITIAL, RelocInfo::kNoPosition); |
| 4507 body->Add(factory()->NewExpressionStatement(yield), zone()); | 4429 body->Add(factory()->NewExpressionStatement( |
| 4430 yield, RelocInfo::kNoPosition), zone()); |
| 4508 } | 4431 } |
| 4509 | 4432 |
| 4510 ParseSourceElements(body, Token::RBRACE, false, false, CHECK_OK); | 4433 ParseSourceElements(body, Token::RBRACE, false, false, CHECK_OK); |
| 4511 | 4434 |
| 4512 if (is_generator) { | 4435 if (is_generator) { |
| 4513 VariableProxy* get_proxy = factory()->NewVariableProxy( | 4436 VariableProxy* get_proxy = factory()->NewVariableProxy( |
| 4514 current_function_state_->generator_object_variable()); | 4437 current_function_state_->generator_object_variable()); |
| 4515 Expression *undefined = factory()->NewLiteral( | 4438 Expression *undefined = factory()->NewLiteral( |
| 4516 isolate()->factory()->undefined_value()); | 4439 isolate()->factory()->undefined_value(), RelocInfo::kNoPosition); |
| 4517 Yield* yield = factory()->NewYield( | 4440 Yield* yield = factory()->NewYield( |
| 4518 get_proxy, undefined, Yield::FINAL, RelocInfo::kNoPosition); | 4441 get_proxy, undefined, Yield::FINAL, RelocInfo::kNoPosition); |
| 4519 body->Add(factory()->NewExpressionStatement(yield), zone()); | 4442 body->Add(factory()->NewExpressionStatement( |
| 4443 yield, RelocInfo::kNoPosition), zone()); |
| 4520 } | 4444 } |
| 4521 | 4445 |
| 4522 materialized_literal_count = function_state.materialized_literal_count(); | 4446 materialized_literal_count = function_state.materialized_literal_count(); |
| 4523 expected_property_count = function_state.expected_property_count(); | 4447 expected_property_count = function_state.expected_property_count(); |
| 4524 handler_count = function_state.handler_count(); | 4448 handler_count = function_state.handler_count(); |
| 4525 | 4449 |
| 4526 Expect(Token::RBRACE, CHECK_OK); | 4450 Expect(Token::RBRACE, CHECK_OK); |
| 4527 scope->set_end_position(scanner().location().end_pos); | 4451 scope->set_end_position(scanner().location().end_pos); |
| 4528 } | 4452 } |
| 4529 | 4453 |
| 4530 // Validate strict mode. | 4454 // Validate strict mode. |
| 4531 if (!top_scope_->is_classic_mode()) { | 4455 if (!top_scope_->is_classic_mode()) { |
| 4532 if (IsEvalOrArguments(function_name)) { | 4456 if (IsEvalOrArguments(function_name)) { |
| 4533 int start_pos = scope->start_position(); | 4457 int start_pos = scope->start_position(); |
| 4534 int position = function_token_position != RelocInfo::kNoPosition | 4458 int position = function_token_pos != RelocInfo::kNoPosition |
| 4535 ? function_token_position | 4459 ? function_token_pos : (start_pos > 0 ? start_pos - 1 : start_pos); |
| 4536 : (start_pos > 0 ? start_pos - 1 : start_pos); | |
| 4537 Scanner::Location location = Scanner::Location(position, start_pos); | 4460 Scanner::Location location = Scanner::Location(position, start_pos); |
| 4538 ReportMessageAt(location, | 4461 ReportMessageAt(location, |
| 4539 "strict_function_name", Vector<const char*>::empty()); | 4462 "strict_function_name", Vector<const char*>::empty()); |
| 4540 *ok = false; | 4463 *ok = false; |
| 4541 return NULL; | 4464 return NULL; |
| 4542 } | 4465 } |
| 4543 if (name_loc.IsValid()) { | 4466 if (name_loc.IsValid()) { |
| 4544 ReportMessageAt(name_loc, "strict_param_name", | 4467 ReportMessageAt(name_loc, "strict_param_name", |
| 4545 Vector<const char*>::empty()); | 4468 Vector<const char*>::empty()); |
| 4546 *ok = false; | 4469 *ok = false; |
| 4547 return NULL; | 4470 return NULL; |
| 4548 } | 4471 } |
| 4549 if (dupe_loc.IsValid()) { | 4472 if (dupe_loc.IsValid()) { |
| 4550 ReportMessageAt(dupe_loc, "strict_param_dupe", | 4473 ReportMessageAt(dupe_loc, "strict_param_dupe", |
| 4551 Vector<const char*>::empty()); | 4474 Vector<const char*>::empty()); |
| 4552 *ok = false; | 4475 *ok = false; |
| 4553 return NULL; | 4476 return NULL; |
| 4554 } | 4477 } |
| 4555 if (name_is_strict_reserved) { | 4478 if (name_is_strict_reserved) { |
| 4556 int start_pos = scope->start_position(); | 4479 int start_pos = scope->start_position(); |
| 4557 int position = function_token_position != RelocInfo::kNoPosition | 4480 int position = function_token_pos != RelocInfo::kNoPosition |
| 4558 ? function_token_position | 4481 ? function_token_pos : (start_pos > 0 ? start_pos - 1 : start_pos); |
| 4559 : (start_pos > 0 ? start_pos - 1 : start_pos); | |
| 4560 Scanner::Location location = Scanner::Location(position, start_pos); | 4482 Scanner::Location location = Scanner::Location(position, start_pos); |
| 4561 ReportMessageAt(location, "strict_reserved_word", | 4483 ReportMessageAt(location, "strict_reserved_word", |
| 4562 Vector<const char*>::empty()); | 4484 Vector<const char*>::empty()); |
| 4563 *ok = false; | 4485 *ok = false; |
| 4564 return NULL; | 4486 return NULL; |
| 4565 } | 4487 } |
| 4566 if (reserved_loc.IsValid()) { | 4488 if (reserved_loc.IsValid()) { |
| 4567 ReportMessageAt(reserved_loc, "strict_reserved_word", | 4489 ReportMessageAt(reserved_loc, "strict_reserved_word", |
| 4568 Vector<const char*>::empty()); | 4490 Vector<const char*>::empty()); |
| 4569 *ok = false; | 4491 *ok = false; |
| (...skipping 16 matching lines...) Expand all Loading... |
| 4586 scope, | 4508 scope, |
| 4587 body, | 4509 body, |
| 4588 materialized_literal_count, | 4510 materialized_literal_count, |
| 4589 expected_property_count, | 4511 expected_property_count, |
| 4590 handler_count, | 4512 handler_count, |
| 4591 num_parameters, | 4513 num_parameters, |
| 4592 duplicate_parameters, | 4514 duplicate_parameters, |
| 4593 function_type, | 4515 function_type, |
| 4594 FunctionLiteral::kIsFunction, | 4516 FunctionLiteral::kIsFunction, |
| 4595 parenthesized, | 4517 parenthesized, |
| 4596 generator); | 4518 generator, |
| 4597 function_literal->set_function_token_position(function_token_position); | 4519 pos); |
| 4520 function_literal->set_function_token_position(function_token_pos); |
| 4598 function_literal->set_ast_properties(&ast_properties); | 4521 function_literal->set_ast_properties(&ast_properties); |
| 4599 function_literal->set_dont_optimize_reason(dont_optimize_reason); | 4522 function_literal->set_dont_optimize_reason(dont_optimize_reason); |
| 4600 | 4523 |
| 4601 if (fni_ != NULL && should_infer_name) fni_->AddFunction(function_literal); | 4524 if (fni_ != NULL && should_infer_name) fni_->AddFunction(function_literal); |
| 4602 return function_literal; | 4525 return function_literal; |
| 4603 } | 4526 } |
| 4604 | 4527 |
| 4605 | 4528 |
| 4606 preparser::PreParser::PreParseResult Parser::LazyParseFunctionLiteral( | 4529 PreParser::PreParseResult Parser::LazyParseFunctionLiteral( |
| 4607 SingletonLogger* logger) { | 4530 SingletonLogger* logger) { |
| 4608 HistogramTimerScope preparse_scope(isolate()->counters()->pre_parse()); | 4531 HistogramTimerScope preparse_scope(isolate()->counters()->pre_parse()); |
| 4609 ASSERT_EQ(Token::LBRACE, scanner().current_token()); | 4532 ASSERT_EQ(Token::LBRACE, scanner().current_token()); |
| 4610 | 4533 |
| 4611 if (reusable_preparser_ == NULL) { | 4534 if (reusable_preparser_ == NULL) { |
| 4612 intptr_t stack_limit = isolate()->stack_guard()->real_climit(); | 4535 intptr_t stack_limit = isolate()->stack_guard()->real_climit(); |
| 4613 reusable_preparser_ = new preparser::PreParser(&scanner_, | 4536 reusable_preparser_ = new PreParser(&scanner_, NULL, stack_limit); |
| 4614 NULL, | |
| 4615 stack_limit); | |
| 4616 reusable_preparser_->set_allow_harmony_scoping(allow_harmony_scoping()); | 4537 reusable_preparser_->set_allow_harmony_scoping(allow_harmony_scoping()); |
| 4617 reusable_preparser_->set_allow_modules(allow_modules()); | 4538 reusable_preparser_->set_allow_modules(allow_modules()); |
| 4618 reusable_preparser_->set_allow_natives_syntax(allow_natives_syntax()); | 4539 reusable_preparser_->set_allow_natives_syntax(allow_natives_syntax()); |
| 4619 reusable_preparser_->set_allow_lazy(true); | 4540 reusable_preparser_->set_allow_lazy(true); |
| 4620 reusable_preparser_->set_allow_generators(allow_generators()); | 4541 reusable_preparser_->set_allow_generators(allow_generators()); |
| 4621 reusable_preparser_->set_allow_for_of(allow_for_of()); | 4542 reusable_preparser_->set_allow_for_of(allow_for_of()); |
| 4622 reusable_preparser_->set_allow_harmony_numeric_literals( | 4543 reusable_preparser_->set_allow_harmony_numeric_literals( |
| 4623 allow_harmony_numeric_literals()); | 4544 allow_harmony_numeric_literals()); |
| 4624 } | 4545 } |
| 4625 preparser::PreParser::PreParseResult result = | 4546 PreParser::PreParseResult result = |
| 4626 reusable_preparser_->PreParseLazyFunction(top_scope_->language_mode(), | 4547 reusable_preparser_->PreParseLazyFunction(top_scope_->language_mode(), |
| 4627 is_generator(), | 4548 is_generator(), |
| 4628 logger); | 4549 logger); |
| 4629 return result; | 4550 return result; |
| 4630 } | 4551 } |
| 4631 | 4552 |
| 4632 | 4553 |
| 4633 Expression* Parser::ParseV8Intrinsic(bool* ok) { | 4554 Expression* Parser::ParseV8Intrinsic(bool* ok) { |
| 4634 // CallRuntime :: | 4555 // CallRuntime :: |
| 4635 // '%' Identifier Arguments | 4556 // '%' Identifier Arguments |
| 4636 | 4557 |
| 4558 int pos = peek_position(); |
| 4637 Expect(Token::MOD, CHECK_OK); | 4559 Expect(Token::MOD, CHECK_OK); |
| 4638 Handle<String> name = ParseIdentifier(CHECK_OK); | 4560 Handle<String> name = ParseIdentifier(CHECK_OK); |
| 4639 ZoneList<Expression*>* args = ParseArguments(CHECK_OK); | 4561 ZoneList<Expression*>* args = ParseArguments(CHECK_OK); |
| 4640 | 4562 |
| 4641 if (extension_ != NULL) { | 4563 if (extension_ != NULL) { |
| 4642 // The extension structures are only accessible while parsing the | 4564 // The extension structures are only accessible while parsing the |
| 4643 // very first time not when reparsing because of lazy compilation. | 4565 // very first time not when reparsing because of lazy compilation. |
| 4644 top_scope_->DeclarationScope()->ForceEagerCompilation(); | 4566 top_scope_->DeclarationScope()->ForceEagerCompilation(); |
| 4645 } | 4567 } |
| 4646 | 4568 |
| (...skipping 25 matching lines...) Expand all Loading... |
| 4672 } | 4594 } |
| 4673 | 4595 |
| 4674 // Check that the function is defined if it's an inline runtime call. | 4596 // Check that the function is defined if it's an inline runtime call. |
| 4675 if (function == NULL && name->Get(0) == '_') { | 4597 if (function == NULL && name->Get(0) == '_') { |
| 4676 ReportMessage("not_defined", Vector<Handle<String> >(&name, 1)); | 4598 ReportMessage("not_defined", Vector<Handle<String> >(&name, 1)); |
| 4677 *ok = false; | 4599 *ok = false; |
| 4678 return NULL; | 4600 return NULL; |
| 4679 } | 4601 } |
| 4680 | 4602 |
| 4681 // We have a valid intrinsics call or a call to a builtin. | 4603 // We have a valid intrinsics call or a call to a builtin. |
| 4682 return factory()->NewCallRuntime(name, function, args); | 4604 return factory()->NewCallRuntime(name, function, args, pos); |
| 4683 } | 4605 } |
| 4684 | 4606 |
| 4685 | 4607 |
| 4686 bool Parser::peek_any_identifier() { | 4608 bool ParserBase::peek_any_identifier() { |
| 4687 Token::Value next = peek(); | 4609 Token::Value next = peek(); |
| 4688 return next == Token::IDENTIFIER || | 4610 return next == Token::IDENTIFIER || |
| 4689 next == Token::FUTURE_RESERVED_WORD || | 4611 next == Token::FUTURE_RESERVED_WORD || |
| 4690 next == Token::FUTURE_STRICT_RESERVED_WORD || | 4612 next == Token::FUTURE_STRICT_RESERVED_WORD || |
| 4691 next == Token::YIELD; | 4613 next == Token::YIELD; |
| 4692 } | 4614 } |
| 4693 | 4615 |
| 4694 | 4616 |
| 4695 void Parser::Consume(Token::Value token) { | 4617 bool ParserBase::CheckContextualKeyword(Vector<const char> keyword) { |
| 4696 Token::Value next = Next(); | |
| 4697 USE(next); | |
| 4698 USE(token); | |
| 4699 ASSERT(next == token); | |
| 4700 } | |
| 4701 | |
| 4702 | |
| 4703 void Parser::Expect(Token::Value token, bool* ok) { | |
| 4704 Token::Value next = Next(); | |
| 4705 if (next == token) return; | |
| 4706 ReportUnexpectedToken(next); | |
| 4707 *ok = false; | |
| 4708 } | |
| 4709 | |
| 4710 | |
| 4711 bool Parser::Check(Token::Value token) { | |
| 4712 Token::Value next = peek(); | |
| 4713 if (next == token) { | |
| 4714 Consume(next); | |
| 4715 return true; | |
| 4716 } | |
| 4717 return false; | |
| 4718 } | |
| 4719 | |
| 4720 | |
| 4721 bool Parser::CheckContextualKeyword(Vector<const char> keyword) { | |
| 4722 if (peek() == Token::IDENTIFIER && | 4618 if (peek() == Token::IDENTIFIER && |
| 4723 scanner().is_next_contextual_keyword(keyword)) { | 4619 scanner()->is_next_contextual_keyword(keyword)) { |
| 4724 Consume(Token::IDENTIFIER); | 4620 Consume(Token::IDENTIFIER); |
| 4725 return true; | 4621 return true; |
| 4726 } | 4622 } |
| 4727 return false; | 4623 return false; |
| 4728 } | 4624 } |
| 4729 | 4625 |
| 4730 | 4626 |
| 4731 void Parser::ExpectSemicolon(bool* ok) { | 4627 void ParserBase::ExpectSemicolon(bool* ok) { |
| 4732 // Check for automatic semicolon insertion according to | 4628 // Check for automatic semicolon insertion according to |
| 4733 // the rules given in ECMA-262, section 7.9, page 21. | 4629 // the rules given in ECMA-262, section 7.9, page 21. |
| 4734 Token::Value tok = peek(); | 4630 Token::Value tok = peek(); |
| 4735 if (tok == Token::SEMICOLON) { | 4631 if (tok == Token::SEMICOLON) { |
| 4736 Next(); | 4632 Next(); |
| 4737 return; | 4633 return; |
| 4738 } | 4634 } |
| 4739 if (scanner().HasAnyLineTerminatorBeforeNext() || | 4635 if (scanner()->HasAnyLineTerminatorBeforeNext() || |
| 4740 tok == Token::RBRACE || | 4636 tok == Token::RBRACE || |
| 4741 tok == Token::EOS) { | 4637 tok == Token::EOS) { |
| 4742 return; | 4638 return; |
| 4743 } | 4639 } |
| 4744 Expect(Token::SEMICOLON, ok); | 4640 Expect(Token::SEMICOLON, ok); |
| 4745 } | 4641 } |
| 4746 | 4642 |
| 4747 | 4643 |
| 4748 void Parser::ExpectContextualKeyword(Vector<const char> keyword, bool* ok) { | 4644 void ParserBase::ExpectContextualKeyword(Vector<const char> keyword, bool* ok) { |
| 4749 Expect(Token::IDENTIFIER, ok); | 4645 Expect(Token::IDENTIFIER, ok); |
| 4750 if (!*ok) return; | 4646 if (!*ok) return; |
| 4751 if (!scanner().is_literal_contextual_keyword(keyword)) { | 4647 if (!scanner()->is_literal_contextual_keyword(keyword)) { |
| 4648 ReportUnexpectedToken(scanner()->current_token()); |
| 4752 *ok = false; | 4649 *ok = false; |
| 4753 ReportUnexpectedToken(scanner().current_token()); | |
| 4754 } | 4650 } |
| 4755 } | 4651 } |
| 4756 | 4652 |
| 4757 | 4653 |
| 4758 Literal* Parser::GetLiteralUndefined() { | 4654 Literal* Parser::GetLiteralUndefined(int position) { |
| 4759 return factory()->NewLiteral(isolate()->factory()->undefined_value()); | 4655 return factory()->NewLiteral( |
| 4656 isolate()->factory()->undefined_value(), position); |
| 4760 } | 4657 } |
| 4761 | 4658 |
| 4762 | 4659 |
| 4763 Literal* Parser::GetLiteralTheHole() { | 4660 Literal* Parser::GetLiteralTheHole(int position) { |
| 4764 return factory()->NewLiteral(isolate()->factory()->the_hole_value()); | 4661 return factory()->NewLiteral( |
| 4662 isolate()->factory()->the_hole_value(), RelocInfo::kNoPosition); |
| 4765 } | 4663 } |
| 4766 | 4664 |
| 4767 | 4665 |
| 4768 // Parses an identifier that is valid for the current scope, in particular it | 4666 // Parses an identifier that is valid for the current scope, in particular it |
| 4769 // fails on strict mode future reserved keywords in a strict scope. | 4667 // fails on strict mode future reserved keywords in a strict scope. |
| 4770 Handle<String> Parser::ParseIdentifier(bool* ok) { | 4668 Handle<String> Parser::ParseIdentifier(bool* ok) { |
| 4771 Token::Value next = Next(); | 4669 Token::Value next = Next(); |
| 4772 if (next == Token::IDENTIFIER || | 4670 if (next == Token::IDENTIFIER || |
| 4773 (top_scope_->is_classic_mode() && | 4671 (top_scope_->is_classic_mode() && |
| 4774 (next == Token::FUTURE_STRICT_RESERVED_WORD || | 4672 (next == Token::FUTURE_STRICT_RESERVED_WORD || |
| (...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4836 | 4734 |
| 4837 if (lhs != NULL && !lhs->is_this() && IsEvalOrArguments(lhs->name())) { | 4735 if (lhs != NULL && !lhs->is_this() && IsEvalOrArguments(lhs->name())) { |
| 4838 ReportMessage(error, Vector<const char*>::empty()); | 4736 ReportMessage(error, Vector<const char*>::empty()); |
| 4839 *ok = false; | 4737 *ok = false; |
| 4840 } | 4738 } |
| 4841 } | 4739 } |
| 4842 | 4740 |
| 4843 | 4741 |
| 4844 // Checks whether an octal literal was last seen between beg_pos and end_pos. | 4742 // Checks whether an octal literal was last seen between beg_pos and end_pos. |
| 4845 // If so, reports an error. Only called for strict mode. | 4743 // If so, reports an error. Only called for strict mode. |
| 4846 void Parser::CheckOctalLiteral(int beg_pos, int end_pos, bool* ok) { | 4744 void ParserBase::CheckOctalLiteral(int beg_pos, int end_pos, bool* ok) { |
| 4847 Scanner::Location octal = scanner().octal_position(); | 4745 Scanner::Location octal = scanner()->octal_position(); |
| 4848 if (octal.IsValid() && | 4746 if (octal.IsValid() && beg_pos <= octal.beg_pos && octal.end_pos <= end_pos) { |
| 4849 beg_pos <= octal.beg_pos && | 4747 ReportMessageAt(octal, "strict_octal_literal"); |
| 4850 octal.end_pos <= end_pos) { | 4748 scanner()->clear_octal_position(); |
| 4851 ReportMessageAt(octal, "strict_octal_literal", | |
| 4852 Vector<const char*>::empty()); | |
| 4853 scanner().clear_octal_position(); | |
| 4854 *ok = false; | 4749 *ok = false; |
| 4855 } | 4750 } |
| 4856 } | 4751 } |
| 4857 | 4752 |
| 4858 | 4753 |
| 4859 void Parser::CheckConflictingVarDeclarations(Scope* scope, bool* ok) { | 4754 void Parser::CheckConflictingVarDeclarations(Scope* scope, bool* ok) { |
| 4860 Declaration* decl = scope->CheckConflictingVarDeclarations(); | 4755 Declaration* decl = scope->CheckConflictingVarDeclarations(); |
| 4861 if (decl != NULL) { | 4756 if (decl != NULL) { |
| 4862 // In harmony mode we treat conflicting variable bindinds as early | 4757 // In harmony mode we treat conflicting variable bindinds as early |
| 4863 // errors. See ES5 16 for a definition of early errors. | 4758 // errors. See ES5 16 for a definition of early errors. |
| (...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4983 TENURED); | 4878 TENURED); |
| 4984 for (int i = 0; i < argc; i++) { | 4879 for (int i = 0; i < argc; i++) { |
| 4985 Handle<Object> element = arguments[i]; | 4880 Handle<Object> element = arguments[i]; |
| 4986 if (!element.is_null()) { | 4881 if (!element.is_null()) { |
| 4987 elements->set(i, *element); | 4882 elements->set(i, *element); |
| 4988 } | 4883 } |
| 4989 } | 4884 } |
| 4990 Handle<JSArray> array = isolate()->factory()->NewJSArrayWithElements( | 4885 Handle<JSArray> array = isolate()->factory()->NewJSArrayWithElements( |
| 4991 elements, FAST_ELEMENTS, TENURED); | 4886 elements, FAST_ELEMENTS, TENURED); |
| 4992 | 4887 |
| 4888 int pos = position(); |
| 4993 ZoneList<Expression*>* args = new(zone()) ZoneList<Expression*>(2, zone()); | 4889 ZoneList<Expression*>* args = new(zone()) ZoneList<Expression*>(2, zone()); |
| 4994 args->Add(factory()->NewLiteral(message), zone()); | 4890 args->Add(factory()->NewLiteral(message, pos), zone()); |
| 4995 args->Add(factory()->NewLiteral(array), zone()); | 4891 args->Add(factory()->NewLiteral(array, pos), zone()); |
| 4996 CallRuntime* call_constructor = | 4892 CallRuntime* call_constructor = |
| 4997 factory()->NewCallRuntime(constructor, NULL, args); | 4893 factory()->NewCallRuntime(constructor, NULL, args, pos); |
| 4998 return factory()->NewThrow(call_constructor, scanner().location().beg_pos); | 4894 return factory()->NewThrow(call_constructor, pos); |
| 4999 } | 4895 } |
| 5000 | 4896 |
| 5001 | 4897 |
| 5002 // ---------------------------------------------------------------------------- | 4898 // ---------------------------------------------------------------------------- |
| 5003 // Regular expressions | 4899 // Regular expressions |
| 5004 | 4900 |
| 5005 | 4901 |
| 5006 RegExpParser::RegExpParser(FlatStringReader* in, | 4902 RegExpParser::RegExpParser(FlatStringReader* in, |
| 5007 Handle<String>* error, | 4903 Handle<String>* error, |
| 5008 bool multiline, | 4904 bool multiline, |
| (...skipping 869 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5878 } | 5774 } |
| 5879 | 5775 |
| 5880 | 5776 |
| 5881 // Create a Scanner for the preparser to use as input, and preparse the source. | 5777 // Create a Scanner for the preparser to use as input, and preparse the source. |
| 5882 ScriptDataImpl* PreParserApi::PreParse(Isolate* isolate, | 5778 ScriptDataImpl* PreParserApi::PreParse(Isolate* isolate, |
| 5883 Utf16CharacterStream* source) { | 5779 Utf16CharacterStream* source) { |
| 5884 CompleteParserRecorder recorder; | 5780 CompleteParserRecorder recorder; |
| 5885 HistogramTimerScope timer(isolate->counters()->pre_parse()); | 5781 HistogramTimerScope timer(isolate->counters()->pre_parse()); |
| 5886 Scanner scanner(isolate->unicode_cache()); | 5782 Scanner scanner(isolate->unicode_cache()); |
| 5887 intptr_t stack_limit = isolate->stack_guard()->real_climit(); | 5783 intptr_t stack_limit = isolate->stack_guard()->real_climit(); |
| 5888 preparser::PreParser preparser(&scanner, &recorder, stack_limit); | 5784 PreParser preparser(&scanner, &recorder, stack_limit); |
| 5889 preparser.set_allow_lazy(true); | 5785 preparser.set_allow_lazy(true); |
| 5890 preparser.set_allow_generators(FLAG_harmony_generators); | 5786 preparser.set_allow_generators(FLAG_harmony_generators); |
| 5891 preparser.set_allow_for_of(FLAG_harmony_iteration); | 5787 preparser.set_allow_for_of(FLAG_harmony_iteration); |
| 5892 preparser.set_allow_harmony_scoping(FLAG_harmony_scoping); | 5788 preparser.set_allow_harmony_scoping(FLAG_harmony_scoping); |
| 5893 preparser.set_allow_harmony_numeric_literals(FLAG_harmony_numeric_literals); | 5789 preparser.set_allow_harmony_numeric_literals(FLAG_harmony_numeric_literals); |
| 5894 scanner.Initialize(source); | 5790 scanner.Initialize(source); |
| 5895 preparser::PreParser::PreParseResult result = preparser.PreParseProgram(); | 5791 PreParser::PreParseResult result = preparser.PreParseProgram(); |
| 5896 if (result == preparser::PreParser::kPreParseStackOverflow) { | 5792 if (result == PreParser::kPreParseStackOverflow) { |
| 5897 isolate->StackOverflow(); | 5793 isolate->StackOverflow(); |
| 5898 return NULL; | 5794 return NULL; |
| 5899 } | 5795 } |
| 5900 | 5796 |
| 5901 // Extract the accumulated data from the recorder as a single | 5797 // Extract the accumulated data from the recorder as a single |
| 5902 // contiguous vector that we are responsible for disposing. | 5798 // contiguous vector that we are responsible for disposing. |
| 5903 Vector<unsigned> store = recorder.ExtractData(); | 5799 Vector<unsigned> store = recorder.ExtractData(); |
| 5904 return new ScriptDataImpl(store); | 5800 return new ScriptDataImpl(store); |
| 5905 } | 5801 } |
| 5906 | 5802 |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5954 ASSERT(info()->isolate()->has_pending_exception()); | 5850 ASSERT(info()->isolate()->has_pending_exception()); |
| 5955 } else { | 5851 } else { |
| 5956 result = ParseProgram(); | 5852 result = ParseProgram(); |
| 5957 } | 5853 } |
| 5958 } | 5854 } |
| 5959 info()->SetFunction(result); | 5855 info()->SetFunction(result); |
| 5960 return (result != NULL); | 5856 return (result != NULL); |
| 5961 } | 5857 } |
| 5962 | 5858 |
| 5963 } } // namespace v8::internal | 5859 } } // namespace v8::internal |
| OLD | NEW |