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

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

Issue 8491055: Second attempt at finalizing all classes in the VM (fix issue 364). (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/code_generator.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, trace_type_finalization, false, "Trace type finalization.");
17 DEFINE_FLAG(bool, verify_implements, false, 18 DEFINE_FLAG(bool, verify_implements, false,
18 "Verify that all classes implement their interface."); 19 "Verify that all classes implement their interface.");
19 DECLARE_FLAG(bool, enable_type_checks); 20 DECLARE_FLAG(bool, enable_type_checks);
20 21
21 void ClassFinalizer::AddPendingClasses( 22 void ClassFinalizer::AddPendingClasses(
22 const GrowableArray<const Class*>& classes) { 23 const GrowableArray<const Class*>& classes) {
23 if (!classes.is_empty()) { 24 if (!classes.is_empty()) {
24 ObjectStore* object_store = Isolate::Current()->object_store(); 25 ObjectStore* object_store = Isolate::Current()->object_store();
25 const Array& old_array = Array::Handle(object_store->pending_classes()); 26 const Array& old_array = Array::Handle(object_store->pending_classes());
26 const intptr_t old_length = old_array.Length(); 27 const intptr_t old_length = old_array.Length();
(...skipping 208 matching lines...) Expand 10 before | Expand all | Expand 10 after
235 OS::PrintErr("Could not verify bootstrap classes : %s\n", err.ToCString()); 236 OS::PrintErr("Could not verify bootstrap classes : %s\n", err.ToCString());
236 OS::Exit(255); 237 OS::Exit(255);
237 } 238 }
238 if (FLAG_trace_class_finalization) { 239 if (FLAG_trace_class_finalization) {
239 OS::Print("VerifyBootstrapClasses END.\n"); 240 OS::Print("VerifyBootstrapClasses END.\n");
240 } 241 }
241 Isolate::Current()->heap()->Verify(); 242 Isolate::Current()->heap()->Verify();
242 } 243 }
243 244
244 245
246 // Resolve unresolved_class in the library of cls.
247 RawClass* ClassFinalizer::ResolveClass(
248 const Class& cls, const UnresolvedClass& unresolved_class) {
249 Library& lib = Library::Handle();
250 if (unresolved_class.qualifier() == String::null()) {
251 lib = cls.library();
252 } else {
253 const String& qualifier = String::Handle(unresolved_class.qualifier());
254 LibraryPrefix& lib_prefix = LibraryPrefix::Handle();
255 lib_prefix = cls.LookupLibraryPrefix(qualifier);
256 if (lib_prefix.IsNull()) {
257 const Script& script = Script::Handle(cls.script());
258 ReportError(script, unresolved_class.token_index(),
259 "cannot resolve library prefix '%s' from '%s'.\n",
260 String::Handle(unresolved_class.Name()).ToCString(),
261 String::Handle(cls.Name()).ToCString());
262 }
263 lib = lib_prefix.library();
264 }
265 ASSERT(!lib.IsNull());
266 const String& class_name = String::Handle(unresolved_class.ident());
267 const Class& resolved_class = Class::Handle(lib.LookupClass(class_name));
268 if (resolved_class.IsNull()) {
269 const Script& script = Script::Handle(cls.script());
270 ReportError(script, unresolved_class.token_index(),
271 "cannot resolve class name '%s' from '%s'.\n",
272 String::Handle(unresolved_class.Name()).ToCString(),
273 String::Handle(cls.Name()).ToCString());
274 }
275 return resolved_class.raw();
276 }
277
278
245 // Resolve unresolved superclasses (String -> Class). 279 // Resolve unresolved superclasses (String -> Class).
246 void ClassFinalizer::ResolveSuperClass(const Class& cls) { 280 void ClassFinalizer::ResolveSuperClass(const Class& cls) {
247 if (cls.is_finalized()) { 281 if (cls.is_finalized()) {
248 return; 282 return;
249 } 283 }
250 Type& super_type = Type::Handle(cls.super_type()); 284 Type& super_type = Type::Handle(cls.super_type());
251 if (super_type.IsNull()) { 285 if (super_type.IsNull()) {
252 return; 286 return;
253 } 287 }
254 // Resolve failures lead to a longjmp. 288 // Resolve failures lead to a longjmp.
255 super_type = ResolveType(cls, super_type); 289 super_type = ResolveType(cls, super_type);
290 if (super_type.IsTypeParameter()) {
291 String& class_name = String::Handle(cls.Name());
292 String& type_parameter_name = String::Handle(super_type.Name());
293 ReportError("'%s' cannot extend or implement type parameter '%s'.\n",
294 class_name.ToCString(),
295 type_parameter_name.ToCString());
296 }
256 cls.set_super_type(super_type); 297 cls.set_super_type(super_type);
257 const Class& super_class = Class::Handle(super_type.type_class()); 298 const Class& super_class = Class::Handle(super_type.type_class());
258 if (cls.is_interface() != super_class.is_interface()) { 299 if (cls.is_interface() != super_class.is_interface()) {
259 String& class_name = String::Handle(cls.Name()); 300 String& class_name = String::Handle(cls.Name());
260 String& super_class_name = String::Handle(super_class.Name()); 301 String& super_class_name = String::Handle(super_class.Name());
261 ReportError("class '%s' and superclass '%s' are not " 302 ReportError("class '%s' and superclass '%s' are not "
262 "both classes or both interfaces.\n", 303 "both classes or both interfaces.\n",
263 class_name.ToCString(), 304 class_name.ToCString(),
264 super_class_name.ToCString()); 305 super_class_name.ToCString());
265 } 306 }
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
319 ReportError("default clause of interface '%s' does not name a class\n", 360 ReportError("default clause of interface '%s' does not name a class\n",
320 interface_name.ToCString()); 361 interface_name.ToCString());
321 } 362 }
322 } 363 }
323 364
324 365
325 RawType* ClassFinalizer::ResolveType(const Class& cls, const Type& type) { 366 RawType* ClassFinalizer::ResolveType(const Class& cls, const Type& type) {
326 if (type.IsResolved()) { 367 if (type.IsResolved()) {
327 return type.raw(); 368 return type.raw();
328 } 369 }
370 if (FLAG_trace_type_finalization) {
371 OS::Print("Resolve type '%s'\n", String::Handle(type.Name()).ToCString());
372 }
329 373
330 // Resolve the type class. 374 // Resolve the type class.
331 if (!type.HasResolvedTypeClass()) { 375 if (!type.HasResolvedTypeClass()) {
332 const UnresolvedClass& unresolved_class = 376 const UnresolvedClass& unresolved_class =
333 UnresolvedClass::Handle(type.unresolved_class()); 377 UnresolvedClass::Handle(type.unresolved_class());
334 const String& type_class_name = String::Handle(unresolved_class.ident()); 378 const String& type_class_name = String::Handle(unresolved_class.ident());
335 379
336 // The type class name may be a type parameter of cls that was not resolved 380 // The type class name may be a type parameter of cls that was not resolved
337 // by the parser because it appeared as part of the declaration 381 // by the parser because it appeared as part of the declaration
338 // as T1 in B<T1, T2 extends A<T1>> or 382 // as T1 in B<T1, T2 extends A<T1>> or
339 // as T2 in B<T1 extends A<T2>, T2>>. 383 // as T2 in B<T1 extends A<T2>, T2>>.
340 const TypeParameter& type_parameter = TypeParameter::Handle( 384 const TypeParameter& type_parameter = TypeParameter::Handle(
341 cls.LookupTypeParameter(type_class_name)); 385 cls.LookupTypeParameter(type_class_name));
342 if (!type_parameter.IsNull()) { 386 if (!type_parameter.IsNull()) {
343 // No need to check for proper instance scoping, since another type 387 // No need to check for proper instance scoping, since another type
344 // parameter must be involved for the type to still be unresolved. 388 // parameter must be involved for the type to still be unresolved.
345 // The scope checking was performed for the other type parameter already. 389 // The scope checking was performed for the other type parameter already.
346 390
347 // A type parameter cannot be parameterized, so report an error if type 391 // A type parameter cannot be parameterized, so report an error if type
348 // arguments have previously been parsed. 392 // arguments have previously been parsed.
349 if (type.arguments() != TypeArguments::null()) { 393 if (type.arguments() != TypeArguments::null()) {
350 ReportError("type parameter '%s' cannot be parameterized", 394 ReportError("type parameter '%s' cannot be parameterized",
351 type_class_name.ToCString()); 395 type_class_name.ToCString());
352 } 396 }
353 return type_parameter.raw(); 397 return type_parameter.raw();
354 } 398 }
355 399
356 // Lookup the type class. 400 // Lookup the type class.
357 Class& type_class = Class::Handle(); 401 const Class& type_class =
358 Library& lib = Library::Handle(); 402 Class::Handle(ResolveClass(cls, unresolved_class));
359 if (unresolved_class.qualifier() == String::null()) { 403
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 }
382 // Replace unresolved class with resolved type class. 404 // Replace unresolved class with resolved type class.
383 ASSERT(type.IsParameterizedType()); 405 ASSERT(type.IsParameterizedType());
384 ParameterizedType& parameterized_type = ParameterizedType::Handle(); 406 ParameterizedType& parameterized_type = ParameterizedType::Handle();
385 parameterized_type ^= type.raw(); 407 parameterized_type ^= type.raw();
386 parameterized_type.set_type_class(Object::Handle(type_class.raw())); 408 parameterized_type.set_type_class(Object::Handle(type_class.raw()));
387 } 409 }
388 410
389 // Resolve type arguments, if any. 411 // Resolve type arguments, if any.
390 const TypeArguments& arguments = TypeArguments::Handle(type.arguments()); 412 const TypeArguments& arguments = TypeArguments::Handle(type.arguments());
391 if (!arguments.IsNull()) { 413 if (!arguments.IsNull()) {
(...skipping 19 matching lines...) Expand all
411 // Example: 433 // Example:
412 // Declared: class C<K, V> extends B<V> { ... } 434 // Declared: class C<K, V> extends B<V> { ... }
413 // class B<T> extends Array<int> { ... } 435 // class B<T> extends Array<int> { ... }
414 // Input: C<String, double> expressed as 436 // Input: C<String, double> expressed as
415 // cls = C, arguments = [null, null, String, double], 437 // cls = C, arguments = [null, null, String, double],
416 // i.e. cls_args = [String, double], offset = 2, length = 2. 438 // i.e. cls_args = [String, double], offset = 2, length = 2.
417 // Output: arguments = [int, double, String, double] 439 // Output: arguments = [int, double, String, double]
418 void ClassFinalizer::FinalizeTypeArguments(const Class& cls, 440 void ClassFinalizer::FinalizeTypeArguments(const Class& cls,
419 const TypeArguments& arguments) { 441 const TypeArguments& arguments) {
420 ASSERT(arguments.Length() >= cls.NumTypeArguments()); 442 ASSERT(arguments.Length() >= cls.NumTypeArguments());
421 // If type checks are enabled, verify the subtyping constraints.
422 if (FLAG_enable_type_checks) {
423 const intptr_t num_type_params = cls.NumTypeParameters();
424 const intptr_t offset = cls.NumTypeArguments() - num_type_params;
425 Type& type = Type::Handle();
426 Type& type_extends = Type::Handle();
427 const TypeArguments& extends_array =
428 TypeArguments::Handle(cls.type_parameter_extends());
429 ASSERT((extends_array.IsNull() && (num_type_params == 0)) ||
430 (extends_array.Length() == num_type_params));
431 for (intptr_t i = 0; i < num_type_params; i++) {
432 type_extends = extends_array.TypeAt(i);
433 if (!type_extends.IsDynamicType()) {
434 type = arguments.TypeAt(offset + i);
435 if (type.IsInstantiated()) {
436 if (!type_extends.IsInstantiated()) {
437 type_extends = type_extends.InstantiateFrom(arguments, offset);
438 }
439 // TODO(regis): Where do we check the constraints when the type is
440 // generic?
441 if (!type.IsSubtypeOf(type_extends)) {
442 const String& type_name = String::Handle(type.Name());
443 const String& extends_name = String::Handle(type_extends.Name());
444 ReportError("type argument '%s' does not extend type '%s'\n",
445 type_name.ToCString(),
446 extends_name.ToCString());
447 }
448 }
449 }
450 }
451 }
452 Type& super_type = Type::Handle(cls.super_type()); 443 Type& super_type = Type::Handle(cls.super_type());
453 if (!super_type.IsNull()) { 444 if (!super_type.IsNull()) {
454 super_type = FinalizeType(super_type); 445 super_type = FinalizeType(super_type);
455 cls.set_super_type(super_type); 446 cls.set_super_type(super_type);
456 const Class& super_class = Class::Handle(super_type.type_class()); 447 const Class& super_class = Class::Handle(super_type.type_class());
457 const TypeArguments& super_type_args = 448 const TypeArguments& super_type_args =
458 TypeArguments::Handle(super_type.arguments()); 449 TypeArguments::Handle(super_type.arguments());
459 const intptr_t num_super_type_params = super_class.NumTypeParameters(); 450 const intptr_t num_super_type_params = super_class.NumTypeParameters();
460 const intptr_t offset = super_class.NumTypeArguments(); 451 const intptr_t offset = super_class.NumTypeArguments();
461 const intptr_t super_offset = offset - num_super_type_params; 452 const intptr_t super_offset = offset - num_super_type_params;
462 ASSERT(offset == (cls.NumTypeArguments() - cls.NumTypeParameters())); 453 ASSERT(offset == (cls.NumTypeArguments() - cls.NumTypeParameters()));
463 Type& super_type_arg = Type::Handle(); 454 Type& super_type_arg = Type::Handle();
464 for (intptr_t i = 0; i < num_super_type_params; i++) { 455 for (intptr_t i = 0; i < num_super_type_params; i++) {
465 super_type_arg = super_type_args.TypeAt(super_offset + i); 456 super_type_arg = super_type_args.TypeAt(super_offset + i);
466 if (!super_type_arg.IsInstantiated()) { 457 if (!super_type_arg.IsInstantiated()) {
467 super_type_arg = super_type_arg.InstantiateFrom(arguments, offset); 458 super_type_arg = super_type_arg.InstantiateFrom(arguments, offset);
468 } 459 }
469 super_type_arg = super_type_arg.Canonicalize(); 460 super_type_arg = super_type_arg.Canonicalize();
470 arguments.SetTypeAt(super_offset + i, super_type_arg); 461 arguments.SetTypeAt(super_offset + i, super_type_arg);
471 } 462 }
472 FinalizeTypeArguments(super_class, arguments); 463 FinalizeTypeArguments(super_class, arguments);
473 } 464 }
474 } 465 }
475 466
476 467
468 // Verify the upper bounds of the type arguments of class cls.
469 void ClassFinalizer::VerifyUpperBounds(const Class& cls,
470 const TypeArguments& arguments) {
471 ASSERT(FLAG_enable_type_checks);
472 ASSERT(arguments.Length() >= cls.NumTypeArguments());
473 const intptr_t num_type_params = cls.NumTypeParameters();
474 const intptr_t offset = cls.NumTypeArguments() - num_type_params;
475 Type& type = Type::Handle();
476 Type& type_extends = Type::Handle();
477 const TypeArguments& extends_array =
478 TypeArguments::Handle(cls.type_parameter_extends());
479 ASSERT((extends_array.IsNull() && (num_type_params == 0)) ||
480 (extends_array.Length() == num_type_params));
481 for (intptr_t i = 0; i < num_type_params; i++) {
482 type_extends = extends_array.TypeAt(i);
483 if (!type_extends.IsDynamicType()) {
484 type = arguments.TypeAt(offset + i);
485 if (type.IsInstantiated()) {
486 if (!type_extends.IsInstantiated()) {
487 type_extends = type_extends.InstantiateFrom(arguments, offset);
488 }
489 // TODO(regis): Where do we check the constraints when the type is
490 // generic?
491 if (!type.IsSubtypeOf(type_extends)) {
492 const String& type_name = String::Handle(type.Name());
493 const String& extends_name = String::Handle(type_extends.Name());
494 ReportError("type argument '%s' of class '%s' "
495 "does not extend type '%s'\n",
496 type_name.ToCString(),
497 extends_name.ToCString());
498 }
499 }
500 }
501 }
502 Type& super_type = Type::Handle(cls.super_type());
503 if (!super_type.IsNull()) {
504 ASSERT(super_type.IsFinalized());
505 const Class& super_class = Class::Handle(super_type.type_class());
506 VerifyUpperBounds(super_class, arguments);
507 }
508 }
509
510
477 RawType* ClassFinalizer::FinalizeType(const Type& type) { 511 RawType* ClassFinalizer::FinalizeType(const Type& type) {
478 ASSERT(type.IsResolved()); 512 ASSERT(type.IsResolved());
479 if (type.IsFinalized()) { 513 if (type.IsFinalized()) {
480 return type.raw(); 514 return type.raw();
481 } 515 }
516 if (FLAG_trace_type_finalization) {
517 OS::Print("Finalize type '%s'\n", String::Handle(type.Name()).ToCString());
518 }
482 519
483 // At this point, we can only have a parameterized_type. 520 // At this point, we can only have a parameterized_type.
484 ParameterizedType& parameterized_type = ParameterizedType::Handle(); 521 ParameterizedType& parameterized_type = ParameterizedType::Handle();
485 parameterized_type ^= type.raw(); 522 parameterized_type ^= type.raw();
486 523
487 if (parameterized_type.IsBeingFinalized()) { 524 if (parameterized_type.IsBeingFinalized()) {
488 ReportError("type '%s' illegally refers to itself\n", 525 ReportError("type '%s' illegally refers to itself\n",
489 String::Handle(parameterized_type.Name()).ToCString()); 526 String::Handle(parameterized_type.Name()).ToCString());
490 } 527 }
491 528
492 // Mark type as being finalized in order to detect illegal self reference. 529 // Mark type as being finalized in order to detect illegal self reference.
493 parameterized_type.set_is_being_finalized(); 530 parameterized_type.set_is_being_finalized();
494 531
495 // Finalize the current type arguments of the type, which are still the 532 // Finalize the current type arguments of the type, which are still the
496 // parsed type arguments. 533 // parsed type arguments.
497 TypeArguments& arguments = 534 TypeArguments& arguments =
498 TypeArguments::Handle(parameterized_type.arguments()); 535 TypeArguments::Handle(parameterized_type.arguments());
499 if (!arguments.IsNull()) { 536 if (!arguments.IsNull()) {
500 intptr_t num_arguments = arguments.Length(); 537 intptr_t num_arguments = arguments.Length();
501 for (intptr_t i = 0; i < num_arguments; i++) { 538 for (intptr_t i = 0; i < num_arguments; i++) {
502 Type& type_argument = Type::Handle(arguments.TypeAt(i)); 539 Type& type_argument = Type::Handle(arguments.TypeAt(i));
503 type_argument = FinalizeType(type_argument); 540 type_argument = FinalizeType(type_argument);
504 arguments.SetTypeAt(i, type_argument); 541 arguments.SetTypeAt(i, type_argument);
505 } 542 }
506 } 543 }
507 544
508 // The type class does not need to be finalized in order to finalize the type, 545 // The type class does not need to be finalized in order to finalize the type,
509 // however, it must at least be resolved. This was done as part of resolving 546 // however, it must at least be resolved (this was done as part of resolving
510 // the type itself. 547 // the type itself, a precondition to calling FinalizeType) and the upper
548 // bounds of its type parameters must be finalized (done here).
511 Class& type_class = Class::Handle(parameterized_type.type_class()); 549 Class& type_class = Class::Handle(parameterized_type.type_class());
512 550
551 // If the type class is a signature class, we are finalizing its signature
552 // type, thereby finalizing the result type and parameter types of its
553 // signature function.
554 // Do this before marking this type as finalized in order to detect cycles.
555 if (type_class.IsSignatureClass()) {
556 // Signature classes are finalized upon creation.
557 ASSERT(type_class.is_finalized());
558 // Resolve and finalize the result and parameter types of the signature
559 // function of this signature class.
560 ResolveAndFinalizeSignature(
561 type_class, Function::Handle(type_class.signature_function()));
562 }
563
513 // The finalized type argument vector needs num_type_arguments types. 564 // The finalized type argument vector needs num_type_arguments types.
514 const intptr_t num_type_arguments = type_class.NumTypeArguments(); 565 const intptr_t num_type_arguments = type_class.NumTypeArguments();
515 // The type class has num_type_parameters type parameters. 566 // The type class has num_type_parameters type parameters.
516 const intptr_t num_type_parameters = type_class.NumTypeParameters(); 567 const intptr_t num_type_parameters = type_class.NumTypeParameters();
517 568
518 // Initialize the type argument vector. 569 // Initialize the type argument vector.
519 // Check the number of parsed type arguments, if any. 570 // Check the number of parsed type arguments, if any.
520 // Specifying no type arguments indicates a raw type, which is not an error. 571 // Specifying no type arguments indicates a raw type, which is not an error.
521 // However, subtyping constraints are checked below, even for a raw type. 572 // However, subtyping constraints are checked below, even for a raw type.
522 if (!arguments.IsNull() && (arguments.Length() != num_type_parameters)) { 573 if (!arguments.IsNull() && (arguments.Length() != num_type_parameters)) {
(...skipping 12 matching lines...) Expand all
535 const intptr_t offset = num_type_arguments - num_type_parameters; 586 const intptr_t offset = num_type_arguments - num_type_parameters;
536 Type& type = Type::Handle(Type::DynamicType()); 587 Type& type = Type::Handle(Type::DynamicType());
537 for (intptr_t i = 0; i < num_type_parameters; i++) { 588 for (intptr_t i = 0; i < num_type_parameters; i++) {
538 // If no type parameters were provided, a raw type is desired, so we 589 // If no type parameters were provided, a raw type is desired, so we
539 // create a vector of DynamicType. 590 // create a vector of DynamicType.
540 if (!arguments.IsNull()) { 591 if (!arguments.IsNull()) {
541 type = arguments.TypeAt(i); 592 type = arguments.TypeAt(i);
542 } 593 }
543 full_arguments.SetTypeAt(offset + i, type); 594 full_arguments.SetTypeAt(offset + i, type);
544 } 595 }
545 FinalizeTypeArguments(type_class, full_arguments); 596 if (type_class.IsSignatureClass()) {
597 const Function& signature_fun =
598 Function::Handle(type_class.signature_function());
599 ASSERT(!signature_fun.is_static());
600 const Class& signature_fun_owner = Class::Handle(signature_fun.owner());
601 FinalizeTypeArguments(signature_fun_owner, full_arguments);
602 } else {
603 FinalizeTypeArguments(type_class, full_arguments);
604 }
546 parameterized_type.set_arguments(full_arguments); 605 parameterized_type.set_arguments(full_arguments);
606
607 // Mark the type as finalized before finalizing the upper bounds, because
608 // cycles via upper bounds are legal at compile time.
609 parameterized_type.set_is_finalized();
610
611 ResolveAndFinalizeUpperBounds(type_class);
612 if (FLAG_enable_type_checks) {
613 VerifyUpperBounds(type_class, full_arguments);
614 }
615 } else {
616 parameterized_type.set_is_finalized();
547 } 617 }
548
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
555 parameterized_type.set_is_finalized();
556 return parameterized_type.Canonicalize(); 618 return parameterized_type.Canonicalize();
557 } 619 }
558 620
559 621
560 RawType* ClassFinalizer::FinalizeAndCanonicalizeType(const Type& type, 622 RawType* ClassFinalizer::FinalizeAndCanonicalizeType(const Type& type,
561 String* errmsg) { 623 String* errmsg) {
562 Isolate* isolate = Isolate::Current(); 624 Isolate* isolate = Isolate::Current();
563 ASSERT(isolate != NULL); 625 ASSERT(isolate != NULL);
564 LongJump* base = isolate->long_jump_base(); 626 LongJump* base = isolate->long_jump_base();
565 LongJump jump; 627 LongJump jump;
566 isolate->set_long_jump_base(&jump); 628 isolate->set_long_jump_base(&jump);
567 if (setjmp(*jump.Set()) == 0) { 629 if (setjmp(*jump.Set()) == 0) {
568 const Type& canonical_type = Type::Handle(FinalizeType(type)); 630 const Type& canonical_type = Type::Handle(FinalizeType(type));
569 isolate->set_long_jump_base(base); 631 isolate->set_long_jump_base(base);
570 *errmsg = String::null(); 632 *errmsg = String::null();
571 return canonical_type.raw(); 633 return canonical_type.raw();
572 } else { 634 } else {
573 // Error occured: Get the error message. 635 // Error occured: Get the error message.
574 isolate->set_long_jump_base(base); 636 isolate->set_long_jump_base(base);
575 *errmsg = isolate->object_store()->sticky_error(); 637 *errmsg = isolate->object_store()->sticky_error();
576 return type.raw(); 638 return type.raw();
577 } 639 }
578 UNREACHABLE(); 640 UNREACHABLE();
579 return Type::null(); 641 return Type::null();
580 } 642 }
581 643
582 644
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.
588 void ClassFinalizer::ResolveAndFinalizeSignature(const Class& cls, 645 void ClassFinalizer::ResolveAndFinalizeSignature(const Class& cls,
589 const Function& function) { 646 const Function& function) {
590 // Resolve result type. 647 // Resolve result type.
591 Type& type = Type::Handle(function.result_type()); 648 Type& type = Type::Handle(function.result_type());
592 type = ResolveType(cls, type); 649 type = ResolveType(cls, type);
593 function.set_result_type(type); 650 function.set_result_type(type);
594 type = FinalizeType(type); 651 type = FinalizeType(type);
595 function.set_result_type(type); 652 function.set_result_type(type);
596 // Resolve formal parameter types. 653 // Resolve formal parameter types.
597 const intptr_t num_parameters = function.NumberOfParameters(); 654 const intptr_t num_parameters = function.NumberOfParameters();
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
637 function = super_class.LookupFunction(name); 694 function = super_class.LookupFunction(name);
638 if (!function.IsNull()) { 695 if (!function.IsNull()) {
639 return super_class.raw(); 696 return super_class.raw();
640 } 697 }
641 super_class = super_class.SuperClass(); 698 super_class = super_class.SuperClass();
642 } 699 }
643 return Class::null(); 700 return Class::null();
644 } 701 }
645 702
646 703
704 // Resolve and finalize the upper bounds of the type parameters of class cls.
705 void ClassFinalizer::ResolveAndFinalizeUpperBounds(const Class& cls) {
706 const intptr_t num_type_params = cls.NumTypeParameters();
707 Type& type_extends = Type::Handle();
708 const TypeArguments& extends_array =
709 TypeArguments::Handle(cls.type_parameter_extends());
710 ASSERT((extends_array.IsNull() && (num_type_params == 0)) ||
711 (extends_array.Length() == num_type_params));
712 for (intptr_t i = 0; i < num_type_params; i++) {
713 type_extends = extends_array.TypeAt(i);
714 type_extends = ResolveType(cls, type_extends);
715 extends_array.SetTypeAt(i, type_extends);
716 type_extends = FinalizeType(type_extends);
717 extends_array.SetTypeAt(i, type_extends);
718 }
719 }
720
721
647 void ClassFinalizer::ResolveAndFinalizeMemberTypes(const Class& cls) { 722 void ClassFinalizer::ResolveAndFinalizeMemberTypes(const Class& cls) {
648 // Note that getters and setters are explicitly listed as such in the list of 723 // Note that getters and setters are explicitly listed as such in the list of
649 // functions of a class, so we do not need to consider fields as implicitly 724 // functions of a class, so we do not need to consider fields as implicitly
650 // generating getters and setters. 725 // generating getters and setters.
651 // The only compile errors we report are therefore: 726 // The only compile errors we report are therefore:
652 // - a getter having the same name as a method (but not a getter) in a super 727 // - a getter having the same name as a method (but not a getter) in a super
653 // class or in a subclass. 728 // class or in a subclass.
654 // - a setter having the same name as a method (but not a setter) in a super 729 // - a setter having the same name as a method (but not a setter) in a super
655 // class or in a subclass. 730 // class or in a subclass.
656 // - a static field, instance field, or static method (but not an instance 731 // - a static field, instance field, or static method (but not an instance
(...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after
770 const String& super_class_name = String::Handle(super_class.Name()); 845 const String& super_class_name = String::Handle(super_class.Name());
771 ReportError("function '%s' of class '%s' conflicts with " 846 ReportError("function '%s' of class '%s' conflicts with "
772 "setter '%s' of super class '%s'.\n", 847 "setter '%s' of super class '%s'.\n",
773 function_name.ToCString(), 848 function_name.ToCString(),
774 class_name.ToCString(), 849 class_name.ToCString(),
775 function_name.ToCString(), 850 function_name.ToCString(),
776 super_class_name.ToCString()); 851 super_class_name.ToCString());
777 } 852 }
778 } 853 }
779 } 854 }
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 }
787 } 855 }
788 856
789 857
790 void ClassFinalizer::FinalizeClass(const Class& cls) { 858 void ClassFinalizer::FinalizeClass(const Class& cls) {
791 if (cls.is_finalized()) { 859 if (cls.is_finalized()) {
792 return; 860 return;
793 } 861 }
794 if (FLAG_trace_class_finalization) { 862 if (FLAG_trace_class_finalization) {
795 OS::Print("Finalize %s\n", cls.ToCString()); 863 OS::Print("Finalize %s\n", cls.ToCString());
796 } 864 }
865 // Signature classes are finalized upon creation.
866 ASSERT(!cls.IsSignatureClass());
797 if (!IsSuperCycleFree(cls)) { 867 if (!IsSuperCycleFree(cls)) {
798 const String& name = String::Handle(cls.Name()); 868 const String& name = String::Handle(cls.Name());
799 ReportError("class '%s' has a cycle in its superclass relationship.\n", 869 ReportError("class '%s' has a cycle in its superclass relationship.\n",
800 name.ToCString()); 870 name.ToCString());
801 } 871 }
802 GrowableArray<const Class*> visited; 872 GrowableArray<const Class*> visited;
803 ResolveInterfaces(cls, &visited); 873 ResolveInterfaces(cls, &visited);
804 Type& super_type = Type::Handle(cls.super_type()); 874 Type& super_type = Type::Handle(cls.super_type());
805 if (!super_type.IsNull()) { 875 if (!super_type.IsNull()) {
806 const Class& super_class = Class::Handle(super_type.type_class()); 876 const Class& super_class = Class::Handle(super_type.type_class());
(...skipping 19 matching lines...) Expand all
826 } 896 }
827 } 897 }
828 // Finalize interface types (but not necessarily interface classes). 898 // Finalize interface types (but not necessarily interface classes).
829 Array& interface_types = Array::Handle(cls.interfaces()); 899 Array& interface_types = Array::Handle(cls.interfaces());
830 Type& interface_type = Type::Handle(); 900 Type& interface_type = Type::Handle();
831 for (intptr_t i = 0; i < interface_types.Length(); i++) { 901 for (intptr_t i = 0; i < interface_types.Length(); i++) {
832 interface_type ^= interface_types.At(i); 902 interface_type ^= interface_types.At(i);
833 interface_type = FinalizeType(interface_type); 903 interface_type = FinalizeType(interface_type);
834 interface_types.SetAt(i, interface_type); 904 interface_types.SetAt(i, interface_type);
835 } 905 }
836 // Mark as finalized before resolving member types in order to break cycles. 906 // Mark as finalized before resolving type parameter upper bounds and member
907 // types in order to break cycles.
837 cls.Finalize(); 908 cls.Finalize();
909 ResolveAndFinalizeUpperBounds(cls);
838 ResolveAndFinalizeMemberTypes(cls); 910 ResolveAndFinalizeMemberTypes(cls);
839 // Run additional checks after all types are finalized. 911 // Run additional checks after all types are finalized.
840 if (cls.is_const()) { 912 if (cls.is_const()) {
841 CheckForLegalConstClass(cls); 913 CheckForLegalConstClass(cls);
842 } 914 }
843 } 915 }
844 916
845 917
846 bool ClassFinalizer::IsSuperCycleFree(const Class& cls) { 918 bool ClassFinalizer::IsSuperCycleFree(const Class& cls) {
847 Class& test1 = Class::Handle(cls.raw()); 919 Class& test1 = Class::Handle(cls.raw());
(...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after
957 interface.IsNumberInterface() || 1029 interface.IsNumberInterface() ||
958 interface.IsIntInterface() || 1030 interface.IsIntInterface() ||
959 interface.IsDoubleInterface() || 1031 interface.IsDoubleInterface() ||
960 interface.IsStringInterface() || 1032 interface.IsStringInterface() ||
961 (interface.IsFunctionInterface() && !cls.IsSignatureClass()) || 1033 (interface.IsFunctionInterface() && !cls.IsSignatureClass()) ||
962 interface.IsDynamicType()) { 1034 interface.IsDynamicType()) {
963 ReportError("'%s' is not allowed to extend or implement '%s'\n", 1035 ReportError("'%s' is not allowed to extend or implement '%s'\n",
964 String::Handle(cls.Name()).ToCString(), 1036 String::Handle(cls.Name()).ToCString(),
965 String::Handle(interface_class.Name()).ToCString()); 1037 String::Handle(interface_class.Name()).ToCString());
966 } 1038 }
967 // TODO(regis): We also need to prevent extending classes Smi, Mint,
968 // BigInt, Double, OneByteString, TwoByteString, FourByteString.
969 } 1039 }
970 // Now resolve the super interfaces. 1040 // Now resolve the super interfaces.
971 ResolveInterfaces(interface_class, visited); 1041 ResolveInterfaces(interface_class, visited);
972 } 1042 }
973 visited->RemoveLast(); 1043 visited->RemoveLast();
974 } 1044 }
975 1045
976 1046
977 // A class is marked as constant if it has one constant constructor. 1047 // A class is marked as constant if it has one constant constructor.
978 // A constant class: 1048 // A constant class:
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after
1084 ASSERT(msg_buffer != NULL); 1154 ASSERT(msg_buffer != NULL);
1085 va_list args; 1155 va_list args;
1086 va_start(args, format); 1156 va_start(args, format);
1087 OS::VSNPrint(msg_buffer, kBufferLength, format, args); 1157 OS::VSNPrint(msg_buffer, kBufferLength, format, args);
1088 va_end(args); 1158 va_end(args);
1089 isolate->long_jump_base()->Jump(1, msg_buffer); 1159 isolate->long_jump_base()->Jump(1, msg_buffer);
1090 UNREACHABLE(); 1160 UNREACHABLE();
1091 } 1161 }
1092 1162
1093 } // namespace dart 1163 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/class_finalizer.h ('k') | runtime/vm/code_generator.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698