Chromium Code Reviews| 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 1373 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1384 | 1384 |
| 1385 if (FLAG_trace_class_finalization) { | 1385 if (FLAG_trace_class_finalization) { |
| 1386 OS::Print("done mixin type appl %s %s extending '%s'\n", | 1386 OS::Print("done mixin type appl %s %s extending '%s'\n", |
| 1387 String::Handle(cls.Name()).ToCString(), | 1387 String::Handle(cls.Name()).ToCString(), |
| 1388 TypeArguments::Handle(cls.type_parameters()).ToCString(), | 1388 TypeArguments::Handle(cls.type_parameters()).ToCString(), |
| 1389 AbstractType::Handle(cls.super_type()).ToCString()); | 1389 AbstractType::Handle(cls.super_type()).ToCString()); |
| 1390 } | 1390 } |
| 1391 } | 1391 } |
| 1392 | 1392 |
| 1393 | 1393 |
| 1394 void ClassFinalizer::CreateForwardingConstructors( | |
| 1395 const Class& mixin_app, | |
| 1396 const GrowableObjectArray& cloned_funcs) { | |
|
srdjan
2013/07/12 21:53:57
ditto
hausner
2013/07/12 22:00:42
Done.
| |
| 1397 const String& mixin_name = String::Handle(mixin_app.Name()); | |
| 1398 const Class& super_class = Class::Handle(mixin_app.SuperClass()); | |
| 1399 const String& super_name = String::Handle(super_class.Name()); | |
| 1400 const Type& dynamic_type = Type::Handle(Type::DynamicType()); | |
| 1401 const Array& functions = Array::Handle(super_class.functions()); | |
| 1402 intptr_t num_functions = functions.Length(); | |
| 1403 Function& func = Function::Handle(); | |
| 1404 for (intptr_t i = 0; i < num_functions; i++) { | |
| 1405 func ^= functions.At(i); | |
| 1406 if (func.IsConstructor()) { | |
| 1407 // Build constructor name from mixin application class name | |
| 1408 // and name of cloned super class constructor. | |
| 1409 String& ctor_name = String::Handle(func.name()); | |
| 1410 ctor_name = String::SubString(ctor_name, super_name.Length()); | |
| 1411 String& clone_name = | |
| 1412 String::Handle(String::Concat(mixin_name, ctor_name)); | |
| 1413 clone_name = Symbols::New(clone_name); | |
| 1414 | |
| 1415 const Function& clone = Function::Handle( | |
| 1416 Function::New(clone_name, | |
| 1417 func.kind(), | |
| 1418 func.is_static(), | |
| 1419 func.is_const(), | |
| 1420 func.is_abstract(), | |
| 1421 func.is_external(), | |
| 1422 mixin_app, | |
| 1423 mixin_app.token_pos())); | |
| 1424 | |
| 1425 clone.set_num_fixed_parameters(func.num_fixed_parameters()); | |
| 1426 clone.SetNumOptionalParameters(func.NumOptionalParameters(), | |
| 1427 func.HasOptionalPositionalParameters()); | |
| 1428 clone.set_result_type(dynamic_type); | |
| 1429 | |
| 1430 const int num_parameters = func.NumParameters(); | |
| 1431 // The cloned ctor shares the parameter names array with the | |
| 1432 // original. | |
| 1433 const Array& parameter_names = Array::Handle(func.parameter_names()); | |
| 1434 ASSERT(parameter_names.Length() == num_parameters); | |
| 1435 clone.set_parameter_names(parameter_names); | |
| 1436 // The parameter types of the cloned constructor are 'dynamic'. | |
| 1437 clone.set_parameter_types(Array::Handle(Array::New(num_parameters))); | |
| 1438 for (intptr_t n = 0; n < num_parameters; n++) { | |
| 1439 clone.SetParameterTypeAt(n, dynamic_type); | |
| 1440 } | |
| 1441 cloned_funcs.Add(clone); | |
| 1442 } | |
| 1443 } | |
| 1444 } | |
| 1445 | |
| 1446 | |
| 1394 void ClassFinalizer::ApplyMixin(const Class& cls) { | 1447 void ClassFinalizer::ApplyMixin(const Class& cls) { |
| 1395 Isolate* isolate = Isolate::Current(); | 1448 Isolate* isolate = Isolate::Current(); |
| 1396 const Type& mixin_type = Type::Handle(isolate, cls.mixin()); | 1449 const Type& mixin_type = Type::Handle(isolate, cls.mixin()); |
| 1397 ASSERT(!mixin_type.IsNull()); | 1450 ASSERT(!mixin_type.IsNull()); |
| 1398 ASSERT(mixin_type.HasResolvedTypeClass()); | 1451 ASSERT(mixin_type.HasResolvedTypeClass()); |
| 1399 const Class& mixin_cls = Class::Handle(isolate, mixin_type.type_class()); | 1452 const Class& mixin_cls = Class::Handle(isolate, mixin_type.type_class()); |
| 1400 mixin_cls.EnsureIsFinalized(isolate); | 1453 mixin_cls.EnsureIsFinalized(isolate); |
| 1401 | 1454 |
| 1402 if (FLAG_trace_class_finalization) { | 1455 if (FLAG_trace_class_finalization) { |
| 1403 OS::Print("Applying mixin '%s' to '%s' at pos %"Pd"\n", | 1456 OS::Print("Applying mixin '%s' to '%s' at pos %"Pd"\n", |
| 1404 String::Handle(mixin_cls.Name()).ToCString(), | 1457 String::Handle(mixin_cls.Name()).ToCString(), |
| 1405 cls.ToCString(), | 1458 cls.ToCString(), |
| 1406 cls.token_pos()); | 1459 cls.token_pos()); |
| 1407 } | 1460 } |
| 1408 | 1461 |
| 1409 const GrowableObjectArray& cloned_funcs = | 1462 const GrowableObjectArray& cloned_funcs = |
| 1410 GrowableObjectArray::Handle(isolate, GrowableObjectArray::New()); | 1463 GrowableObjectArray::Handle(isolate, GrowableObjectArray::New()); |
| 1464 | |
| 1465 CreateForwardingConstructors(cls, cloned_funcs); | |
| 1466 | |
| 1411 Array& functions = Array::Handle(isolate); | 1467 Array& functions = Array::Handle(isolate); |
| 1412 Function& func = Function::Handle(isolate); | 1468 Function& func = Function::Handle(isolate); |
| 1413 // The parser creates the mixin application class and adds just | 1469 // The parser creates the mixin application class with no functions. |
| 1414 // one function, the implicit constructor. | 1470 ASSERT((functions = cls.functions(), functions.Length() == 0)); |
| 1415 functions = cls.functions(); | |
| 1416 ASSERT(functions.Length() == 1); | |
| 1417 func ^= functions.At(0); | |
| 1418 ASSERT(func.IsImplicitConstructor()); | |
| 1419 cloned_funcs.Add(func); | |
| 1420 // Now clone the functions from the mixin class. | 1471 // Now clone the functions from the mixin class. |
| 1421 functions = mixin_cls.functions(); | 1472 functions = mixin_cls.functions(); |
| 1422 const intptr_t num_functions = functions.Length(); | 1473 const intptr_t num_functions = functions.Length(); |
| 1423 for (int i = 0; i < num_functions; i++) { | 1474 for (int i = 0; i < num_functions; i++) { |
| 1424 func ^= functions.At(i); | 1475 func ^= functions.At(i); |
| 1425 if (func.IsConstructor()) { | 1476 if (func.IsConstructor()) { |
| 1426 // A mixin class must not have explicit constructors. | 1477 // A mixin class must not have explicit constructors. |
| 1427 if (!func.IsImplicitConstructor()) { | 1478 if (!func.IsImplicitConstructor()) { |
| 1428 const Script& script = Script::Handle(isolate, cls.script()); | 1479 const Script& script = Script::Handle(isolate, cls.script()); |
| 1429 ReportError(script, cls.token_pos(), | 1480 ReportError(script, cls.token_pos(), |
| (...skipping 707 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2137 expected_name ^= String::New("_offset"); | 2188 expected_name ^= String::New("_offset"); |
| 2138 ASSERT(String::EqualsIgnoringPrivateKey(name, expected_name)); | 2189 ASSERT(String::EqualsIgnoringPrivateKey(name, expected_name)); |
| 2139 field ^= fields_array.At(2); | 2190 field ^= fields_array.At(2); |
| 2140 ASSERT(field.Offset() == TypedDataView::length_offset()); | 2191 ASSERT(field.Offset() == TypedDataView::length_offset()); |
| 2141 name ^= field.name(); | 2192 name ^= field.name(); |
| 2142 ASSERT(name.Equals("length")); | 2193 ASSERT(name.Equals("length")); |
| 2143 #endif | 2194 #endif |
| 2144 } | 2195 } |
| 2145 | 2196 |
| 2146 } // namespace dart | 2197 } // namespace dart |
| OLD | NEW |