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

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

Issue 12210127: First stab at mixins in VM compiler (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 7 years, 10 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
« no previous file with comments | « runtime/vm/class_finalizer.h ('k') | runtime/vm/object.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2013, 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/class_finalizer.h" 5 #include "vm/class_finalizer.h"
6 6
7 #include "vm/flags.h" 7 #include "vm/flags.h"
8 #include "vm/heap.h" 8 #include "vm/heap.h"
9 #include "vm/isolate.h" 9 #include "vm/isolate.h"
10 #include "vm/longjump.h" 10 #include "vm/longjump.h"
(...skipping 1080 matching lines...) Expand 10 before | Expand all | Expand 10 after
1091 function_name.ToCString(), 1091 function_name.ToCString(),
1092 class_name.ToCString(), 1092 class_name.ToCString(),
1093 function_name.ToCString(), 1093 function_name.ToCString(),
1094 super_class_name.ToCString()); 1094 super_class_name.ToCString());
1095 } 1095 }
1096 } 1096 }
1097 } 1097 }
1098 } 1098 }
1099 1099
1100 1100
1101 void ClassFinalizer::ApplyMixin(const Class& cls) {
1102 const Type& mixin_type = Type::Handle(cls.mixin());
1103 ASSERT(!mixin_type.IsNull());
1104 ASSERT(mixin_type.HasResolvedTypeClass());
1105 const Class& mixin_cls = Class::Handle(mixin_type.type_class());
1106
1107 if (FLAG_trace_class_finalization) {
1108 OS::Print("Applying mixin '%s' to '%s'\n",
1109 String::Handle(mixin_cls.Name()).ToCString(),
1110 cls.ToCString());
1111 }
1112
1113 // Check that the super class of the mixin class is extending
1114 // class Object.
1115 const Type& mixin_super_type = Type::Handle(mixin_cls.super_type());
1116 if (!mixin_super_type.IsObjectType()) {
1117 const Script& script = Script::Handle(cls.script());
1118 const String& class_name = String::Handle(mixin_cls.Name());
1119 ReportError(script, cls.token_pos(),
1120 "mixin class %s must extend class Object",
1121 class_name.ToCString());
1122 }
1123
1124 const Array& functions = Array::Handle(mixin_cls.functions());
1125 Function& func = Function::Handle();
1126 const intptr_t num_functions = functions.Length();
1127 for (int i = 0; i < num_functions; i++) {
1128 func ^= functions.At(i);
1129 if (func.IsConstructor()) {
1130 // A mixin class must not have explicit constructors.
1131 if (!func.IsImplicitConstructor()) {
1132 const Script& script = Script::Handle(cls.script());
1133 ReportError(script, cls.token_pos(),
1134 "mixin class %s must not have constructors\n",
1135 String::Handle(mixin_cls.Name()).ToCString());
1136 }
1137 continue; // Skip the implicit constructor.
1138 }
1139 if (!func.is_static()) {
1140 func = func.Clone(cls);
1141 cls.AddFunction(func);
1142 }
1143 }
1144 Array& fields = Array::Handle(mixin_cls.fields());
1145 Field& field = Field::Handle();
1146 const GrowableObjectArray& cloned_fields =
1147 GrowableObjectArray::Handle(GrowableObjectArray::New());
1148 const intptr_t num_fields = fields.Length();
1149 for (int i = 0; i < num_fields; i++) {
1150 field ^= fields.At(i);
1151 if (!field.is_static()) {
1152 field = field.Clone(cls);
1153 cloned_fields.Add(field);
1154 }
1155 }
1156 fields = Array::MakeArray(cloned_fields);
1157 ASSERT(Array::Handle(cls.fields()).Length() == 0);
1158 cls.SetFields(fields);
1159 }
1160
1161
1101 void ClassFinalizer::FinalizeClass(const Class& cls) { 1162 void ClassFinalizer::FinalizeClass(const Class& cls) {
1102 if (cls.is_finalized()) { 1163 if (cls.is_finalized()) {
1103 return; 1164 return;
1104 } 1165 }
1105 if (FLAG_trace_class_finalization) { 1166 if (FLAG_trace_class_finalization) {
1106 OS::Print("Finalize %s\n", cls.ToCString()); 1167 OS::Print("Finalize %s\n", cls.ToCString());
1107 } 1168 }
1108 if (!IsSuperCycleFree(cls)) { 1169 if (!IsSuperCycleFree(cls)) {
1109 const String& name = String::Handle(cls.Name()); 1170 const String& name = String::Handle(cls.Name());
1110 const Script& script = Script::Handle(cls.script()); 1171 const Script& script = Script::Handle(cls.script());
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
1143 // Resolve and finalize the result and parameter types of the signature 1204 // Resolve and finalize the result and parameter types of the signature
1144 // function of this signature class. 1205 // function of this signature class.
1145 const Function& sig_function = Function::Handle(cls.signature_function()); 1206 const Function& sig_function = Function::Handle(cls.signature_function());
1146 ResolveAndFinalizeSignature(cls, sig_function); 1207 ResolveAndFinalizeSignature(cls, sig_function);
1147 1208
1148 // Resolve and finalize the signature type of this signature class. 1209 // Resolve and finalize the signature type of this signature class.
1149 const Type& sig_type = Type::Handle(cls.SignatureType()); 1210 const Type& sig_type = Type::Handle(cls.SignatureType());
1150 FinalizeType(cls, sig_type, kCanonicalizeWellFormed); 1211 FinalizeType(cls, sig_type, kCanonicalizeWellFormed);
1151 return; 1212 return;
1152 } 1213 }
1214 if (cls.mixin() != Type::null()) {
1215 // Copy instance methods and fields from the mixin class.
1216 // This has to happen before the check whether the methods of
1217 // the class conflict with inherited methods.
1218 ApplyMixin(cls);
1219 }
1153 // Finalize interface types (but not necessarily interface classes). 1220 // Finalize interface types (but not necessarily interface classes).
1154 Array& interface_types = Array::Handle(cls.interfaces()); 1221 Array& interface_types = Array::Handle(cls.interfaces());
1155 AbstractType& interface_type = AbstractType::Handle(); 1222 AbstractType& interface_type = AbstractType::Handle();
1156 for (intptr_t i = 0; i < interface_types.Length(); i++) { 1223 for (intptr_t i = 0; i < interface_types.Length(); i++) {
1157 interface_type ^= interface_types.At(i); 1224 interface_type ^= interface_types.At(i);
1158 interface_type = FinalizeType(cls, interface_type, kCanonicalizeWellFormed); 1225 interface_type = FinalizeType(cls, interface_type, kCanonicalizeWellFormed);
1159 interface_types.SetAt(i, interface_type); 1226 interface_types.SetAt(i, interface_type);
1160 } 1227 }
1161 // Mark as finalized before resolving type parameter upper bounds and member 1228 // Mark as finalized before resolving type parameter upper bounds and member
1162 // types in order to break cycles. 1229 // types in order to break cycles.
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after
1260 if ((*visited)[i] == cls_index) { 1327 if ((*visited)[i] == cls_index) {
1261 // We have already visited class 'cls'. We found a cycle. 1328 // We have already visited class 'cls'. We found a cycle.
1262 const String& class_name = String::Handle(cls.Name()); 1329 const String& class_name = String::Handle(cls.Name());
1263 const Script& script = Script::Handle(cls.script()); 1330 const Script& script = Script::Handle(cls.script());
1264 ReportError(script, cls.token_pos(), 1331 ReportError(script, cls.token_pos(),
1265 "cyclic reference found for class '%s'", 1332 "cyclic reference found for class '%s'",
1266 class_name.ToCString()); 1333 class_name.ToCString());
1267 } 1334 }
1268 } 1335 }
1269 1336
1270 // If the class/interface has no explicit super class/interfaces, we are done. 1337 // If the class/interface has no explicit super class/interfaces
1338 // and is not a mixin application, we are done.
1271 Type& super_type = Type::Handle(cls.super_type()); 1339 Type& super_type = Type::Handle(cls.super_type());
1340 Type& mixin_type = Type::Handle(cls.mixin());
1272 Array& super_interfaces = Array::Handle(cls.interfaces()); 1341 Array& super_interfaces = Array::Handle(cls.interfaces());
1273 if ((super_type.IsNull() || super_type.IsObjectType()) && 1342 if ((super_type.IsNull() || super_type.IsObjectType()) &&
1274 (super_interfaces.Length() == 0)) { 1343 (super_interfaces.Length() == 0) &&
1344 (mixin_type.IsNull())) {
1275 return; 1345 return;
1276 } 1346 }
1277 1347
1278 // If cls belongs to core lib or to core lib's implementation, restrictions 1348 if (!mixin_type.IsNull()) {
1279 // about allowed interfaces are lifted. 1349 ResolveType(cls, mixin_type, kCanonicalizeWellFormed);
1350 }
1351
1352 // If cls belongs to core lib, restrictions about allowed interfaces
1353 // are lifted.
1280 const bool cls_belongs_to_core_lib = cls.library() == Library::CoreLibrary(); 1354 const bool cls_belongs_to_core_lib = cls.library() == Library::CoreLibrary();
1281 1355
1282 // Resolve and check the super type and interfaces of cls. 1356 // Resolve and check the super type and interfaces of cls.
1283 visited->Add(cls_index); 1357 visited->Add(cls_index);
1284 AbstractType& interface = AbstractType::Handle(); 1358 AbstractType& interface = AbstractType::Handle();
1285 Class& interface_class = Class::Handle(); 1359 Class& interface_class = Class::Handle();
1286 1360
1287 // Resolve super type. Failures lead to a longjmp. 1361 // Resolve super type. Failures lead to a longjmp.
1288 ResolveType(cls, super_type, kCanonicalizeWellFormed); 1362 ResolveType(cls, super_type, kCanonicalizeWellFormed);
1289 1363
1290 // If cls belongs to core lib or to core lib's implementation, restrictions
1291 interface_class = super_type.type_class(); 1364 interface_class = super_type.type_class();
1292 // If cls belongs to core lib or to core lib's implementation, restrictions 1365 // If cls belongs to core lib or to core lib's implementation, restrictions
1293 // about allowed interfaces are lifted. 1366 // about allowed interfaces are lifted.
1294 if (!cls_belongs_to_core_lib) { 1367 if (!cls_belongs_to_core_lib) {
1295 // Prevent extending core implementation classes. 1368 // Prevent extending core implementation classes.
1296 bool is_error = false; 1369 bool is_error = false;
1297 switch (interface_class.id()) { 1370 switch (interface_class.id()) {
1298 case kNumberCid: 1371 case kNumberCid:
1299 case kIntegerCid: // Class Integer, not int. 1372 case kIntegerCid: // Class Integer, not int.
1300 case kSmiCid: 1373 case kSmiCid:
(...skipping 281 matching lines...) Expand 10 before | Expand all | Expand 10 after
1582 void ClassFinalizer::ReportError(const char* format, ...) { 1655 void ClassFinalizer::ReportError(const char* format, ...) {
1583 va_list args; 1656 va_list args;
1584 va_start(args, format); 1657 va_start(args, format);
1585 const Error& error = Error::Handle( 1658 const Error& error = Error::Handle(
1586 Parser::FormatError(Script::Handle(), -1, "Error", format, args)); 1659 Parser::FormatError(Script::Handle(), -1, "Error", format, args));
1587 va_end(args); 1660 va_end(args);
1588 ReportError(error); 1661 ReportError(error);
1589 } 1662 }
1590 1663
1591 } // namespace dart 1664 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/class_finalizer.h ('k') | runtime/vm/object.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698