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

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

Issue 8509031: Revert r1380 that is breaking frog. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 9 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/class_finalizer_test.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) 2011, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2011, 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"
11 #include "vm/object_store.h" 11 #include "vm/object_store.h"
12 12
13 namespace dart { 13 namespace dart {
14 14
15 DEFINE_FLAG(bool, print_classes, false, "Prints details about loaded classes."); 15 DEFINE_FLAG(bool, print_classes, false, "Prints details about loaded classes.");
16 DEFINE_FLAG(bool, trace_class_finalization, false, "Trace class finalization."); 16 DEFINE_FLAG(bool, trace_class_finalization, false, "Trace class finalization.");
17 DEFINE_FLAG(bool, verify_implements, false, 17 DEFINE_FLAG(bool, verify_implements, false,
18 "Verify that all classes implement their interface."); 18 "Verify that all classes implement their interface.");
19 DECLARE_FLAG(bool, enable_type_checks); 19 DECLARE_FLAG(bool, enable_type_checks);
20 20
21 void ClassFinalizer::ExpectClassesToFinalize() { 21 void ClassFinalizer::AddPendingClasses(
22 if (!IsExpectingClassesToFinalize()) {
23 ObjectStore* object_store = Isolate::Current()->object_store();
24 object_store->set_pending_classes(Array::Handle(Array::Empty()));
25 ASSERT(IsExpectingClassesToFinalize());
26 }
27 }
28
29
30 bool ClassFinalizer::IsExpectingClassesToFinalize() {
31 ObjectStore* object_store = Isolate::Current()->object_store();
32 const Array& classes = Array::Handle(object_store->pending_classes());
33 return !classes.IsNull();
34 }
35
36
37 void ClassFinalizer::AddClassesToFinalize(
38 const GrowableArray<const Class*>& classes) { 22 const GrowableArray<const Class*>& classes) {
39 // ExpectClassesToFinalize() must be called prior to calling
40 // AddClassesToFinalize().
41 ASSERT(IsExpectingClassesToFinalize());
42 if (!classes.is_empty()) { 23 if (!classes.is_empty()) {
43 ObjectStore* object_store = Isolate::Current()->object_store(); 24 ObjectStore* object_store = Isolate::Current()->object_store();
44 const Array& old_array = Array::Handle(object_store->pending_classes()); 25 const Array& old_array = Array::Handle(object_store->pending_classes());
45 const intptr_t old_length = old_array.Length(); 26 const intptr_t old_length = old_array.Length();
46 const int new_length = old_length + classes.length(); 27 const int new_length = old_length + classes.length();
47 const Array& new_array = Array::Handle(Array::Grow(old_array, new_length)); 28 const Array& new_array = Array::Handle(Array::Grow(old_array, new_length));
48 // Add new classes. 29 // Add new classes.
49 for (int i = 0; i < classes.length(); i++) { 30 for (int i = 0; i < classes.length(); i++) {
50 new_array.SetAt(i + old_length, *classes[i]); 31 new_array.SetAt(i + old_length, *classes[i]);
51 } 32 }
52 object_store->set_pending_classes(new_array); 33 object_store->set_pending_classes(new_array);
53 ASSERT(IsExpectingClassesToFinalize());
54 } 34 }
55 } 35 }
56 36
57 37
38 bool ClassFinalizer::AllClassesFinalized() {
39 ObjectStore* object_store = Isolate::Current()->object_store();
40 const Array& classes = Array::Handle(object_store->pending_classes());
41 return classes.Length() == 0;
42 }
43
44
58 // Class finalization occurs: 45 // Class finalization occurs:
59 // a) when bootstrap process completes (VerifyBootstrapClasses). 46 // a) when bootstrap process completes (VerifyBootstrapClasses).
60 // b) after the user classes are loaded (dart_api). 47 // b) after the user classes are loaded (dart_api).
61 bool ClassFinalizer::FinalizeAllClasses() { 48 bool ClassFinalizer::FinalizePendingClasses() {
62 bool retval = true; 49 bool retval = true;
63 Isolate* isolate = Isolate::Current(); 50 Isolate* isolate = Isolate::Current();
64 ASSERT(isolate != NULL); 51 ASSERT(isolate != NULL);
65 ObjectStore* object_store = isolate->object_store(); 52 ObjectStore* object_store = isolate->object_store();
66 const String& error = String::Handle(object_store->sticky_error()); 53 const String& error = String::Handle(object_store->sticky_error());
67 if (!error.IsNull()) { 54 if (!error.IsNull()) {
68 return false; 55 return false;
69 } 56 }
70 LongJump* base = isolate->long_jump_base(); 57 LongJump* base = isolate->long_jump_base();
71 LongJump jump; 58 LongJump jump;
72 isolate->set_long_jump_base(&jump); 59 isolate->set_long_jump_base(&jump);
73 if (setjmp(*jump.Set()) == 0) { 60 if (setjmp(*jump.Set()) == 0) {
74 const Array& class_array = Array::Handle(object_store->pending_classes()); 61 const Array& class_array = Array::Handle(object_store->pending_classes());
75 const intptr_t num_pending_classes = 62 ASSERT(!class_array.IsNull());
76 class_array.IsNull() ? 0 : class_array.Length();
77 Class& cls = Class::Handle(); 63 Class& cls = Class::Handle();
78 // First resolve all superclasses. 64 // First resolve all superclasses.
79 for (intptr_t i = 0; i < num_pending_classes; i++) { 65 for (intptr_t i = 0; i < class_array.Length(); i++) {
80 cls ^= class_array.At(i); 66 cls ^= class_array.At(i);
81 if (FLAG_trace_class_finalization) { 67 if (FLAG_trace_class_finalization) {
82 OS::Print("Resolving super and default: %s\n", cls.ToCString()); 68 OS::Print("Resolving super and default: %s\n", cls.ToCString());
83 } 69 }
84 ResolveSuperClass(cls); 70 ResolveSuperClass(cls);
85 if (cls.is_interface()) { 71 if (cls.is_interface()) {
86 ResolveDefaultClass(cls); 72 ResolveDefaultClass(cls);
87 } 73 }
88 } 74 }
89 // Finalize all classes. 75 // Finalize all classes.
90 for (intptr_t i = 0; i < num_pending_classes; i++) { 76 for (intptr_t i = 0; i < class_array.Length(); i++) {
91 cls ^= class_array.At(i); 77 cls ^= class_array.At(i);
92 FinalizeClass(cls); 78 FinalizeClass(cls);
93 } 79 }
94 if (FLAG_print_classes) { 80 if (FLAG_print_classes) {
95 for (intptr_t i = 0; i < num_pending_classes; i++) { 81 for (intptr_t i = 0; i < class_array.Length(); i++) {
96 cls ^= class_array.At(i); 82 cls ^= class_array.At(i);
97 PrintClassInformation(cls); 83 PrintClassInformation(cls);
98 } 84 }
99 } 85 }
100 if (FLAG_verify_implements) { 86 if (FLAG_verify_implements) {
101 for (intptr_t i = 0; i < num_pending_classes; i++) { 87 for (intptr_t i = 0; i < class_array.Length(); i++) {
102 cls ^= class_array.At(i); 88 cls ^= class_array.At(i);
103 if (!cls.is_interface()) { 89 if (!cls.is_interface()) {
104 VerifyClassImplements(cls); 90 VerifyClassImplements(cls);
105 } 91 }
106 } 92 }
107 } 93 }
108 // Clear pending classes array. 94 // Clear pending classes array.
109 object_store->set_pending_classes(Array::Handle()); 95 object_store->set_pending_classes(Array::Handle(Array::Empty()));
110 ASSERT(!IsExpectingClassesToFinalize());
111 96
112 // Check to ensure there are no duplicate definitions in the library 97 // Check to ensure there are no duplicate definitions in the library
113 // hierarchy. 98 // hierarchy.
114 const String& str = String::Handle(Library::CheckForDuplicateDefinition()); 99 const String& str = String::Handle(Library::CheckForDuplicateDefinition());
115 if (!str.IsNull()) { 100 if (!str.IsNull()) {
116 ReportError("Duplicate definition : %s\n", str.ToCString()); 101 ReportError("Duplicate definition : %s\n", str.ToCString());
117 } 102 }
118 } else { 103 } else {
119 retval = false; 104 retval = false;
120 } 105 }
(...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after
237 for (intptr_t i = 0; i < class_array.Length(); i++) { 222 for (intptr_t i = 0; i < class_array.Length(); i++) {
238 // TODO(iposva): Add real checks. 223 // TODO(iposva): Add real checks.
239 cls ^= class_array.At(i); 224 cls ^= class_array.At(i);
240 if (cls.is_finalized() || cls.is_prefinalized()) { 225 if (cls.is_finalized() || cls.is_prefinalized()) {
241 // Pre-finalized bootstrap classes must not define any fields. 226 // Pre-finalized bootstrap classes must not define any fields.
242 ASSERT(Array::Handle(cls.fields()).Length() == 0); 227 ASSERT(Array::Handle(cls.fields()).Length() == 0);
243 } 228 }
244 } 229 }
245 230
246 // Finalize classes that aren't pre-finalized by Object::Init(). 231 // Finalize classes that aren't pre-finalized by Object::Init().
247 if (!FinalizeAllClasses()) { 232 if (!FinalizePendingClasses()) {
248 // TODO(srdjan): Exit like a real VM instead. 233 // TODO(srdjan): Exit like a real VM instead.
249 const String& err = String::Handle(object_store->sticky_error()); 234 const String& err = String::Handle(object_store->sticky_error());
250 OS::PrintErr("Could not verify bootstrap classes : %s\n", err.ToCString()); 235 OS::PrintErr("Could not verify bootstrap classes : %s\n", err.ToCString());
251 OS::Exit(255); 236 OS::Exit(255);
252 } 237 }
253 if (FLAG_trace_class_finalization) { 238 if (FLAG_trace_class_finalization) {
254 OS::Print("VerifyBootstrapClasses END.\n"); 239 OS::Print("VerifyBootstrapClasses END.\n");
255 } 240 }
256 Isolate::Current()->heap()->Verify(); 241 Isolate::Current()->heap()->Verify();
257 } 242 }
258 243
259 244
260 // Resolve unresolved_class in the library of cls.
261 RawClass* ClassFinalizer::ResolveClass(
262 const Class& cls, const UnresolvedClass& unresolved_class) {
263 Library& lib = Library::Handle();
264 if (unresolved_class.qualifier() == String::null()) {
265 lib = cls.library();
266 } else {
267 const String& qualifier = String::Handle(unresolved_class.qualifier());
268 LibraryPrefix& lib_prefix = LibraryPrefix::Handle();
269 lib_prefix = cls.LookupLibraryPrefix(qualifier);
270 if (lib_prefix.IsNull()) {
271 const Script& script = Script::Handle(cls.script());
272 ReportError(script, unresolved_class.token_index(),
273 "cannot resolve library prefix '%s' from '%s'.\n",
274 String::Handle(unresolved_class.Name()).ToCString(),
275 String::Handle(cls.Name()).ToCString());
276 }
277 lib = lib_prefix.library();
278 }
279 ASSERT(!lib.IsNull());
280 const String& class_name = String::Handle(unresolved_class.ident());
281 const Class& resolved_class = Class::Handle(lib.LookupClass(class_name));
282 if (resolved_class.IsNull()) {
283 const Script& script = Script::Handle(cls.script());
284 ReportError(script, unresolved_class.token_index(),
285 "cannot resolve class name '%s' from '%s'.\n",
286 String::Handle(unresolved_class.Name()).ToCString(),
287 String::Handle(cls.Name()).ToCString());
288 }
289 return resolved_class.raw();
290 }
291
292
293 // Resolve unresolved superclasses (String -> Class). 245 // Resolve unresolved superclasses (String -> Class).
294 void ClassFinalizer::ResolveSuperClass(const Class& cls) { 246 void ClassFinalizer::ResolveSuperClass(const Class& cls) {
295 if (cls.is_finalized()) { 247 if (cls.is_finalized()) {
296 return; 248 return;
297 } 249 }
298 Type& super_type = Type::Handle(cls.super_type()); 250 Type& super_type = Type::Handle(cls.super_type());
299 if (super_type.IsNull()) { 251 if (super_type.IsNull()) {
300 return; 252 return;
301 } 253 }
302 // Resolve failures lead to a longjmp. 254 // Resolve failures lead to a longjmp.
303 super_type = ResolveType(cls, super_type); 255 super_type = ResolveType(cls, super_type);
304 if (super_type.IsTypeParameter()) {
305 String& class_name = String::Handle(cls.Name());
306 String& type_parameter_name = String::Handle(super_type.Name());
307 ReportError("'%s' cannot extend or implement type parameter '%s'.\n",
308 class_name.ToCString(),
309 type_parameter_name.ToCString());
310 }
311 cls.set_super_type(super_type); 256 cls.set_super_type(super_type);
312 const Class& super_class = Class::Handle(super_type.type_class()); 257 const Class& super_class = Class::Handle(super_type.type_class());
313 if (cls.is_interface() != super_class.is_interface()) { 258 if (cls.is_interface() != super_class.is_interface()) {
314 String& class_name = String::Handle(cls.Name()); 259 String& class_name = String::Handle(cls.Name());
315 String& super_class_name = String::Handle(super_class.Name()); 260 String& super_class_name = String::Handle(super_class.Name());
316 ReportError("class '%s' and superclass '%s' are not " 261 ReportError("class '%s' and superclass '%s' are not "
317 "both classes or both interfaces.\n", 262 "both classes or both interfaces.\n",
318 class_name.ToCString(), 263 class_name.ToCString(),
319 super_class_name.ToCString()); 264 super_class_name.ToCString());
320 } 265 }
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after
402 // A type parameter cannot be parameterized, so report an error if type 347 // A type parameter cannot be parameterized, so report an error if type
403 // arguments have previously been parsed. 348 // arguments have previously been parsed.
404 if (type.arguments() != TypeArguments::null()) { 349 if (type.arguments() != TypeArguments::null()) {
405 ReportError("type parameter '%s' cannot be parameterized", 350 ReportError("type parameter '%s' cannot be parameterized",
406 type_class_name.ToCString()); 351 type_class_name.ToCString());
407 } 352 }
408 return type_parameter.raw(); 353 return type_parameter.raw();
409 } 354 }
410 355
411 // Lookup the type class. 356 // Lookup the type class.
412 const Class& type_class = 357 Class& type_class = Class::Handle();
413 Class::Handle(ResolveClass(cls, unresolved_class)); 358 Library& lib = Library::Handle();
414 359 if (unresolved_class.qualifier() == String::null()) {
360 lib = cls.library();
361 } else {
362 const String& qualifier = String::Handle(unresolved_class.qualifier());
363 LibraryPrefix& lib_prefix = LibraryPrefix::Handle();
364 lib_prefix = cls.LookupLibraryPrefix(qualifier);
365 if (lib_prefix.IsNull()) {
366 const Script& script = Script::Handle(cls.script());
367 ReportError(script, unresolved_class.token_index(),
368 "cannot resolve name '%s'\n",
369 String::Handle(unresolved_class.Name()).ToCString());
370 }
371 lib = lib_prefix.library();
372 }
373 ASSERT(!lib.IsNull());
374 type_class = lib.LookupClass(type_class_name);
375 if (type_class.IsNull()) {
376 const Script& script = Script::Handle(cls.script());
377 ReportError(script, unresolved_class.token_index(),
378 "cannot resolve class name '%s' from '%s'\n",
379 String::Handle(unresolved_class.Name()).ToCString(),
380 String::Handle(cls.Name()).ToCString());
381 }
415 // Replace unresolved class with resolved type class. 382 // Replace unresolved class with resolved type class.
416 ASSERT(type.IsParameterizedType()); 383 ASSERT(type.IsParameterizedType());
417 ParameterizedType& parameterized_type = ParameterizedType::Handle(); 384 ParameterizedType& parameterized_type = ParameterizedType::Handle();
418 parameterized_type ^= type.raw(); 385 parameterized_type ^= type.raw();
419 parameterized_type.set_type_class(Object::Handle(type_class.raw())); 386 parameterized_type.set_type_class(Object::Handle(type_class.raw()));
420 } 387 }
421 388
422 // Resolve type arguments, if any. 389 // Resolve type arguments, if any.
423 const TypeArguments& arguments = TypeArguments::Handle(type.arguments()); 390 const TypeArguments& arguments = TypeArguments::Handle(type.arguments());
424 if (!arguments.IsNull()) { 391 if (!arguments.IsNull()) {
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after
532 if (!arguments.IsNull()) { 499 if (!arguments.IsNull()) {
533 intptr_t num_arguments = arguments.Length(); 500 intptr_t num_arguments = arguments.Length();
534 for (intptr_t i = 0; i < num_arguments; i++) { 501 for (intptr_t i = 0; i < num_arguments; i++) {
535 Type& type_argument = Type::Handle(arguments.TypeAt(i)); 502 Type& type_argument = Type::Handle(arguments.TypeAt(i));
536 type_argument = FinalizeType(type_argument); 503 type_argument = FinalizeType(type_argument);
537 arguments.SetTypeAt(i, type_argument); 504 arguments.SetTypeAt(i, type_argument);
538 } 505 }
539 } 506 }
540 507
541 // The type class does not need to be finalized in order to finalize the type, 508 // The type class does not need to be finalized in order to finalize the type,
542 // however, it must at least be resolved (this was done as part of resolving 509 // however, it must at least be resolved. This was done as part of resolving
543 // the type itself, a precondition to calling FinalizeType) and the upper 510 // the type itself.
544 // bounds of its type parameters must be finalized (done here).
545 Class& type_class = Class::Handle(parameterized_type.type_class()); 511 Class& type_class = Class::Handle(parameterized_type.type_class());
546 512
547 // If the type class is a signature class, finalize it, thereby finalizing the
548 // result and parameter types of its signature function.
549 // Do this before marking this type as finalized in order to detect cycles.
550 if (type_class.IsSignatureClass()) {
551 FinalizeClass(type_class);
552 }
553
554 // The finalized type argument vector needs num_type_arguments types. 513 // The finalized type argument vector needs num_type_arguments types.
555 const intptr_t num_type_arguments = type_class.NumTypeArguments(); 514 const intptr_t num_type_arguments = type_class.NumTypeArguments();
556 // The type class has num_type_parameters type parameters. 515 // The type class has num_type_parameters type parameters.
557 const intptr_t num_type_parameters = type_class.NumTypeParameters(); 516 const intptr_t num_type_parameters = type_class.NumTypeParameters();
558 517
559 // Initialize the type argument vector. 518 // Initialize the type argument vector.
560 // Check the number of parsed type arguments, if any. 519 // Check the number of parsed type arguments, if any.
561 // Specifying no type arguments indicates a raw type, which is not an error. 520 // Specifying no type arguments indicates a raw type, which is not an error.
562 // However, subtyping constraints are checked below, even for a raw type. 521 // However, subtyping constraints are checked below, even for a raw type.
563 if (!arguments.IsNull() && (arguments.Length() != num_type_parameters)) { 522 if (!arguments.IsNull() && (arguments.Length() != num_type_parameters)) {
(...skipping 15 matching lines...) Expand all
579 // If no type parameters were provided, a raw type is desired, so we 538 // If no type parameters were provided, a raw type is desired, so we
580 // create a vector of DynamicType. 539 // create a vector of DynamicType.
581 if (!arguments.IsNull()) { 540 if (!arguments.IsNull()) {
582 type = arguments.TypeAt(i); 541 type = arguments.TypeAt(i);
583 } 542 }
584 full_arguments.SetTypeAt(offset + i, type); 543 full_arguments.SetTypeAt(offset + i, type);
585 } 544 }
586 FinalizeTypeArguments(type_class, full_arguments); 545 FinalizeTypeArguments(type_class, full_arguments);
587 parameterized_type.set_arguments(full_arguments); 546 parameterized_type.set_arguments(full_arguments);
588 } 547 }
589 // Mark the type as finalized before finalizing the upper bounds, because 548
590 // cycles via upper bounds are legal at compile time. 549 // If the type is a function type, finalize the result and parameter types.
550 if (type_class.IsSignatureClass()) {
551 ResolveAndFinalizeSignature(
552 type_class, Function::Handle(type_class.signature_function()));
553 }
554
591 parameterized_type.set_is_finalized(); 555 parameterized_type.set_is_finalized();
592 ResolveAndFinalizeUpperBounds(type_class);
593
594 return parameterized_type.Canonicalize(); 556 return parameterized_type.Canonicalize();
595 } 557 }
596 558
597 559
598 RawType* ClassFinalizer::FinalizeAndCanonicalizeType(const Type& type, 560 RawType* ClassFinalizer::FinalizeAndCanonicalizeType(const Type& type,
599 String* errmsg) { 561 String* errmsg) {
600 Isolate* isolate = Isolate::Current(); 562 Isolate* isolate = Isolate::Current();
601 ASSERT(isolate != NULL); 563 ASSERT(isolate != NULL);
602 LongJump* base = isolate->long_jump_base(); 564 LongJump* base = isolate->long_jump_base();
603 LongJump jump; 565 LongJump jump;
604 isolate->set_long_jump_base(&jump); 566 isolate->set_long_jump_base(&jump);
605 if (setjmp(*jump.Set()) == 0) { 567 if (setjmp(*jump.Set()) == 0) {
606 Type& canonical_type = Type::Handle(); 568 const Type& canonical_type = Type::Handle(FinalizeType(type));
607 if (type.IsSignatureType() && !AllClassesFinalized()) {
608 // Postpone the finalization of this signature type and class.
609 GrowableArray<const Class*> classes;
610 classes.Add(&Class::ZoneHandle(type.type_class()));
611 ClassFinalizer::AddClassesToFinalize(classes);
612 } else {
613 canonical_type = FinalizeType(type);
614 }
615 isolate->set_long_jump_base(base); 569 isolate->set_long_jump_base(base);
616 *errmsg = String::null(); 570 *errmsg = String::null();
617 return canonical_type.raw(); 571 return canonical_type.raw();
618 } else { 572 } else {
619 // Error occured: Get the error message. 573 // Error occured: Get the error message.
620 isolate->set_long_jump_base(base); 574 isolate->set_long_jump_base(base);
621 *errmsg = isolate->object_store()->sticky_error(); 575 *errmsg = isolate->object_store()->sticky_error();
622 return type.raw(); 576 return type.raw();
623 } 577 }
624 UNREACHABLE(); 578 UNREACHABLE();
625 return Type::null(); 579 return Type::null();
626 } 580 }
627 581
628 582
583 // Top level function signatures are canonicalized, added to the library class
584 // dictionary, and finalized with other library classes and interfaces.
585 // Function signatures used as type of a local variable or of a local function
586 // are canonicalized and finalized upon creation, since all the types they
587 // reference are already resolved.
629 void ClassFinalizer::ResolveAndFinalizeSignature(const Class& cls, 588 void ClassFinalizer::ResolveAndFinalizeSignature(const Class& cls,
630 const Function& function) { 589 const Function& function) {
631 // Resolve result type. 590 // Resolve result type.
632 Type& type = Type::Handle(function.result_type()); 591 Type& type = Type::Handle(function.result_type());
633 type = ResolveType(cls, type); 592 type = ResolveType(cls, type);
634 function.set_result_type(type); 593 function.set_result_type(type);
635 type = FinalizeType(type); 594 type = FinalizeType(type);
636 function.set_result_type(type); 595 function.set_result_type(type);
637 // Resolve formal parameter types. 596 // Resolve formal parameter types.
638 const intptr_t num_parameters = function.NumberOfParameters(); 597 const intptr_t num_parameters = function.NumberOfParameters();
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
678 function = super_class.LookupFunction(name); 637 function = super_class.LookupFunction(name);
679 if (!function.IsNull()) { 638 if (!function.IsNull()) {
680 return super_class.raw(); 639 return super_class.raw();
681 } 640 }
682 super_class = super_class.SuperClass(); 641 super_class = super_class.SuperClass();
683 } 642 }
684 return Class::null(); 643 return Class::null();
685 } 644 }
686 645
687 646
688 void ClassFinalizer::ResolveAndFinalizeUpperBounds(const Class& cls) {
689 const intptr_t num_type_params = cls.NumTypeParameters();
690 Type& type_extends = Type::Handle();
691 const TypeArguments& extends_array =
692 TypeArguments::Handle(cls.type_parameter_extends());
693 ASSERT((extends_array.IsNull() && (num_type_params == 0)) ||
694 (extends_array.Length() == num_type_params));
695 for (intptr_t i = 0; i < num_type_params; i++) {
696 type_extends = extends_array.TypeAt(i);
697 type_extends = ResolveType(cls, type_extends);
698 extends_array.SetTypeAt(i, type_extends);
699 type_extends = FinalizeType(type_extends);
700 extends_array.SetTypeAt(i, type_extends);
701 }
702 }
703
704
705 void ClassFinalizer::ResolveAndFinalizeMemberTypes(const Class& cls) { 647 void ClassFinalizer::ResolveAndFinalizeMemberTypes(const Class& cls) {
706 // Note that getters and setters are explicitly listed as such in the list of 648 // Note that getters and setters are explicitly listed as such in the list of
707 // functions of a class, so we do not need to consider fields as implicitly 649 // functions of a class, so we do not need to consider fields as implicitly
708 // generating getters and setters. 650 // generating getters and setters.
709 // The only compile errors we report are therefore: 651 // The only compile errors we report are therefore:
710 // - a getter having the same name as a method (but not a getter) in a super 652 // - a getter having the same name as a method (but not a getter) in a super
711 // class or in a subclass. 653 // class or in a subclass.
712 // - a setter having the same name as a method (but not a setter) in a super 654 // - a setter having the same name as a method (but not a setter) in a super
713 // class or in a subclass. 655 // class or in a subclass.
714 // - a static field, instance field, or static method (but not an instance 656 // - a static field, instance field, or static method (but not an instance
(...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after
828 const String& super_class_name = String::Handle(super_class.Name()); 770 const String& super_class_name = String::Handle(super_class.Name());
829 ReportError("function '%s' of class '%s' conflicts with " 771 ReportError("function '%s' of class '%s' conflicts with "
830 "setter '%s' of super class '%s'.\n", 772 "setter '%s' of super class '%s'.\n",
831 function_name.ToCString(), 773 function_name.ToCString(),
832 class_name.ToCString(), 774 class_name.ToCString(),
833 function_name.ToCString(), 775 function_name.ToCString(),
834 super_class_name.ToCString()); 776 super_class_name.ToCString());
835 } 777 }
836 } 778 }
837 } 779 }
780 // Resolve the signature type if this class is a signature class.
781 if (cls.IsSignatureClass()) {
782 Type& signature_type = Type::Handle(cls.SignatureType());
783 signature_type = FinalizeType(signature_type);
784 // Signature types are canonicalized by default.
785 ASSERT(signature_type.raw() == cls.SignatureType());
786 }
838 } 787 }
839 788
840 789
841 void ClassFinalizer::FinalizeClass(const Class& cls) { 790 void ClassFinalizer::FinalizeClass(const Class& cls) {
842 if (cls.is_finalized()) { 791 if (cls.is_finalized()) {
843 return; 792 return;
844 } 793 }
845 if (FLAG_trace_class_finalization) { 794 if (FLAG_trace_class_finalization) {
846 OS::Print("Finalize %s\n", cls.ToCString()); 795 OS::Print("Finalize %s\n", cls.ToCString());
847 } 796 }
(...skipping 29 matching lines...) Expand all
877 } 826 }
878 } 827 }
879 // Finalize interface types (but not necessarily interface classes). 828 // Finalize interface types (but not necessarily interface classes).
880 Array& interface_types = Array::Handle(cls.interfaces()); 829 Array& interface_types = Array::Handle(cls.interfaces());
881 Type& interface_type = Type::Handle(); 830 Type& interface_type = Type::Handle();
882 for (intptr_t i = 0; i < interface_types.Length(); i++) { 831 for (intptr_t i = 0; i < interface_types.Length(); i++) {
883 interface_type ^= interface_types.At(i); 832 interface_type ^= interface_types.At(i);
884 interface_type = FinalizeType(interface_type); 833 interface_type = FinalizeType(interface_type);
885 interface_types.SetAt(i, interface_type); 834 interface_types.SetAt(i, interface_type);
886 } 835 }
887 // Mark as finalized before resolving type parameter upper bounds and member 836 // Mark as finalized before resolving member types in order to break cycles.
888 // types in order to break cycles.
889 cls.Finalize(); 837 cls.Finalize();
890 ResolveAndFinalizeUpperBounds(cls);
891 ResolveAndFinalizeMemberTypes(cls); 838 ResolveAndFinalizeMemberTypes(cls);
892
893 if (cls.IsSignatureClass()) {
894 // Finalize the signature type of this signature class.
895 Type& signature_type = Type::Handle(cls.SignatureType());
896 signature_type = FinalizeType(signature_type);
897 // Signature types are canonicalized by default.
898 ASSERT(signature_type.raw() == cls.SignatureType());
899
900 // Resolve and finalize the result and parameter types of the signature
901 // function of this signature class.
902 ResolveAndFinalizeSignature(cls,
903 Function::Handle(cls.signature_function()));
904 }
905
906 // Run additional checks after all types are finalized. 839 // Run additional checks after all types are finalized.
907 if (cls.is_const()) { 840 if (cls.is_const()) {
908 CheckForLegalConstClass(cls); 841 CheckForLegalConstClass(cls);
909 } 842 }
910 } 843 }
911 844
912 845
913 bool ClassFinalizer::IsSuperCycleFree(const Class& cls) { 846 bool ClassFinalizer::IsSuperCycleFree(const Class& cls) {
914 Class& test1 = Class::Handle(cls.raw()); 847 Class& test1 = Class::Handle(cls.raw());
915 Class& test2 = Class::Handle(cls.SuperClass()); 848 Class& test2 = Class::Handle(cls.SuperClass());
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after
1024 interface.IsNumberInterface() || 957 interface.IsNumberInterface() ||
1025 interface.IsIntInterface() || 958 interface.IsIntInterface() ||
1026 interface.IsDoubleInterface() || 959 interface.IsDoubleInterface() ||
1027 interface.IsStringInterface() || 960 interface.IsStringInterface() ||
1028 (interface.IsFunctionInterface() && !cls.IsSignatureClass()) || 961 (interface.IsFunctionInterface() && !cls.IsSignatureClass()) ||
1029 interface.IsDynamicType()) { 962 interface.IsDynamicType()) {
1030 ReportError("'%s' is not allowed to extend or implement '%s'\n", 963 ReportError("'%s' is not allowed to extend or implement '%s'\n",
1031 String::Handle(cls.Name()).ToCString(), 964 String::Handle(cls.Name()).ToCString(),
1032 String::Handle(interface_class.Name()).ToCString()); 965 String::Handle(interface_class.Name()).ToCString());
1033 } 966 }
967 // TODO(regis): We also need to prevent extending classes Smi, Mint,
968 // BigInt, Double, OneByteString, TwoByteString, FourByteString.
1034 } 969 }
1035 // Now resolve the super interfaces. 970 // Now resolve the super interfaces.
1036 ResolveInterfaces(interface_class, visited); 971 ResolveInterfaces(interface_class, visited);
1037 } 972 }
1038 visited->RemoveLast(); 973 visited->RemoveLast();
1039 } 974 }
1040 975
1041 976
1042 // A class is marked as constant if it has one constant constructor. 977 // A class is marked as constant if it has one constant constructor.
1043 // A constant class: 978 // A constant class:
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after
1149 ASSERT(msg_buffer != NULL); 1084 ASSERT(msg_buffer != NULL);
1150 va_list args; 1085 va_list args;
1151 va_start(args, format); 1086 va_start(args, format);
1152 OS::VSNPrint(msg_buffer, kBufferLength, format, args); 1087 OS::VSNPrint(msg_buffer, kBufferLength, format, args);
1153 va_end(args); 1088 va_end(args);
1154 isolate->long_jump_base()->Jump(1, msg_buffer); 1089 isolate->long_jump_base()->Jump(1, msg_buffer);
1155 UNREACHABLE(); 1090 UNREACHABLE();
1156 } 1091 }
1157 1092
1158 } // namespace dart 1093 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/class_finalizer.h ('k') | runtime/vm/class_finalizer_test.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698