| 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 509 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 520 } | 520 } |
| 521 | 521 |
| 522 | 522 |
| 523 RawAbstractType* ClassFinalizer::FinalizeType(const Class& cls, | 523 RawAbstractType* ClassFinalizer::FinalizeType(const Class& cls, |
| 524 const AbstractType& type, | 524 const AbstractType& type, |
| 525 FinalizationKind finalization) { | 525 FinalizationKind finalization) { |
| 526 if (type.IsFinalized()) { | 526 if (type.IsFinalized()) { |
| 527 return type.raw(); | 527 return type.raw(); |
| 528 } | 528 } |
| 529 ASSERT(type.IsResolved()); | 529 ASSERT(type.IsResolved()); |
| 530 ASSERT((finalization == kFinalize) || (finalization == kFinalizeWellFormed)); |
| 530 | 531 |
| 531 if (FLAG_trace_type_finalization) { | 532 if (FLAG_trace_type_finalization) { |
| 532 OS::Print("Finalize type '%s'\n", String::Handle(type.Name()).ToCString()); | 533 OS::Print("Finalize type '%s'\n", String::Handle(type.Name()).ToCString()); |
| 533 } | 534 } |
| 534 | 535 |
| 535 if (type.IsTypeParameter()) { | 536 if (type.IsTypeParameter()) { |
| 536 ASSERT(!cls.IsNull()); | 537 ASSERT(!cls.IsNull()); |
| 537 TypeParameter& type_parameter = TypeParameter::Handle(); | 538 TypeParameter& type_parameter = TypeParameter::Handle(); |
| 538 type_parameter ^= type.raw(); | 539 type_parameter ^= type.raw(); |
| 539 // The index must reflect the position of this type parameter in the type | 540 // The index must reflect the position of this type parameter in the type |
| (...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 661 ResolveAndFinalizeUpperBounds(type_class); | 662 ResolveAndFinalizeUpperBounds(type_class); |
| 662 Error& malformed_error = Error::Handle(); | 663 Error& malformed_error = Error::Handle(); |
| 663 // Pass the full type argument vector as the bounds instantiator. | 664 // Pass the full type argument vector as the bounds instantiator. |
| 664 if (!full_arguments.IsWithinBoundsOf(type_class, | 665 if (!full_arguments.IsWithinBoundsOf(type_class, |
| 665 full_arguments, | 666 full_arguments, |
| 666 &malformed_error)) { | 667 &malformed_error)) { |
| 667 ASSERT(!malformed_error.IsNull()); | 668 ASSERT(!malformed_error.IsNull()); |
| 668 // The type argument vector of the type is not within bounds. The type | 669 // The type argument vector of the type is not within bounds. The type |
| 669 // is malformed. Prepend malformed_error to new malformed type error in | 670 // is malformed. Prepend malformed_error to new malformed type error in |
| 670 // order to report both locations. | 671 // order to report both locations. |
| 672 // Note that malformed bounds never result in a compile time error, even |
| 673 // in checked mode. Therefore, overwrite finalization with kFinalize |
| 674 // when finalizing the malformed type. |
| 671 FinalizeMalformedType( | 675 FinalizeMalformedType( |
| 672 malformed_error, | 676 malformed_error, |
| 673 cls, parameterized_type, finalization, | 677 cls, parameterized_type, kFinalize, |
| 674 "type arguments of type '%s' are not within bounds", | 678 "type arguments of type '%s' are not within bounds", |
| 675 String::Handle(parameterized_type.Name()).ToCString()); | 679 String::Handle(parameterized_type.Name()).ToCString()); |
| 676 return parameterized_type.raw(); | 680 return parameterized_type.raw(); |
| 677 } | 681 } |
| 678 } | 682 } |
| 679 } else { | 683 } else { |
| 680 parameterized_type.set_is_finalized(); | 684 parameterized_type.set_is_finalized(); |
| 681 } | 685 } |
| 682 return parameterized_type.Canonicalize(); | 686 return parameterized_type.Canonicalize(); |
| 683 } | 687 } |
| 684 | 688 |
| 685 | 689 |
| 686 void ClassFinalizer::ResolveAndFinalizeSignature(const Class& cls, | 690 void ClassFinalizer::ResolveAndFinalizeSignature(const Class& cls, |
| 687 const Function& function) { | 691 const Function& function) { |
| 688 // Resolve result type. | 692 // Resolve result type. |
| 689 AbstractType& type = AbstractType::Handle(function.result_type()); | 693 AbstractType& type = AbstractType::Handle(function.result_type()); |
| 690 FinalizationKind result_finalization = kFinalize; | 694 FinalizationKind result_finalization = kFinalize; |
| 691 if (function.IsFactory()) { | 695 if (function.IsFactory()) { |
| 692 // The name of a factory must always be resolved to a class or interface. | 696 // The name of a factory must always be resolved to a class or interface. |
| 693 // The parser sets the factory result type to a type with an unresolved | 697 // The parser sets the factory result type to a type with an unresolved |
| 694 // class whose name matches the factory name. | 698 // class whose name matches the factory name. |
| 695 result_finalization = kFinalizeWellFormed; | 699 result_finalization = kFinalizeWellFormed; |
| 700 // TODO(regis): Gilad asks if this compile-time error could be relaxed. |
| 701 // The result type of such a factory method would simply be malformed. |
| 696 } | 702 } |
| 697 ResolveType(cls, type, result_finalization); | 703 ResolveType(cls, type, result_finalization); |
| 698 type = FinalizeType(cls, type, result_finalization); | 704 type = FinalizeType(cls, type, result_finalization); |
| 699 function.set_result_type(type); | 705 function.set_result_type(type); |
| 700 // Resolve formal parameter types. | 706 // Resolve formal parameter types. |
| 701 const intptr_t num_parameters = function.NumberOfParameters(); | 707 const intptr_t num_parameters = function.NumberOfParameters(); |
| 702 for (intptr_t i = 0; i < num_parameters; i++) { | 708 for (intptr_t i = 0; i < num_parameters; i++) { |
| 703 type = function.ParameterTypeAt(i); | 709 type = function.ParameterTypeAt(i); |
| 704 ResolveType(cls, type, kFinalize); | 710 ResolveType(cls, type, kFinalize); |
| 705 type = FinalizeType(cls, type, kFinalize); | 711 type = FinalizeType(cls, type, kFinalize); |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 750 // Resolve and finalize the upper bounds of the type parameters of class cls. | 756 // Resolve and finalize the upper bounds of the type parameters of class cls. |
| 751 void ClassFinalizer::ResolveAndFinalizeUpperBounds(const Class& cls) { | 757 void ClassFinalizer::ResolveAndFinalizeUpperBounds(const Class& cls) { |
| 752 const intptr_t num_type_params = cls.NumTypeParameters(); | 758 const intptr_t num_type_params = cls.NumTypeParameters(); |
| 753 AbstractType& bound = AbstractType::Handle(); | 759 AbstractType& bound = AbstractType::Handle(); |
| 754 const AbstractTypeArguments& bounds = | 760 const AbstractTypeArguments& bounds = |
| 755 AbstractTypeArguments::Handle(cls.type_parameter_bounds()); | 761 AbstractTypeArguments::Handle(cls.type_parameter_bounds()); |
| 756 ASSERT((bounds.IsNull() && (num_type_params == 0)) || | 762 ASSERT((bounds.IsNull() && (num_type_params == 0)) || |
| 757 (bounds.Length() == num_type_params)); | 763 (bounds.Length() == num_type_params)); |
| 758 for (intptr_t i = 0; i < num_type_params; i++) { | 764 for (intptr_t i = 0; i < num_type_params; i++) { |
| 759 bound = bounds.TypeAt(i); | 765 bound = bounds.TypeAt(i); |
| 760 if (bound.IsDynamicType()) { | 766 if (bound.IsFinalized()) { |
| 761 continue; | 767 continue; |
| 762 } | 768 } |
| 763 ResolveType(cls, bound, kFinalize); | 769 ResolveType(cls, bound, kFinalize); |
| 764 bound = FinalizeType(cls, bound, kFinalize); | 770 bound = FinalizeType(cls, bound, kFinalize); |
| 765 bounds.SetTypeAt(i, bound); | 771 bounds.SetTypeAt(i, bound); |
| 766 } | 772 } |
| 767 } | 773 } |
| 768 | 774 |
| 769 | 775 |
| 770 void ClassFinalizer::ResolveAndFinalizeMemberTypes(const Class& cls) { | 776 void ClassFinalizer::ResolveAndFinalizeMemberTypes(const Class& cls) { |
| (...skipping 435 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1206 error ^= Parser::FormatError( | 1212 error ^= Parser::FormatError( |
| 1207 script, type.token_index(), "Error", format, args); | 1213 script, type.token_index(), "Error", format, args); |
| 1208 } else { | 1214 } else { |
| 1209 error ^= Parser::FormatErrorWithAppend( | 1215 error ^= Parser::FormatErrorWithAppend( |
| 1210 prev_error, script, type.token_index(), "Error", format, args); | 1216 prev_error, script, type.token_index(), "Error", format, args); |
| 1211 } | 1217 } |
| 1212 if (finalization == kFinalizeWellFormed) { | 1218 if (finalization == kFinalizeWellFormed) { |
| 1213 ReportError(error); | 1219 ReportError(error); |
| 1214 } | 1220 } |
| 1215 } | 1221 } |
| 1216 // Replace malformed type with Dynamic type. | |
| 1217 type.set_type_class(Class::Handle(Object::dynamic_class())); | |
| 1218 type.set_arguments(AbstractTypeArguments::Handle()); | |
| 1219 if (FLAG_enable_type_checks) { | 1222 if (FLAG_enable_type_checks) { |
| 1220 // In checked mode, mark type as malformed. | 1223 // In checked mode, mark type as malformed. |
| 1221 type.set_malformed_error(error); | 1224 type.set_malformed_error(error); |
| 1225 } else { |
| 1226 // In production mode, replace malformed type with Dynamic type. |
| 1227 type.set_type_class(Class::Handle(Object::dynamic_class())); |
| 1228 type.set_arguments(AbstractTypeArguments::Handle()); |
| 1222 } | 1229 } |
| 1223 if (!type.IsFinalized()) { | 1230 if (!type.IsFinalized()) { |
| 1224 type.set_is_finalized(); | 1231 type.set_is_finalized(); |
| 1225 type.Canonicalize(); | 1232 // Do not canonicalize malformed types, since they may not be resolved. |
| 1226 } else { | 1233 } else { |
| 1227 // The only case where the malformed type was already finalized is when its | 1234 // The only case where the malformed type was already finalized is when its |
| 1228 // type arguments are not within bounds. In that case, we have a prev_error. | 1235 // type arguments are not within bounds. In that case, we have a prev_error. |
| 1229 ASSERT(!prev_error.IsNull()); | 1236 ASSERT(!prev_error.IsNull()); |
| 1230 } | 1237 } |
| 1231 } | 1238 } |
| 1232 | 1239 |
| 1233 | 1240 |
| 1234 void ClassFinalizer::ReportError(const Error& error) { | 1241 void ClassFinalizer::ReportError(const Error& error) { |
| 1235 Isolate::Current()->long_jump_base()->Jump(1, error); | 1242 Isolate::Current()->long_jump_base()->Jump(1, error); |
| (...skipping 15 matching lines...) Expand all Loading... |
| 1251 void ClassFinalizer::ReportError(const char* format, ...) { | 1258 void ClassFinalizer::ReportError(const char* format, ...) { |
| 1252 va_list args; | 1259 va_list args; |
| 1253 va_start(args, format); | 1260 va_start(args, format); |
| 1254 const Error& error = Error::Handle( | 1261 const Error& error = Error::Handle( |
| 1255 Parser::FormatError(Script::Handle(), -1, "Error", format, args)); | 1262 Parser::FormatError(Script::Handle(), -1, "Error", format, args)); |
| 1256 va_end(args); | 1263 va_end(args); |
| 1257 ReportError(error); | 1264 ReportError(error); |
| 1258 } | 1265 } |
| 1259 | 1266 |
| 1260 } // namespace dart | 1267 } // namespace dart |
| OLD | NEW |