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

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
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 1227 matching lines...) Expand 10 before | Expand all | Expand 10 after
1238 !IsAliasCycleFree(type_class, visited)) { 1238 !IsAliasCycleFree(type_class, visited)) {
1239 return false; 1239 return false;
1240 } 1240 }
1241 } 1241 }
1242 } 1242 }
1243 visited->RemoveLast(); 1243 visited->RemoveLast();
1244 return true; 1244 return true;
1245 } 1245 }
1246 1246
1247 1247
1248 void ClassFinalizer::ApplyMixin(const Class& cls, const Type& mixin) {
1249 ASSERT(mixin.HasResolvedTypeClass());
1250 const Class& mixin_cls = Class::Handle(mixin.type_class());
1251
1252 // Check that the super class of the mixin class is extending
1253 // class Object.
1254 const Type& mixin_super_type = Type::Handle(mixin_cls.super_type());
1255 ResolveType(mixin_cls, mixin_super_type, kCanonicalizeWellFormed);
1256 if (!mixin_super_type.IsObjectType()) {
1257 const Script& script = Script::Handle(cls.script());
1258 const String& class_name = String::Handle(mixin_cls.Name());
1259 ReportError(script, cls.token_pos(),
siva 2013/02/13 01:34:37 I am wondering if it would be more helpful if you
hausner 2013/02/13 19:58:14 I thought it makes more sense to report it where t
1260 "mixin class %s must extend class Object",
1261 class_name.ToCString());
1262 }
1263
1264 const Array& functions = Array::Handle(mixin_cls.functions());
1265 Function& func = Function::Handle();
1266 const intptr_t num_functions = functions.Length();
1267 for (int i = 0; i < num_functions; i++) {
1268 func ^= functions.At(i);
1269 if (func.IsConstructor()) {
1270 // A mixin class must not have explicit constructors.
1271 if (!func.IsImplicitConstructor()) {
1272 const Script& script = Script::Handle(cls.script());
1273 ReportError(script, cls.token_pos(),
siva 2013/02/13 01:34:37 Ditto.
hausner 2013/02/13 19:58:14 Ditto.
1274 "mixin class %s must not have constructors\n",
1275 String::Handle(mixin_cls.Name()).ToCString());
1276 }
1277 continue; // Skip the implicit constructor.
1278 }
1279 // TODO(hausner): must check whether the function contains
1280 // super calls. If so, report error.
1281 if (!func.is_static()) {
1282 func = func.Clone(cls);
1283 cls.AddFunction(func);
siva 2013/02/13 01:34:37 Our AddFunction implementation is very inefficient
hausner 2013/02/13 19:58:14 I agree with what you suggest, but let me check it
1284 }
1285 }
1286 Array& fields = Array::Handle(mixin_cls.fields());
1287 Field& field = Field::Handle();
1288 const GrowableObjectArray& cloned_fields =
1289 GrowableObjectArray::Handle(GrowableObjectArray::New());
1290 const intptr_t num_fields = fields.Length();
1291 for (int i = 0; i < num_fields; i++) {
1292 field ^= fields.At(i);
1293 if (!field.is_static()) {
1294 field = field.Clone(cls);
1295 cloned_fields.Add(field);
1296 }
1297 }
1298 fields = Array::MakeArray(cloned_fields);
siva 2013/02/13 01:34:37 Maybe we should assert here that ASSERT(cls.fields
hausner 2013/02/13 19:58:14 Done.
1299 cls.SetFields(fields);
1300 }
1301
1302
1248 // Recursively walks the graph of explicitly declared super type and 1303 // Recursively walks the graph of explicitly declared super type and
1249 // interfaces, resolving unresolved super types and interfaces. 1304 // interfaces, resolving unresolved super types and interfaces.
1250 // Reports an error if there is an interface reference that cannot be 1305 // Reports an error if there is an interface reference that cannot be
1251 // resolved, or if there is a cycle in the graph. We detect cycles by 1306 // resolved, or if there is a cycle in the graph. We detect cycles by
1252 // remembering interfaces we've visited in each path through the 1307 // remembering interfaces we've visited in each path through the
1253 // graph. If we visit an interface a second time on a given path, 1308 // graph. If we visit an interface a second time on a given path,
1254 // we found a loop. 1309 // we found a loop.
1255 void ClassFinalizer::ResolveSuperTypeAndInterfaces( 1310 void ClassFinalizer::ResolveSuperTypeAndInterfaces(
1256 const Class& cls, GrowableArray<intptr_t>* visited) { 1311 const Class& cls, GrowableArray<intptr_t>* visited) {
1257 ASSERT(visited != NULL); 1312 ASSERT(visited != NULL);
1258 const intptr_t cls_index = cls.id(); 1313 const intptr_t cls_index = cls.id();
1259 for (int i = 0; i < visited->length(); i++) { 1314 for (int i = 0; i < visited->length(); i++) {
1260 if ((*visited)[i] == cls_index) { 1315 if ((*visited)[i] == cls_index) {
1261 // We have already visited class 'cls'. We found a cycle. 1316 // We have already visited class 'cls'. We found a cycle.
1262 const String& class_name = String::Handle(cls.Name()); 1317 const String& class_name = String::Handle(cls.Name());
1263 const Script& script = Script::Handle(cls.script()); 1318 const Script& script = Script::Handle(cls.script());
1264 ReportError(script, cls.token_pos(), 1319 ReportError(script, cls.token_pos(),
1265 "cyclic reference found for class '%s'", 1320 "cyclic reference found for class '%s'",
1266 class_name.ToCString()); 1321 class_name.ToCString());
1267 } 1322 }
1268 } 1323 }
1269 1324
1270 // If the class/interface has no explicit super class/interfaces, we are done. 1325 // If the class/interface has no explicit super class/interfaces
1326 // and is not a mixin application, we are done.
1271 Type& super_type = Type::Handle(cls.super_type()); 1327 Type& super_type = Type::Handle(cls.super_type());
1328 Type& mixin_type = Type::Handle(cls.mixin());
1272 Array& super_interfaces = Array::Handle(cls.interfaces()); 1329 Array& super_interfaces = Array::Handle(cls.interfaces());
1273 if ((super_type.IsNull() || super_type.IsObjectType()) && 1330 if ((super_type.IsNull() || super_type.IsObjectType()) &&
1274 (super_interfaces.Length() == 0)) { 1331 (super_interfaces.Length() == 0) &&
1332 (mixin_type.IsNull())) {
1275 return; 1333 return;
1276 } 1334 }
1277 1335
1278 // If cls belongs to core lib or to core lib's implementation, restrictions 1336 if (!mixin_type.IsNull()) {
1279 // about allowed interfaces are lifted. 1337 ResolveType(cls, mixin_type, kCanonicalizeWellFormed);
1338 ApplyMixin(cls, mixin_type);
1339 }
1340
1341 // If cls belongs to core lib, restrictions about allowed interfaces
1342 // are lifted.
1280 const bool cls_belongs_to_core_lib = cls.library() == Library::CoreLibrary(); 1343 const bool cls_belongs_to_core_lib = cls.library() == Library::CoreLibrary();
1281 1344
1282 // Resolve and check the super type and interfaces of cls. 1345 // Resolve and check the super type and interfaces of cls.
1283 visited->Add(cls_index); 1346 visited->Add(cls_index);
1284 AbstractType& interface = AbstractType::Handle(); 1347 AbstractType& interface = AbstractType::Handle();
1285 Class& interface_class = Class::Handle(); 1348 Class& interface_class = Class::Handle();
1286 1349
1287 // Resolve super type. Failures lead to a longjmp. 1350 // Resolve super type. Failures lead to a longjmp.
1288 ResolveType(cls, super_type, kCanonicalizeWellFormed); 1351 ResolveType(cls, super_type, kCanonicalizeWellFormed);
1289 1352
1290 // If cls belongs to core lib or to core lib's implementation, restrictions
1291 interface_class = super_type.type_class(); 1353 interface_class = super_type.type_class();
1292 // If cls belongs to core lib or to core lib's implementation, restrictions 1354 // If cls belongs to core lib or to core lib's implementation, restrictions
1293 // about allowed interfaces are lifted. 1355 // about allowed interfaces are lifted.
1294 if (!cls_belongs_to_core_lib) { 1356 if (!cls_belongs_to_core_lib) {
1295 // Prevent extending core implementation classes. 1357 // Prevent extending core implementation classes.
1296 bool is_error = false; 1358 bool is_error = false;
1297 switch (interface_class.id()) { 1359 switch (interface_class.id()) {
1298 case kNumberCid: 1360 case kNumberCid:
1299 case kIntegerCid: // Class Integer, not int. 1361 case kIntegerCid: // Class Integer, not int.
1300 case kSmiCid: 1362 case kSmiCid:
(...skipping 281 matching lines...) Expand 10 before | Expand all | Expand 10 after
1582 void ClassFinalizer::ReportError(const char* format, ...) { 1644 void ClassFinalizer::ReportError(const char* format, ...) {
1583 va_list args; 1645 va_list args;
1584 va_start(args, format); 1646 va_start(args, format);
1585 const Error& error = Error::Handle( 1647 const Error& error = Error::Handle(
1586 Parser::FormatError(Script::Handle(), -1, "Error", format, args)); 1648 Parser::FormatError(Script::Handle(), -1, "Error", format, args));
1587 va_end(args); 1649 va_end(args);
1588 ReportError(error); 1650 ReportError(error);
1589 } 1651 }
1590 1652
1591 } // namespace dart 1653 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/class_finalizer.h ('k') | runtime/vm/object.h » ('j') | runtime/vm/object.h » ('J')

Powered by Google App Engine
This is Rietveld 408576698