Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, 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 500 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 511 FinalizationKind finalization) { | 511 FinalizationKind finalization) { |
| 512 ASSERT(arguments.Length() >= cls.NumTypeArguments()); | 512 ASSERT(arguments.Length() >= cls.NumTypeArguments()); |
| 513 if (!cls.is_finalized()) { | 513 if (!cls.is_finalized()) { |
| 514 const GrowableObjectArray& visited = | 514 const GrowableObjectArray& visited = |
| 515 GrowableObjectArray::Handle(GrowableObjectArray::New()); | 515 GrowableObjectArray::Handle(GrowableObjectArray::New()); |
| 516 ResolveInterfaces(cls, visited); | 516 ResolveInterfaces(cls, visited); |
| 517 FinalizeTypeParameters(cls); | 517 FinalizeTypeParameters(cls); |
| 518 } | 518 } |
| 519 Type& super_type = Type::Handle(cls.super_type()); | 519 Type& super_type = Type::Handle(cls.super_type()); |
| 520 if (!super_type.IsNull()) { | 520 if (!super_type.IsNull()) { |
| 521 super_type ^= FinalizeType(cls, super_type, finalization); | |
| 522 cls.set_super_type(super_type); | |
| 523 const Class& super_class = Class::Handle(super_type.type_class()); | 521 const Class& super_class = Class::Handle(super_type.type_class()); |
| 524 const AbstractTypeArguments& super_type_args = | 522 AbstractTypeArguments& super_type_args = AbstractTypeArguments::Handle(); |
| 525 AbstractTypeArguments::Handle(super_type.arguments()); | 523 if (super_type.IsBeingFinalized()) { |
| 524 // This type references itself via its type arguments. This is legal, but | |
| 525 // we must avoid the fractal of death. We therefore map the inner most | |
|
srdjan
2012/04/26 22:30:21
Need a link to 'fractal of death' description ;-)
regis
2012/04/26 22:39:04
Renamed "fractal of death" to "endless recursion".
| |
| 526 // super type to Dynamic. | |
| 527 // Note that a direct self-reference via the super class chain is illegal | |
| 528 // and reported as an error earlier. | |
| 529 // Such legal self-references occur with F-bounded quantification. | |
| 530 // Example 1: class Derived extends Base<Derived>. | |
| 531 // The type 'Derived' forms a cycle by pointing to itself via its | |
| 532 // flattened type argument vector: Derived[Base[Derived[Base[...]]]] | |
| 533 // We break the cycle as follows: Derived[Base[Derived[Dynamic]]] | |
| 534 // Example 2: class Derived extends Base<Middle<Derived>> results in | |
| 535 // Derived[Base[Middle[Derived[Dynamic]]]] | |
| 536 // Example 3: class Derived<T> extends Base<Derived<T>> results in | |
| 537 // Derived[Base[Derived[Dynamic]], T]. | |
| 538 ASSERT(super_type_args.IsNull()); // Same as a vector of Dynamic. | |
| 539 } else { | |
| 540 super_type ^= FinalizeType(cls, super_type, finalization); | |
| 541 cls.set_super_type(super_type); | |
| 542 super_type_args = super_type.arguments(); | |
| 543 } | |
| 526 const intptr_t num_super_type_params = super_class.NumTypeParameters(); | 544 const intptr_t num_super_type_params = super_class.NumTypeParameters(); |
| 527 const intptr_t offset = super_class.NumTypeArguments(); | 545 const intptr_t offset = super_class.NumTypeArguments(); |
| 528 const intptr_t super_offset = offset - num_super_type_params; | 546 const intptr_t super_offset = offset - num_super_type_params; |
| 529 ASSERT(offset == (cls.NumTypeArguments() - cls.NumTypeParameters())); | 547 ASSERT(offset == (cls.NumTypeArguments() - cls.NumTypeParameters())); |
| 530 AbstractType& super_type_arg = AbstractType::Handle(Type::DynamicType()); | 548 AbstractType& super_type_arg = AbstractType::Handle(Type::DynamicType()); |
| 531 for (intptr_t i = 0; i < num_super_type_params; i++) { | 549 for (intptr_t i = 0; i < num_super_type_params; i++) { |
| 532 if (!super_type_args.IsNull()) { | 550 if (!super_type_args.IsNull()) { |
| 533 super_type_arg = super_type_args.TypeAt(super_offset + i); | 551 super_type_arg = super_type_args.TypeAt(super_offset + i); |
| 534 if (!super_type_arg.IsInstantiated()) { | 552 if (!super_type_arg.IsInstantiated()) { |
| 535 super_type_arg = super_type_arg.InstantiateFrom(arguments); | 553 super_type_arg = super_type_arg.InstantiateFrom(arguments); |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 585 Error::Handle(), // No previous error. | 603 Error::Handle(), // No previous error. |
| 586 cls, parameterized_type, finalization, | 604 cls, parameterized_type, finalization, |
| 587 "type '%s' illegally refers to itself", | 605 "type '%s' illegally refers to itself", |
| 588 String::Handle(parameterized_type.Name()).ToCString()); | 606 String::Handle(parameterized_type.Name()).ToCString()); |
| 589 return parameterized_type.raw(); | 607 return parameterized_type.raw(); |
| 590 } | 608 } |
| 591 | 609 |
| 592 // Mark type as being finalized in order to detect illegal self reference. | 610 // Mark type as being finalized in order to detect illegal self reference. |
| 593 parameterized_type.set_is_being_finalized(); | 611 parameterized_type.set_is_being_finalized(); |
| 594 | 612 |
| 613 // The type class does not need to be finalized in order to finalize the type, | |
| 614 // however, it must at least be resolved (this was done as part of resolving | |
| 615 // the type itself, a precondition to calling FinalizeType). | |
| 616 // Also, the interfaces of the type class must be resolved and the type | |
| 617 // parameters of the type class must be finalized. | |
| 618 Class& type_class = Class::Handle(parameterized_type.type_class()); | |
| 619 if (!type_class.is_finalized()) { | |
| 620 const GrowableObjectArray& visited = | |
| 621 GrowableObjectArray::Handle(GrowableObjectArray::New()); | |
| 622 ResolveInterfaces(type_class, visited); | |
| 623 FinalizeTypeParameters(type_class); | |
| 624 } | |
| 625 | |
| 595 // Finalize the current type arguments of the type, which are still the | 626 // Finalize the current type arguments of the type, which are still the |
| 596 // parsed type arguments. | 627 // parsed type arguments. |
| 597 AbstractTypeArguments& arguments = | 628 AbstractTypeArguments& arguments = |
| 598 AbstractTypeArguments::Handle(parameterized_type.arguments()); | 629 AbstractTypeArguments::Handle(parameterized_type.arguments()); |
| 599 if (!arguments.IsNull()) { | 630 if (!arguments.IsNull()) { |
| 600 intptr_t num_arguments = arguments.Length(); | 631 intptr_t num_arguments = arguments.Length(); |
| 601 for (intptr_t i = 0; i < num_arguments; i++) { | 632 for (intptr_t i = 0; i < num_arguments; i++) { |
| 602 AbstractType& type_argument = AbstractType::Handle(arguments.TypeAt(i)); | 633 AbstractType& type_argument = AbstractType::Handle(arguments.TypeAt(i)); |
| 603 type_argument = FinalizeType(cls, type_argument, finalization); | 634 type_argument = FinalizeType(cls, type_argument, finalization); |
| 604 arguments.SetTypeAt(i, type_argument); | 635 arguments.SetTypeAt(i, type_argument); |
| 605 } | 636 } |
| 606 } | 637 } |
| 607 | 638 |
| 608 // The type class does not need to be finalized in order to finalize the type, | |
| 609 // however, it must at least be resolved (this was done as part of resolving | |
| 610 // the type itself, a precondition to calling FinalizeType). | |
| 611 // Also, the interfaces of the type class must be resolved and the type | |
| 612 // parameters of the type class must be finalized. | |
| 613 Class& type_class = Class::Handle(parameterized_type.type_class()); | |
| 614 if (!type_class.is_finalized()) { | |
| 615 const GrowableObjectArray& visited = | |
| 616 GrowableObjectArray::Handle(GrowableObjectArray::New()); | |
| 617 ResolveInterfaces(type_class, visited); | |
| 618 FinalizeTypeParameters(type_class); | |
| 619 } | |
| 620 | |
| 621 // If the type class is a signature class, we are finalizing its signature | 639 // If the type class is a signature class, we are finalizing its signature |
| 622 // type, thereby finalizing the result type and parameter types of its | 640 // type, thereby finalizing the result type and parameter types of its |
| 623 // signature function. | 641 // signature function. |
| 624 // Do this before marking this type as finalized in order to detect cycles. | 642 // Do this before marking this type as finalized in order to detect cycles. |
| 625 if (type_class.IsSignatureClass()) { | 643 if (type_class.IsSignatureClass()) { |
| 626 // Signature classes are finalized upon creation. | 644 // Signature classes are finalized upon creation. |
| 627 ASSERT(type_class.is_finalized()); | 645 ASSERT(type_class.is_finalized()); |
| 628 // Resolve and finalize the result and parameter types of the signature | 646 // Resolve and finalize the result and parameter types of the signature |
| 629 // function of this signature class. | 647 // function of this signature class. |
| 630 ResolveAndFinalizeSignature( | 648 ResolveAndFinalizeSignature( |
| (...skipping 713 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1344 void ClassFinalizer::ReportError(const char* format, ...) { | 1362 void ClassFinalizer::ReportError(const char* format, ...) { |
| 1345 va_list args; | 1363 va_list args; |
| 1346 va_start(args, format); | 1364 va_start(args, format); |
| 1347 const Error& error = Error::Handle( | 1365 const Error& error = Error::Handle( |
| 1348 Parser::FormatError(Script::Handle(), -1, "Error", format, args)); | 1366 Parser::FormatError(Script::Handle(), -1, "Error", format, args)); |
| 1349 va_end(args); | 1367 va_end(args); |
| 1350 ReportError(error); | 1368 ReportError(error); |
| 1351 } | 1369 } |
| 1352 | 1370 |
| 1353 } // namespace dart | 1371 } // namespace dart |
| OLD | NEW |