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

Side by Side Diff: runtime/vm/class_finalizer.cc

Issue 49853004: Implement stricter rule about self referencing typedefs (fix issue 13675). (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 7 years, 1 month 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
« no previous file with comments | « runtime/vm/class_finalizer.h ('k') | runtime/vm/object.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 566 matching lines...) Expand 10 before | Expand all | Expand 10 after
577 AbstractTypeArguments& super_type_args = AbstractTypeArguments::Handle(); 577 AbstractTypeArguments& super_type_args = AbstractTypeArguments::Handle();
578 if (super_type.IsBeingFinalized()) { 578 if (super_type.IsBeingFinalized()) {
579 // This type references itself via its type arguments. This is legal, but 579 // This type references itself via its type arguments. This is legal, but
580 // we must avoid endless recursion. We therefore map the innermost 580 // we must avoid endless recursion. We therefore map the innermost
581 // super type to dynamic. 581 // super type to dynamic.
582 // Note that a direct self-reference via the super class chain is illegal 582 // Note that a direct self-reference via the super class chain is illegal
583 // and reported as an error earlier. 583 // and reported as an error earlier.
584 // Such legal self-references occur with F-bounded quantification. 584 // Such legal self-references occur with F-bounded quantification.
585 // Example 1: class Derived extends Base<Derived>. 585 // Example 1: class Derived extends Base<Derived>.
586 // The type 'Derived' forms a cycle by pointing to itself via its 586 // The type 'Derived' forms a cycle by pointing to itself via its
587 // flattened type argument vector: Derived[Base[Derived[Base[...]]]] 587 // flattened type argument vector: Derived[Derived[...]]
588 // We break the cycle as follows: Derived[Base[Derived[dynamic]]] 588 // We break the cycle as follows: Derived[Derived[dynamic]]
589 // Example 2: class Derived extends Base<Middle<Derived>> results in 589 // Example 2: class Derived extends Base<Middle<Derived>> results in
590 // Derived[Base[Middle[Derived[dynamic]]]] 590 // Derived[Middle[Derived[dynamic]]]
591 // Example 3: class Derived<T> extends Base<Derived<T>> results in 591 // Example 3: class Derived<T> extends Base<Derived<T>> results in
592 // Derived[Base[Derived[dynamic]], T]. 592 // Derived[Derived[dynamic], T].
593 ASSERT(super_type_args.IsNull()); // Same as a vector of dynamic. 593 ASSERT(super_type_args.IsNull()); // Same as a vector of dynamic.
594 } else { 594 } else {
595 super_type ^= FinalizeType(cls, super_type, finalization); 595 super_type ^= FinalizeType(cls, super_type, finalization);
596 cls.set_super_type(super_type); 596 cls.set_super_type(super_type);
597 super_type_args = super_type.arguments(); 597 super_type_args = super_type.arguments();
598 } 598 }
599 const intptr_t num_super_type_params = super_class.NumTypeParameters(); 599 const intptr_t num_super_type_params = super_class.NumTypeParameters();
600 const intptr_t offset = super_class.NumTypeArguments(); 600 const intptr_t offset = super_class.NumTypeArguments();
601 const intptr_t super_offset = offset - num_super_type_params; 601 const intptr_t super_offset = offset - num_super_type_params;
602 ASSERT(offset == (cls.NumTypeArguments() - cls.NumOwnTypeArguments())); 602 ASSERT(offset == (cls.NumTypeArguments() - cls.NumOwnTypeArguments()));
(...skipping 1517 matching lines...) Expand 10 before | Expand all | Expand 10 after
2120 if (!test2.IsNull()) { 2120 if (!test2.IsNull()) {
2121 test2 = test2.SuperClass(); 2121 test2 = test2.SuperClass();
2122 } 2122 }
2123 } 2123 }
2124 // No cycles. 2124 // No cycles.
2125 return true; 2125 return true;
2126 } 2126 }
2127 2127
2128 2128
2129 // Helper function called by IsAliasCycleFree. 2129 // Helper function called by IsAliasCycleFree.
2130 bool ClassFinalizer::IsParameterTypeCycleFree( 2130 bool ClassFinalizer::IsTypeCycleFree(
2131 const Class& cls, 2131 const Class& cls,
2132 const AbstractType& type, 2132 const AbstractType& type,
2133 GrowableArray<intptr_t>* visited) { 2133 GrowableArray<intptr_t>* visited) {
2134 ASSERT(visited != NULL); 2134 ASSERT(visited != NULL);
2135 ResolveType(cls, type, kCanonicalize); 2135 ResolveType(cls, type, kCanonicalize);
2136 if (type.IsType() && !type.IsMalformed()) { 2136 if (type.IsType() && !type.IsMalformed()) {
2137 const Class& type_class = Class::Handle(type.type_class()); 2137 const Class& type_class = Class::Handle(type.type_class());
2138 if (!type_class.is_type_finalized() && 2138 if (!type_class.is_type_finalized() &&
2139 type_class.IsSignatureClass() && 2139 type_class.IsSignatureClass() &&
2140 !IsAliasCycleFree(type_class, visited)) { 2140 !IsAliasCycleFree(type_class, visited)) {
2141 return false; 2141 return false;
2142 } 2142 }
2143 const AbstractTypeArguments& type_args = AbstractTypeArguments::Handle( 2143 const AbstractTypeArguments& type_args = AbstractTypeArguments::Handle(
2144 type.arguments()); 2144 type.arguments());
2145 if (!type_args.IsNull()) { 2145 if (!type_args.IsNull()) {
2146 AbstractType& type_arg = AbstractType::Handle(); 2146 AbstractType& type_arg = AbstractType::Handle();
2147 for (intptr_t i = 0; i < type_args.Length(); i++) { 2147 for (intptr_t i = 0; i < type_args.Length(); i++) {
2148 type_arg = type_args.TypeAt(i); 2148 type_arg = type_args.TypeAt(i);
2149 if (!IsParameterTypeCycleFree(cls, type_arg, visited)) { 2149 if (!IsTypeCycleFree(cls, type_arg, visited)) {
2150 return false; 2150 return false;
2151 } 2151 }
2152 } 2152 }
2153 } 2153 }
2154 } 2154 }
2155 return true; 2155 return true;
2156 } 2156 }
2157 2157
2158 2158
2159 // Returns false if the function type alias illegally refers to itself. 2159 // Returns false if the function type alias illegally refers to itself.
2160 bool ClassFinalizer::IsAliasCycleFree(const Class& cls, 2160 bool ClassFinalizer::IsAliasCycleFree(const Class& cls,
2161 GrowableArray<intptr_t>* visited) { 2161 GrowableArray<intptr_t>* visited) {
2162 ASSERT(cls.IsSignatureClass()); 2162 ASSERT(cls.IsSignatureClass());
2163 ASSERT(!cls.is_type_finalized()); 2163 ASSERT(!cls.is_type_finalized());
2164 ASSERT(visited != NULL); 2164 ASSERT(visited != NULL);
2165 const intptr_t cls_index = cls.id(); 2165 const intptr_t cls_index = cls.id();
2166 for (intptr_t i = 0; i < visited->length(); i++) { 2166 for (intptr_t i = 0; i < visited->length(); i++) {
2167 if ((*visited)[i] == cls_index) { 2167 if ((*visited)[i] == cls_index) {
2168 // We have already visited alias 'cls'. We found a cycle. 2168 // We have already visited alias 'cls'. We found a cycle.
2169 return false; 2169 return false;
2170 } 2170 }
2171 } 2171 }
2172 2172
2173 // Visit the result type and parameter types of this signature type. 2173 // Visit the bounds, result type, and parameter types of this signature type.
2174 visited->Add(cls.id()); 2174 visited->Add(cls.id());
2175 AbstractType& type = AbstractType::Handle();
2176
2177 // Check the bounds of this signature type.
2178 const intptr_t num_type_params = cls.NumTypeParameters();
2179 TypeParameter& type_param = TypeParameter::Handle();
2180 const AbstractTypeArguments& type_params =
2181 AbstractTypeArguments::Handle(cls.type_parameters());
2182 ASSERT((type_params.IsNull() && (num_type_params == 0)) ||
2183 (type_params.Length() == num_type_params));
2184 for (intptr_t i = 0; i < num_type_params; i++) {
2185 type_param ^= type_params.TypeAt(i);
2186 type = type_param.bound();
2187 if (!IsTypeCycleFree(cls, type, visited)) {
2188 return false;
2189 }
2190 }
2191 // Check the result type of the function of this signature type.
2175 const Function& function = Function::Handle(cls.signature_function()); 2192 const Function& function = Function::Handle(cls.signature_function());
2176 // Check class of result type. 2193 type = function.result_type();
2177 AbstractType& type = AbstractType::Handle(function.result_type()); 2194 if (!IsTypeCycleFree(cls, type, visited)) {
2178 if (!IsParameterTypeCycleFree(cls, type, visited)) {
2179 return false; 2195 return false;
2180 } 2196 }
2181 // Check classes of formal parameter types. 2197 // Check the formal parameter types of the function of this signature type.
2182 const intptr_t num_parameters = function.NumParameters(); 2198 const intptr_t num_parameters = function.NumParameters();
2183 for (intptr_t i = 0; i < num_parameters; i++) { 2199 for (intptr_t i = 0; i < num_parameters; i++) {
2184 type = function.ParameterTypeAt(i); 2200 type = function.ParameterTypeAt(i);
2185 if (!IsParameterTypeCycleFree(cls, type, visited)) { 2201 if (!IsTypeCycleFree(cls, type, visited)) {
2186 return false; 2202 return false;
2187 } 2203 }
2188 } 2204 }
2189 visited->RemoveLast(); 2205 visited->RemoveLast();
2190 return true; 2206 return true;
2191 } 2207 }
2192 2208
2193 2209
2194 // Returns false if the mixin illegally refers to itself. 2210 // Returns false if the mixin illegally refers to itself.
2195 bool ClassFinalizer::IsMixinCycleFree(const Class& cls, 2211 bool ClassFinalizer::IsMixinCycleFree(const Class& cls,
(...skipping 550 matching lines...) Expand 10 before | Expand all | Expand 10 after
2746 expected_name ^= String::New("_offset"); 2762 expected_name ^= String::New("_offset");
2747 ASSERT(String::EqualsIgnoringPrivateKey(name, expected_name)); 2763 ASSERT(String::EqualsIgnoringPrivateKey(name, expected_name));
2748 field ^= fields_array.At(2); 2764 field ^= fields_array.At(2);
2749 ASSERT(field.Offset() == TypedDataView::length_offset()); 2765 ASSERT(field.Offset() == TypedDataView::length_offset());
2750 name ^= field.name(); 2766 name ^= field.name();
2751 ASSERT(name.Equals("length")); 2767 ASSERT(name.Equals("length"));
2752 #endif 2768 #endif
2753 } 2769 }
2754 2770
2755 } // namespace dart 2771 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/class_finalizer.h ('k') | runtime/vm/object.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698