| OLD | NEW |
| 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 #include "vm/parser.h" | 5 #include "vm/parser.h" |
| 6 | 6 |
| 7 #include "lib/invocation_mirror.h" | 7 #include "lib/invocation_mirror.h" |
| 8 #include "vm/bigint_operations.h" | 8 #include "vm/bigint_operations.h" |
| 9 #include "vm/bootstrap.h" | 9 #include "vm/bootstrap.h" |
| 10 #include "vm/class_finalizer.h" | 10 #include "vm/class_finalizer.h" |
| (...skipping 739 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 750 TimerScope timer(FLAG_compiler_stats, &CompilerStats::parser_timer); | 750 TimerScope timer(FLAG_compiler_stats, &CompilerStats::parser_timer); |
| 751 Isolate* isolate = Isolate::Current(); | 751 Isolate* isolate = Isolate::Current(); |
| 752 ASSERT(isolate->long_jump_base()->IsSafeToJump()); | 752 ASSERT(isolate->long_jump_base()->IsSafeToJump()); |
| 753 ASSERT(parsed_function != NULL); | 753 ASSERT(parsed_function != NULL); |
| 754 const Function& func = parsed_function->function(); | 754 const Function& func = parsed_function->function(); |
| 755 const Script& script = Script::Handle(isolate, func.script()); | 755 const Script& script = Script::Handle(isolate, func.script()); |
| 756 Parser parser(script, parsed_function, func.token_pos()); | 756 Parser parser(script, parsed_function, func.token_pos()); |
| 757 SequenceNode* node_sequence = NULL; | 757 SequenceNode* node_sequence = NULL; |
| 758 Array& default_parameter_values = Array::ZoneHandle(isolate, Array::null()); | 758 Array& default_parameter_values = Array::ZoneHandle(isolate, Array::null()); |
| 759 switch (func.kind()) { | 759 switch (func.kind()) { |
| 760 case RawFunction::kRegularFunction: | 760 case RawFunction::kRegularFunction: { |
| 761 } |
| 761 case RawFunction::kClosureFunction: | 762 case RawFunction::kClosureFunction: |
| 762 case RawFunction::kGetterFunction: | 763 case RawFunction::kGetterFunction: |
| 763 case RawFunction::kSetterFunction: | 764 case RawFunction::kSetterFunction: |
| 764 case RawFunction::kConstructor: | 765 case RawFunction::kConstructor: { |
| 766 const Class& owner = Class::Handle(func.Owner()); |
| 767 const String& name = String::Handle(func.name()); |
| 768 if (owner.IsSignatureClass() && name.Equals("==")) { |
| 769 node_sequence = parser.ParseClosureEqualsFunction(func); |
| 770 break; |
| 771 } |
| 772 if (owner.IsSignatureClass() && name.Equals("get:hashCode")) { |
| 773 node_sequence = parser.ParseClosureHashCodeFunction(func); |
| 774 break; |
| 775 } |
| 765 // The call to a redirecting factory is redirected. | 776 // The call to a redirecting factory is redirected. |
| 766 ASSERT(!func.IsRedirectingFactory()); | 777 ASSERT(!func.IsRedirectingFactory()); |
| 767 node_sequence = parser.ParseFunc(func, default_parameter_values); | 778 node_sequence = parser.ParseFunc(func, default_parameter_values); |
| 768 break; | 779 break; |
| 780 } |
| 769 case RawFunction::kImplicitGetter: | 781 case RawFunction::kImplicitGetter: |
| 770 ASSERT(!func.is_static()); | 782 ASSERT(!func.is_static()); |
| 771 node_sequence = parser.ParseInstanceGetter(func); | 783 node_sequence = parser.ParseInstanceGetter(func); |
| 772 break; | 784 break; |
| 773 case RawFunction::kImplicitSetter: | 785 case RawFunction::kImplicitSetter: |
| 774 ASSERT(!func.is_static()); | 786 ASSERT(!func.is_static()); |
| 775 node_sequence = parser.ParseInstanceSetter(func); | 787 node_sequence = parser.ParseInstanceSetter(func); |
| 776 break; | 788 break; |
| 777 case RawFunction::kImplicitStaticFinalGetter: | 789 case RawFunction::kImplicitStaticFinalGetter: |
| 778 node_sequence = parser.ParseStaticFinalGetter(func); | 790 node_sequence = parser.ParseStaticFinalGetter(func); |
| (...skipping 331 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1110 Function::ZoneHandle(func.extracted_method_closure()), | 1122 Function::ZoneHandle(func.extracted_method_closure()), |
| 1111 load_receiver, | 1123 load_receiver, |
| 1112 NULL); | 1124 NULL); |
| 1113 | 1125 |
| 1114 ReturnNode* return_node = new ReturnNode(ident_pos, closure); | 1126 ReturnNode* return_node = new ReturnNode(ident_pos, closure); |
| 1115 current_block_->statements->Add(return_node); | 1127 current_block_->statements->Add(return_node); |
| 1116 return CloseBlock(); | 1128 return CloseBlock(); |
| 1117 } | 1129 } |
| 1118 | 1130 |
| 1119 | 1131 |
| 1132 static const String& PrivateCoreLibName(const String& str) { |
| 1133 const Library& core_lib = Library::Handle(Library::CoreLibrary()); |
| 1134 const String& private_name = String::ZoneHandle(core_lib.PrivateName(str)); |
| 1135 return private_name; |
| 1136 } |
| 1137 |
| 1138 |
| 1139 SequenceNode* Parser::ParseClosureEqualsFunction(const Function& func) { |
| 1140 TRACE_PARSER("ParseClosureEqualsFunction"); |
| 1141 ParamList params; |
| 1142 |
| 1143 const intptr_t token_pos = func.token_pos(); |
| 1144 ASSERT(func.token_pos() == 0); |
| 1145 ASSERT(current_class().raw() == func.Owner()); |
| 1146 params.AddReceiver(ReceiverType(), token_pos); |
| 1147 params.AddFinalParameter( |
| 1148 token_pos, |
| 1149 &String::ZoneHandle(Symbols::New("other")), |
| 1150 &Type::ZoneHandle(Type::DynamicType())); |
| 1151 ASSERT(func.num_fixed_parameters() == 2); // Receiver, other. |
| 1152 ASSERT(!func.HasOptionalParameters()); |
| 1153 |
| 1154 // Build local scope for function and populate with the formal parameters. |
| 1155 OpenFunctionBlock(func); |
| 1156 AddFormalParamsToScope(¶ms, current_block_->scope); |
| 1157 |
| 1158 // Receiver is local 0. |
| 1159 LocalVariable* receiver = current_block_->scope->VariableAt(0); |
| 1160 LoadLocalNode* load_receiver = new LoadLocalNode(token_pos, receiver); |
| 1161 |
| 1162 // Other is local 1. |
| 1163 LocalVariable* other = current_block_->scope->VariableAt(1); |
| 1164 LoadLocalNode* load_other = new LoadLocalNode(token_pos, other); |
| 1165 |
| 1166 ArgumentListNode* arguments = new ArgumentListNode(token_pos); |
| 1167 arguments->Add(load_receiver); |
| 1168 arguments->Add(load_other); |
| 1169 |
| 1170 const Function& compare_func = Function::ZoneHandle(Resolver::ResolveStatic( |
| 1171 Library::Handle(Library::CoreLibrary()), |
| 1172 String::Handle(), |
| 1173 PrivateCoreLibName(Symbols::ClosureCompareFunction()), |
| 1174 arguments->length(), |
| 1175 arguments->names(), |
| 1176 Resolver::kIsQualified, |
| 1177 NULL)); |
| 1178 ASSERT(!compare_func.IsNull()); |
| 1179 |
| 1180 StaticCallNode* call = new StaticCallNode(token_pos, compare_func, arguments); |
| 1181 |
| 1182 ReturnNode* return_node = new ReturnNode(token_pos, call); |
| 1183 current_block_->statements->Add(return_node); |
| 1184 return CloseBlock(); |
| 1185 } |
| 1186 |
| 1187 |
| 1188 SequenceNode* Parser::ParseClosureHashCodeFunction(const Function& func) { |
| 1189 TRACE_PARSER("ParseClosureHashCodeFunction"); |
| 1190 ParamList params; |
| 1191 |
| 1192 const intptr_t token_pos = func.token_pos(); |
| 1193 ASSERT(func.token_pos() == 0); |
| 1194 ASSERT(current_class().raw() == func.Owner()); |
| 1195 params.AddReceiver(ReceiverType(), token_pos); |
| 1196 ASSERT(func.num_fixed_parameters() == 1); // Receiver, other. |
| 1197 ASSERT(!func.HasOptionalParameters()); |
| 1198 |
| 1199 // Build local scope for function and populate with the formal parameters. |
| 1200 OpenFunctionBlock(func); |
| 1201 AddFormalParamsToScope(¶ms, current_block_->scope); |
| 1202 |
| 1203 // Receiver is local 0. |
| 1204 LocalVariable* receiver = current_block_->scope->VariableAt(0); |
| 1205 LoadLocalNode* load_receiver = new LoadLocalNode(token_pos, receiver); |
| 1206 |
| 1207 ArgumentListNode* arguments = new ArgumentListNode(token_pos); |
| 1208 arguments->Add(load_receiver); |
| 1209 |
| 1210 const Function& hash_code_func = Function::ZoneHandle(Resolver::ResolveStatic( |
| 1211 Library::Handle(Library::CoreLibrary()), |
| 1212 String::Handle(), |
| 1213 PrivateCoreLibName(Symbols::ClosureHashCodeFunction()), |
| 1214 arguments->length(), |
| 1215 arguments->names(), |
| 1216 Resolver::kIsQualified, |
| 1217 NULL)); |
| 1218 ASSERT(!hash_code_func.IsNull()); |
| 1219 |
| 1220 StaticCallNode* call = |
| 1221 new StaticCallNode(token_pos, hash_code_func, arguments); |
| 1222 |
| 1223 ReturnNode* return_node = new ReturnNode(token_pos, call); |
| 1224 current_block_->statements->Add(return_node); |
| 1225 return CloseBlock(); |
| 1226 } |
| 1227 |
| 1228 |
| 1120 void Parser::BuildDispatcherScope(const Function& func, | 1229 void Parser::BuildDispatcherScope(const Function& func, |
| 1121 const ArgumentsDescriptor& desc, | 1230 const ArgumentsDescriptor& desc, |
| 1122 Array& default_values) { | 1231 Array& default_values) { |
| 1123 ParamList params; | 1232 ParamList params; |
| 1124 // Receiver first. | 1233 // Receiver first. |
| 1125 intptr_t token_pos = func.token_pos(); | 1234 intptr_t token_pos = func.token_pos(); |
| 1126 params.AddReceiver(ReceiverType(), token_pos); | 1235 params.AddReceiver(ReceiverType(), token_pos); |
| 1127 // Remaining positional parameters. | 1236 // Remaining positional parameters. |
| 1128 intptr_t i = 1; | 1237 intptr_t i = 1; |
| 1129 for (; i < desc.PositionalCount(); ++i) { | 1238 for (; i < desc.PositionalCount(); ++i) { |
| (...skipping 478 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1608 String& name = String::Handle(class_name.raw()); | 1717 String& name = String::Handle(class_name.raw()); |
| 1609 if (class_name.CharAt(0) == Scanner::kPrivateIdentifierStart) { | 1718 if (class_name.CharAt(0) == Scanner::kPrivateIdentifierStart) { |
| 1610 // Private identifiers are mangled on a per script basis. | 1719 // Private identifiers are mangled on a per script basis. |
| 1611 name = String::Concat(name, String::Handle(core_lib.private_key())); | 1720 name = String::Concat(name, String::Handle(core_lib.private_key())); |
| 1612 name = Symbols::New(name); | 1721 name = Symbols::New(name); |
| 1613 } | 1722 } |
| 1614 return core_lib.LookupClass(name, NULL); // No ambiguity error expected. | 1723 return core_lib.LookupClass(name, NULL); // No ambiguity error expected. |
| 1615 } | 1724 } |
| 1616 | 1725 |
| 1617 | 1726 |
| 1618 static const String& PrivateCoreLibName(const String& str) { | |
| 1619 const Library& core_lib = Library::Handle(Library::CoreLibrary()); | |
| 1620 const String& private_name = String::ZoneHandle(core_lib.PrivateName(str)); | |
| 1621 return private_name; | |
| 1622 } | |
| 1623 | |
| 1624 | |
| 1625 StaticCallNode* Parser::BuildInvocationMirrorAllocation( | 1727 StaticCallNode* Parser::BuildInvocationMirrorAllocation( |
| 1626 intptr_t call_pos, | 1728 intptr_t call_pos, |
| 1627 const String& function_name, | 1729 const String& function_name, |
| 1628 const ArgumentListNode& function_args, | 1730 const ArgumentListNode& function_args, |
| 1629 const LocalVariable* temp_for_last_arg) { | 1731 const LocalVariable* temp_for_last_arg) { |
| 1630 const intptr_t args_pos = function_args.token_pos(); | 1732 const intptr_t args_pos = function_args.token_pos(); |
| 1631 // Build arguments to the call to the static | 1733 // Build arguments to the call to the static |
| 1632 // InvocationMirror._allocateInvocationMirror method. | 1734 // InvocationMirror._allocateInvocationMirror method. |
| 1633 ArgumentListNode* arguments = new ArgumentListNode(args_pos); | 1735 ArgumentListNode* arguments = new ArgumentListNode(args_pos); |
| 1634 // The first argument is the original function name. | 1736 // The first argument is the original function name. |
| (...skipping 8656 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 10291 void Parser::SkipQualIdent() { | 10393 void Parser::SkipQualIdent() { |
| 10292 ASSERT(IsIdentifier()); | 10394 ASSERT(IsIdentifier()); |
| 10293 ConsumeToken(); | 10395 ConsumeToken(); |
| 10294 if (CurrentToken() == Token::kPERIOD) { | 10396 if (CurrentToken() == Token::kPERIOD) { |
| 10295 ConsumeToken(); // Consume the kPERIOD token. | 10397 ConsumeToken(); // Consume the kPERIOD token. |
| 10296 ExpectIdentifier("identifier expected after '.'"); | 10398 ExpectIdentifier("identifier expected after '.'"); |
| 10297 } | 10399 } |
| 10298 } | 10400 } |
| 10299 | 10401 |
| 10300 } // namespace dart | 10402 } // namespace dart |
| OLD | NEW |