| OLD | NEW |
| 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 1239 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1250 class_name.ToCString(), | 1250 class_name.ToCString(), |
| 1251 function_name.ToCString(), | 1251 function_name.ToCString(), |
| 1252 super_class_name.ToCString()); | 1252 super_class_name.ToCString()); |
| 1253 } | 1253 } |
| 1254 } | 1254 } |
| 1255 } | 1255 } |
| 1256 } | 1256 } |
| 1257 | 1257 |
| 1258 | 1258 |
| 1259 // Copy the type parameters of the super and mixin classes to the | 1259 // Copy the type parameters of the super and mixin classes to the |
| 1260 // mixin application class. Change type arguments of super type to | 1260 // mixin application class. Change type arguments of super type and of |
| 1261 // refer to the respective type parameters of the mixin application | 1261 // interfaces to refer to the respective type parameters of the mixin |
| 1262 // class. | 1262 // application class. |
| 1263 void ClassFinalizer::CloneTypeParameters(const Class& mixapp_class) { | 1263 void ClassFinalizer::CloneTypeParameters(const Class& mixapp_class) { |
| 1264 ASSERT(mixapp_class.NumTypeParameters() == 0); | 1264 ASSERT(mixapp_class.NumTypeParameters() == 0); |
| 1265 | 1265 |
| 1266 const AbstractType& super_type = | 1266 const AbstractType& super_type = |
| 1267 AbstractType::Handle(mixapp_class.super_type()); | 1267 AbstractType::Handle(mixapp_class.super_type()); |
| 1268 ASSERT(super_type.IsResolved()); | 1268 ASSERT(super_type.IsResolved()); |
| 1269 const Class& super_class = Class::Handle(super_type.type_class()); | 1269 const Class& super_class = Class::Handle(super_type.type_class()); |
| 1270 const Type& mixin_type = Type::Handle(mixapp_class.mixin()); | 1270 const Type& mixin_type = Type::Handle(mixapp_class.mixin()); |
| 1271 const Class& mixin_class = Class::Handle(mixin_type.type_class()); | 1271 const Class& mixin_class = Class::Handle(mixin_type.type_class()); |
| 1272 const int num_super_parameters = super_class.NumTypeParameters(); | 1272 const int num_super_parameters = super_class.NumTypeParameters(); |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1311 param.token_pos()); | 1311 param.token_pos()); |
| 1312 cloned_type_params.SetTypeAt(cloned_index, cloned_param); | 1312 cloned_type_params.SetTypeAt(cloned_index, cloned_param); |
| 1313 // Change the type arguments of the super type to refer to the | 1313 // Change the type arguments of the super type to refer to the |
| 1314 // cloned type parameters of the mixin application class. | 1314 // cloned type parameters of the mixin application class. |
| 1315 super_type_args.SetTypeAt(cloned_index, cloned_param); | 1315 super_type_args.SetTypeAt(cloned_index, cloned_param); |
| 1316 cloned_index++; | 1316 cloned_index++; |
| 1317 } | 1317 } |
| 1318 // TODO(hausner): May need to handle BoundedType here. | 1318 // TODO(hausner): May need to handle BoundedType here. |
| 1319 ASSERT(super_type.IsType()); | 1319 ASSERT(super_type.IsType()); |
| 1320 Type::Cast(super_type).set_arguments(super_type_args); | 1320 Type::Cast(super_type).set_arguments(super_type_args); |
| 1321 ASSERT(!super_type.IsFinalized()); |
| 1321 } | 1322 } |
| 1322 | 1323 |
| 1323 // Second, clone the type parameters of the mixin class. | 1324 // Second, clone the type parameters of the mixin class. |
| 1324 // We need to retain the parameter names of the mixin class | 1325 // We need to retain the parameter names of the mixin class |
| 1325 // since the code that will be compiled in the context of the | 1326 // since the code that will be compiled in the context of the |
| 1326 // mixin application class may refer to the type parameters | 1327 // mixin application class may refer to the type parameters |
| 1327 // with that name. | 1328 // with that name. |
| 1328 if (num_mixin_parameters > 0) { | 1329 if (num_mixin_parameters > 0) { |
| 1329 const TypeArguments& mixin_params = | 1330 const TypeArguments& mixin_params = |
| 1330 TypeArguments::Handle(mixin_class.type_parameters()); | 1331 TypeArguments::Handle(mixin_class.type_parameters()); |
| 1332 const TypeArguments& interface_type_args = TypeArguments::Handle( |
| 1333 TypeArguments::New(num_mixin_parameters)); |
| 1331 for (int i = 0; i < num_mixin_parameters; i++) { | 1334 for (int i = 0; i < num_mixin_parameters; i++) { |
| 1332 param ^= mixin_params.TypeAt(i); | 1335 param ^= mixin_params.TypeAt(i); |
| 1333 param_name = param.name(); | 1336 param_name = param.name(); |
| 1334 param_bound = param.bound(); | 1337 param_bound = param.bound(); |
| 1335 | 1338 |
| 1336 // TODO(hausner): handle type bounds. | 1339 // TODO(hausner): handle type bounds. |
| 1337 if (!param_bound.IsObjectType()) { | 1340 if (!param_bound.IsObjectType()) { |
| 1338 const Script& script = Script::Handle(mixapp_class.script()); | 1341 const Script& script = Script::Handle(mixapp_class.script()); |
| 1339 ReportError(script, param.token_pos(), | 1342 ReportError(script, param.token_pos(), |
| 1340 "type parameter '%s': type bounds not yet" | 1343 "type parameter '%s': type bounds not yet" |
| 1341 " implemented for mixins\n", | 1344 " implemented for mixins\n", |
| 1342 param_name.ToCString()); | 1345 param_name.ToCString()); |
| 1343 } | 1346 } |
| 1344 cloned_param = TypeParameter::New(mixapp_class, | 1347 cloned_param = TypeParameter::New(mixapp_class, |
| 1345 cloned_index, | 1348 cloned_index, |
| 1346 param_name, | 1349 param_name, |
| 1347 param_bound, | 1350 param_bound, |
| 1348 param.token_pos()); | 1351 param.token_pos()); |
| 1349 cloned_type_params.SetTypeAt(cloned_index, cloned_param); | 1352 cloned_type_params.SetTypeAt(cloned_index, cloned_param); |
| 1353 interface_type_args.SetTypeAt(i, cloned_param); |
| 1350 cloned_index++; | 1354 cloned_index++; |
| 1351 } | 1355 } |
| 1356 |
| 1357 // Lastly, change the type arguments of the single interface type to |
| 1358 // refer to the cloned type parameters of the mixin application class. |
| 1359 Array& interface_types = Array::Handle(mixapp_class.interfaces()); |
| 1360 ASSERT(interface_types.Length() == 1); |
| 1361 AbstractType& interface_type = AbstractType::Handle(); |
| 1362 interface_type ^= interface_types.At(0); |
| 1363 ASSERT(interface_type.IsResolved()); |
| 1364 // TODO(hausner): May need to handle BoundedType here. |
| 1365 ASSERT(interface_type.IsType()); |
| 1366 Type::Cast(interface_type).set_arguments(interface_type_args); |
| 1367 ASSERT(!interface_type.IsFinalized()); |
| 1352 } | 1368 } |
| 1353 mixapp_class.set_type_parameters(cloned_type_params); | 1369 mixapp_class.set_type_parameters(cloned_type_params); |
| 1354 } | 1370 } |
| 1355 | 1371 |
| 1356 | 1372 |
| 1357 void ClassFinalizer::ApplyMixinTypes(const Class& cls) { | 1373 void ClassFinalizer::ApplyMixinTypes(const Class& cls) { |
| 1358 const Type& mixin_type = Type::Handle(cls.mixin()); | 1374 const Type& mixin_type = Type::Handle(cls.mixin()); |
| 1359 ASSERT(!mixin_type.IsNull()); | 1375 ASSERT(!mixin_type.IsNull()); |
| 1360 ASSERT(mixin_type.HasResolvedTypeClass()); | 1376 ASSERT(mixin_type.HasResolvedTypeClass()); |
| 1361 const Class& mixin_cls = Class::Handle(mixin_type.type_class()); | 1377 const Class& mixin_cls = Class::Handle(mixin_type.type_class()); |
| 1362 | 1378 |
| 1363 if (FLAG_trace_class_finalization) { | 1379 if (FLAG_trace_class_finalization) { |
| 1364 OS::Print("Applying mixin type '%s' to '%s' at pos %"Pd"\n", | 1380 OS::Print("Applying mixin type '%s' to '%s' at pos %"Pd"\n", |
| 1365 String::Handle(mixin_cls.Name()).ToCString(), | 1381 String::Handle(mixin_type.Name()).ToCString(), |
| 1366 cls.ToCString(), | 1382 cls.ToCString(), |
| 1367 cls.token_pos()); | 1383 cls.token_pos()); |
| 1368 } | 1384 } |
| 1369 | 1385 |
| 1370 // Check that the super class of the mixin class is extending | 1386 // Check that the super class of the mixin class is extending |
| 1371 // class Object. | 1387 // class Object. |
| 1372 const AbstractType& mixin_super_type = | 1388 const AbstractType& mixin_super_type = |
| 1373 AbstractType::Handle(mixin_cls.super_type()); | 1389 AbstractType::Handle(mixin_cls.super_type()); |
| 1374 if (!mixin_super_type.IsObjectType()) { | 1390 if (!mixin_super_type.IsObjectType()) { |
| 1375 const Script& script = Script::Handle(cls.script()); | 1391 const Script& script = Script::Handle(cls.script()); |
| 1376 const String& class_name = String::Handle(mixin_cls.Name()); | 1392 const String& class_name = String::Handle(mixin_cls.Name()); |
| 1377 ReportError(script, cls.token_pos(), | 1393 ReportError(script, cls.token_pos(), |
| 1378 "mixin class %s must extend class Object", | 1394 "mixin class %s must extend class Object", |
| 1379 class_name.ToCString()); | 1395 class_name.ToCString()); |
| 1380 } | 1396 } |
| 1381 | 1397 |
| 1382 // Copy type parameters to mixin application class. | 1398 // Copy type parameters to mixin application class. |
| 1383 CloneTypeParameters(cls); | 1399 CloneTypeParameters(cls); |
| 1384 | 1400 |
| 1385 if (FLAG_trace_class_finalization) { | 1401 if (FLAG_trace_class_finalization) { |
| 1386 OS::Print("done mixin type appl %s %s extending '%s'\n", | 1402 OS::Print("Done applying mixin type '%s' to class %s %s extending '%s'\n", |
| 1403 String::Handle(mixin_type.Name()).ToCString(), |
| 1387 String::Handle(cls.Name()).ToCString(), | 1404 String::Handle(cls.Name()).ToCString(), |
| 1388 TypeArguments::Handle(cls.type_parameters()).ToCString(), | 1405 TypeArguments::Handle(cls.type_parameters()).ToCString(), |
| 1389 AbstractType::Handle(cls.super_type()).ToCString()); | 1406 AbstractType::Handle(cls.super_type()).ToCString()); |
| 1390 } | 1407 } |
| 1391 } | 1408 } |
| 1392 | 1409 |
| 1393 | 1410 |
| 1394 void ClassFinalizer::CreateForwardingConstructors( | 1411 void ClassFinalizer::CreateForwardingConstructors( |
| 1395 const Class& mixin_app, | 1412 const Class& mixin_app, |
| 1396 const GrowableObjectArray& cloned_funcs) { | 1413 const GrowableObjectArray& cloned_funcs) { |
| (...skipping 791 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2188 expected_name ^= String::New("_offset"); | 2205 expected_name ^= String::New("_offset"); |
| 2189 ASSERT(String::EqualsIgnoringPrivateKey(name, expected_name)); | 2206 ASSERT(String::EqualsIgnoringPrivateKey(name, expected_name)); |
| 2190 field ^= fields_array.At(2); | 2207 field ^= fields_array.At(2); |
| 2191 ASSERT(field.Offset() == TypedDataView::length_offset()); | 2208 ASSERT(field.Offset() == TypedDataView::length_offset()); |
| 2192 name ^= field.name(); | 2209 name ^= field.name(); |
| 2193 ASSERT(name.Equals("length")); | 2210 ASSERT(name.Equals("length")); |
| 2194 #endif | 2211 #endif |
| 2195 } | 2212 } |
| 2196 | 2213 |
| 2197 } // namespace dart | 2214 } // namespace dart |
| OLD | NEW |