| 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/code_generator.h" | 7 #include "vm/code_generator.h" |
| 8 #include "vm/flags.h" | 8 #include "vm/flags.h" |
| 9 #include "vm/heap.h" | 9 #include "vm/heap.h" |
| 10 #include "vm/isolate.h" | 10 #include "vm/isolate.h" |
| (...skipping 1390 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1401 const intptr_t num_super_type_params = super_class.NumTypeParameters(); | 1401 const intptr_t num_super_type_params = super_class.NumTypeParameters(); |
| 1402 const Type& mixin_type = Type::Handle(isolate, mixin_app_class.mixin()); | 1402 const Type& mixin_type = Type::Handle(isolate, mixin_app_class.mixin()); |
| 1403 const Class& mixin_class = Class::Handle(isolate, mixin_type.type_class()); | 1403 const Class& mixin_class = Class::Handle(isolate, mixin_type.type_class()); |
| 1404 const intptr_t num_mixin_type_params = mixin_class.NumTypeParameters(); | 1404 const intptr_t num_mixin_type_params = mixin_class.NumTypeParameters(); |
| 1405 // The mixin class cannot be Object and this was checked earlier. | 1405 // The mixin class cannot be Object and this was checked earlier. |
| 1406 ASSERT(!mixin_class.IsObjectClass()); | 1406 ASSERT(!mixin_class.IsObjectClass()); |
| 1407 | 1407 |
| 1408 // Add the mixin type to the interfaces that the mixin application | 1408 // Add the mixin type to the interfaces that the mixin application |
| 1409 // class implements. This is necessary so that type tests work. | 1409 // class implements. This is necessary so that type tests work. |
| 1410 const Array& interfaces = Array::Handle(isolate, Array::New(1)); | 1410 const Array& interfaces = Array::Handle(isolate, Array::New(1)); |
| 1411 const Type& interface = Type::Handle(isolate, Type::New( | 1411 interfaces.SetAt(0, mixin_type); |
| 1412 mixin_class, | |
| 1413 Object::null_abstract_type_arguments(), // Set again below if generic. | |
| 1414 mixin_app_class.token_pos())); | |
| 1415 ASSERT(!interface.IsFinalized()); | |
| 1416 interfaces.SetAt(0, interface); | |
| 1417 ASSERT(mixin_app_class.interfaces() == Object::empty_array().raw()); | 1412 ASSERT(mixin_app_class.interfaces() == Object::empty_array().raw()); |
| 1418 mixin_app_class.set_interfaces(interfaces); | 1413 mixin_app_class.set_interfaces(interfaces); |
| 1419 | 1414 |
| 1420 // If both the super type and the mixin type are non generic, the mixin | 1415 // If both the super type and the mixin type are non generic, the mixin |
| 1421 // application class is non generic as well and we can skip type parameter | 1416 // application class is non generic as well and we can skip type parameter |
| 1422 // cloning. | 1417 // cloning. |
| 1423 bool has_uninstantiated_bounds = false; | 1418 bool has_uninstantiated_bounds = false; |
| 1424 if ((num_super_type_params + num_mixin_type_params) > 0) { | 1419 if ((num_super_type_params + num_mixin_type_params) > 0) { |
| 1425 // First, clone the super class type parameters. Rename them so that | 1420 // First, clone the super class type parameters. Rename them so that |
| 1426 // there can be no name conflict between the parameters of the super | 1421 // there can be no name conflict between the parameters of the super |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1466 // Second, clone the type parameters of the mixin class. | 1461 // Second, clone the type parameters of the mixin class. |
| 1467 // We need to retain the parameter names of the mixin class | 1462 // We need to retain the parameter names of the mixin class |
| 1468 // since the code that will be compiled in the context of the | 1463 // since the code that will be compiled in the context of the |
| 1469 // mixin application class may refer to the type parameters | 1464 // mixin application class may refer to the type parameters |
| 1470 // with that name. | 1465 // with that name. |
| 1471 if (num_mixin_type_params > 0) { | 1466 if (num_mixin_type_params > 0) { |
| 1472 const TypeArguments& mixin_params = | 1467 const TypeArguments& mixin_params = |
| 1473 TypeArguments::Handle(isolate, mixin_class.type_parameters()); | 1468 TypeArguments::Handle(isolate, mixin_class.type_parameters()); |
| 1474 const TypeArguments& mixin_type_args = TypeArguments::Handle(isolate, | 1469 const TypeArguments& mixin_type_args = TypeArguments::Handle(isolate, |
| 1475 TypeArguments::New(num_mixin_type_params)); | 1470 TypeArguments::New(num_mixin_type_params)); |
| 1476 // TODO(regis): Can we share interface type and mixin_type? | |
| 1477 const TypeArguments& interface_type_args = TypeArguments::Handle(isolate, | |
| 1478 TypeArguments::New(num_mixin_type_params)); | |
| 1479 for (intptr_t i = 0; i < num_mixin_type_params; i++) { | 1471 for (intptr_t i = 0; i < num_mixin_type_params; i++) { |
| 1480 param ^= mixin_params.TypeAt(i); | 1472 param ^= mixin_params.TypeAt(i); |
| 1481 param_name = param.name(); | 1473 param_name = param.name(); |
| 1482 param_bound = param.bound(); // The bound will be adjusted below. | 1474 param_bound = param.bound(); // The bound will be adjusted below. |
| 1483 if (!param_bound.IsInstantiated()) { | 1475 if (!param_bound.IsInstantiated()) { |
| 1484 has_uninstantiated_bounds = true; | 1476 has_uninstantiated_bounds = true; |
| 1485 } | 1477 } |
| 1486 cloned_param = TypeParameter::New(mixin_app_class, | 1478 cloned_param = TypeParameter::New(mixin_app_class, |
| 1487 cloned_index, | 1479 cloned_index, |
| 1488 param_name, | 1480 param_name, |
| 1489 param_bound, | 1481 param_bound, |
| 1490 param.token_pos()); | 1482 param.token_pos()); |
| 1491 cloned_type_params.SetTypeAt(cloned_index, cloned_param); | 1483 cloned_type_params.SetTypeAt(cloned_index, cloned_param); |
| 1492 interface_type_args.SetTypeAt(i, cloned_param); | |
| 1493 mixin_type_args.SetTypeAt(i, cloned_param); | 1484 mixin_type_args.SetTypeAt(i, cloned_param); |
| 1494 cloned_index++; | 1485 cloned_index++; |
| 1495 } | 1486 } |
| 1496 | 1487 |
| 1497 // Third, replace the type parameters appearing in the bounds of the mixin | 1488 // Third, replace the type parameters appearing in the bounds of the mixin |
| 1498 // type parameters, if any, by the cloned type parameters. This can be | 1489 // type parameters, if any, by the cloned type parameters. This can be |
| 1499 // done by instantiating each bound using the mixin_type_args as | 1490 // done by instantiating each bound using the mixin_type_args as |
| 1500 // instantiator. Since the mixin class must extend Object, its first type | 1491 // instantiator. Since the mixin class must extend Object, its first type |
| 1501 // parameter has index 0, therefore, the instantiator does not require | 1492 // parameter has index 0, therefore, the instantiator does not require |
| 1502 // shifting. There is however an exception where the mixin class is an | 1493 // shifting. There is however an exception where the mixin class is an |
| (...skipping 12 matching lines...) Expand all Loading... |
| 1515 &bound_error); | 1506 &bound_error); |
| 1516 // The instantiator contains only TypeParameter objects and no | 1507 // The instantiator contains only TypeParameter objects and no |
| 1517 // BoundedType objects, so no bound error may occur. | 1508 // BoundedType objects, so no bound error may occur. |
| 1518 ASSERT(bound_error.IsNull()); | 1509 ASSERT(bound_error.IsNull()); |
| 1519 ASSERT(!param_bound.IsInstantiated()); | 1510 ASSERT(!param_bound.IsInstantiated()); |
| 1520 param.set_bound(param_bound); | 1511 param.set_bound(param_bound); |
| 1521 } | 1512 } |
| 1522 } | 1513 } |
| 1523 } | 1514 } |
| 1524 | 1515 |
| 1525 // Lastly, set the type arguments of the mixin type and of the single | 1516 // Lastly, set the type arguments of the mixin type, which is also the |
| 1526 // interface type. | 1517 // single interface type. |
| 1527 ASSERT(!mixin_type.IsFinalized()); | 1518 ASSERT(!mixin_type.IsFinalized()); |
| 1528 mixin_type.set_arguments(mixin_type_args); | 1519 mixin_type.set_arguments(mixin_type_args); |
| 1529 ASSERT(!interface.IsFinalized()); | |
| 1530 interface.set_arguments(interface_type_args); | |
| 1531 } | 1520 } |
| 1532 mixin_app_class.set_type_parameters(cloned_type_params); | 1521 mixin_app_class.set_type_parameters(cloned_type_params); |
| 1533 } | 1522 } |
| 1534 // If the mixin class is a mixin application alias class, we insert a new | 1523 // If the mixin class is a mixin application alias class, we insert a new |
| 1535 // synthesized mixin application class in the super chain of this mixin | 1524 // synthesized mixin application class in the super chain of this mixin |
| 1536 // application class. The new class will have the aliased mixin as actual | 1525 // application class. The new class will have the aliased mixin as actual |
| 1537 // mixin. | 1526 // mixin. |
| 1538 if (mixin_class.is_mixin_app_alias()) { | 1527 if (mixin_class.is_mixin_app_alias()) { |
| 1539 ApplyMixinAppAlias(mixin_app_class, has_uninstantiated_bounds); | 1528 ApplyMixinAppAlias(mixin_app_class, has_uninstantiated_bounds); |
| 1540 } | 1529 } |
| (...skipping 1319 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2860 expected_name ^= String::New("_offset"); | 2849 expected_name ^= String::New("_offset"); |
| 2861 ASSERT(String::EqualsIgnoringPrivateKey(name, expected_name)); | 2850 ASSERT(String::EqualsIgnoringPrivateKey(name, expected_name)); |
| 2862 field ^= fields_array.At(2); | 2851 field ^= fields_array.At(2); |
| 2863 ASSERT(field.Offset() == TypedDataView::length_offset()); | 2852 ASSERT(field.Offset() == TypedDataView::length_offset()); |
| 2864 name ^= field.name(); | 2853 name ^= field.name(); |
| 2865 ASSERT(name.Equals("length")); | 2854 ASSERT(name.Equals("length")); |
| 2866 #endif | 2855 #endif |
| 2867 } | 2856 } |
| 2868 | 2857 |
| 2869 } // namespace dart | 2858 } // namespace dart |
| OLD | NEW |