Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(158)

Side by Side Diff: runtime/vm/parser.cc

Issue 22425006: Fix equality of implicit closures in the Dart VM. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 7 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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
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
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(&params, 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(&params, 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
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
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
OLDNEW
« runtime/vm/object.cc ('K') | « runtime/vm/parser.h ('k') | runtime/vm/symbols.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698