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

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

Issue 9615035: Generate dynamic type errors according to spec. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 8 years, 9 months 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
OLDNEW
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 148 matching lines...) Expand 10 before | Expand all | Expand 10 after
159 while (class_function.IsNull()) { 159 while (class_function.IsNull()) {
160 test_class = test_class.SuperClass(); 160 test_class = test_class.SuperClass();
161 if (test_class.IsNull()) break; 161 if (test_class.IsNull()) break;
162 class_function = test_class.LookupDynamicFunction(function_name); 162 class_function = test_class.LookupDynamicFunction(function_name);
163 } 163 }
164 if (class_function.IsNull()) { 164 if (class_function.IsNull()) {
165 OS::Print("%s implements '%s' missing: '%s'\n", 165 OS::Print("%s implements '%s' missing: '%s'\n",
166 class_name.ToCString(), 166 class_name.ToCString(),
167 interface_name.ToCString(), 167 interface_name.ToCString(),
168 function_name.ToCString()); 168 function_name.ToCString());
169 } else if (!class_function.IsSubtypeOf(TypeArguments::Handle(), 169 } else {
170 Error& malformed_error = Error::Handle();
171 if (!class_function.IsSubtypeOf(TypeArguments::Handle(),
170 interface_function, 172 interface_function,
171 TypeArguments::Handle())) { 173 TypeArguments::Handle(),
172 OS::Print("The type of instance method '%s' in class '%s' is not a " 174 &malformed_error)) {
173 "subtype of the type of '%s' in interface '%s'\n", 175 if (!malformed_error.IsNull()) {
174 function_name.ToCString(), 176 OS::Print("%s\n", malformed_error.ToErrorCString());
srdjan 2012/03/07 00:41:23 Shouldn't this be going to PrintErr?
regis 2012/03/07 02:22:38 Done.
175 class_name.ToCString(), 177 }
176 function_name.ToCString(), 178 OS::Print("The type of instance method '%s' in class '%s' is not a "
177 interface_name.ToCString()); 179 "subtype of the type of '%s' in interface '%s'\n",
180 function_name.ToCString(),
181 class_name.ToCString(),
182 function_name.ToCString(),
183 interface_name.ToCString());
184 }
178 } 185 }
179 } 186 }
180 } 187 }
181 } 188 }
182 #else 189 #else
183 190
184 void ClassFinalizer::VerifyClassImplements(const Class& cls) {} 191 void ClassFinalizer::VerifyClassImplements(const Class& cls) {}
185 192
186 #endif 193 #endif
187 194
(...skipping 258 matching lines...) Expand 10 before | Expand all | Expand 10 after
446 Class::Handle(ResolveClass(cls, unresolved_class)); 453 Class::Handle(ResolveClass(cls, unresolved_class));
447 454
448 // Replace unresolved class with resolved type class. 455 // Replace unresolved class with resolved type class.
449 ASSERT(type.IsType()); 456 ASSERT(type.IsType());
450 Type& parameterized_type = Type::Handle(); 457 Type& parameterized_type = Type::Handle();
451 parameterized_type ^= type.raw(); 458 parameterized_type ^= type.raw();
452 if (!type_class.IsNull()) { 459 if (!type_class.IsNull()) {
453 parameterized_type.set_type_class(Object::Handle(type_class.raw())); 460 parameterized_type.set_type_class(Object::Handle(type_class.raw()));
454 } else { 461 } else {
455 // The type class could not be resolved. The type is malformed. 462 // The type class could not be resolved. The type is malformed.
456 FinalizeMalformedType(cls, parameterized_type, finalization, 463 FinalizeMalformedType(Error::Handle(), // No previous error.
464 cls, parameterized_type, finalization,
457 "cannot resolve class name '%s' from '%s'", 465 "cannot resolve class name '%s' from '%s'",
458 String::Handle(unresolved_class.Name()).ToCString(), 466 String::Handle(unresolved_class.Name()).ToCString(),
459 String::Handle(cls.Name()).ToCString()); 467 String::Handle(cls.Name()).ToCString());
460 return; 468 return;
461 } 469 }
462 } 470 }
463 471
464 // Resolve type arguments, if any. 472 // Resolve type arguments, if any.
465 const AbstractTypeArguments& arguments = 473 const AbstractTypeArguments& arguments =
466 AbstractTypeArguments::Handle(type.arguments()); 474 AbstractTypeArguments::Handle(type.arguments());
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after
546 return type_parameter.raw(); 554 return type_parameter.raw();
547 } 555 }
548 556
549 // At this point, we can only have a parameterized_type. 557 // At this point, we can only have a parameterized_type.
550 Type& parameterized_type = Type::Handle(); 558 Type& parameterized_type = Type::Handle();
551 parameterized_type ^= type.raw(); 559 parameterized_type ^= type.raw();
552 560
553 if (parameterized_type.IsBeingFinalized()) { 561 if (parameterized_type.IsBeingFinalized()) {
554 // Self reference detected. The type is malformed. 562 // Self reference detected. The type is malformed.
555 FinalizeMalformedType( 563 FinalizeMalformedType(
564 Error::Handle(), // No previous error.
556 cls, parameterized_type, finalization, 565 cls, parameterized_type, finalization,
557 "type '%s' illegally refers to itself", 566 "type '%s' illegally refers to itself",
558 String::Handle(parameterized_type.Name()).ToCString()); 567 String::Handle(parameterized_type.Name()).ToCString());
559 return parameterized_type.raw(); 568 return parameterized_type.raw();
560 } 569 }
561 570
562 // Mark type as being finalized in order to detect illegal self reference. 571 // Mark type as being finalized in order to detect illegal self reference.
563 parameterized_type.set_is_being_finalized(); 572 parameterized_type.set_is_being_finalized();
564 573
565 // Finalize the current type arguments of the type, which are still the 574 // Finalize the current type arguments of the type, which are still the
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
605 // The type class has num_type_parameters type parameters. 614 // The type class has num_type_parameters type parameters.
606 const intptr_t num_type_parameters = type_class.NumTypeParameters(); 615 const intptr_t num_type_parameters = type_class.NumTypeParameters();
607 616
608 // Initialize the type argument vector. 617 // Initialize the type argument vector.
609 // Check the number of parsed type arguments, if any. 618 // Check the number of parsed type arguments, if any.
610 // Specifying no type arguments indicates a raw type, which is not an error. 619 // Specifying no type arguments indicates a raw type, which is not an error.
611 // However, type parameter bounds are checked below, even for a raw type. 620 // However, type parameter bounds are checked below, even for a raw type.
612 if (!arguments.IsNull() && (arguments.Length() != num_type_parameters)) { 621 if (!arguments.IsNull() && (arguments.Length() != num_type_parameters)) {
613 // Wrong number of type arguments. The type is malformed. 622 // Wrong number of type arguments. The type is malformed.
614 FinalizeMalformedType( 623 FinalizeMalformedType(
624 Error::Handle(), // No previous error.
615 cls, parameterized_type, finalization, 625 cls, parameterized_type, finalization,
616 "wrong number of type arguments in type '%s'", 626 "wrong number of type arguments in type '%s'",
617 String::Handle(parameterized_type.Name()).ToCString()); 627 String::Handle(parameterized_type.Name()).ToCString());
618 return parameterized_type.raw(); 628 return parameterized_type.raw();
619 } 629 }
620 // The full type argument vector consists of the type arguments of the 630 // The full type argument vector consists of the type arguments of the
621 // super types of type_class, which may be initialized from the parsed 631 // super types of type_class, which may be initialized from the parsed
622 // type arguments, followed by the parsed type arguments. 632 // type arguments, followed by the parsed type arguments.
623 if (num_type_arguments > 0) { 633 if (num_type_arguments > 0) {
624 TypeArguments& full_arguments = TypeArguments::Handle( 634 TypeArguments& full_arguments = TypeArguments::Handle(
(...skipping 20 matching lines...) Expand all
645 FinalizeTypeArguments(type_class, full_arguments, finalization); 655 FinalizeTypeArguments(type_class, full_arguments, finalization);
646 } 656 }
647 // FinalizeTypeArguments can modify 'full_arguments', 657 // FinalizeTypeArguments can modify 'full_arguments',
648 // canonicalize afterwards. 658 // canonicalize afterwards.
649 full_arguments ^= full_arguments.Canonicalize(); 659 full_arguments ^= full_arguments.Canonicalize();
650 parameterized_type.set_arguments(full_arguments); 660 parameterized_type.set_arguments(full_arguments);
651 661
652 // Mark the type as finalized. 662 // Mark the type as finalized.
653 parameterized_type.set_is_finalized(); 663 parameterized_type.set_is_finalized();
654 664
655 // No need to verify the upper bounds of the finalized type arguments, since 665 // Upper bounds of the finalized type arguments are only verified in checked
656 // bound errors are static type errors, which are not reported by the VM. 666 // mode, since bound errors are never reported by the vm in production mode.
667 if (FLAG_enable_type_checks && full_arguments.IsInstantiated()) {
668 ResolveAndFinalizeUpperBounds(type_class);
669 Error& malformed_error = Error::Handle();
670 // Pass the full type argument vector as the bounds instantiator.
671 if (!full_arguments.IsWithinBoundsOf(type_class,
672 full_arguments,
673 &malformed_error)) {
674 ASSERT(!malformed_error.IsNull());
675 // The type argument vector of the type is not within bounds. The type
676 // is malformed. Prepend malformed_error to new malformed type error in
677 // order to report both locations.
678 FinalizeMalformedType(
679 malformed_error,
680 cls, parameterized_type, finalization,
681 "type arguments of type '%s' are not within bounds",
682 String::Handle(parameterized_type.Name()).ToCString());
683 return parameterized_type.raw();
684 }
685 }
657 } else { 686 } else {
658 parameterized_type.set_is_finalized(); 687 parameterized_type.set_is_finalized();
659 } 688 }
660 return parameterized_type.Canonicalize(); 689 return parameterized_type.Canonicalize();
661 } 690 }
662 691
663 692
664 void ClassFinalizer::ResolveAndFinalizeSignature(const Class& cls, 693 void ClassFinalizer::ResolveAndFinalizeSignature(const Class& cls,
665 const Function& function) { 694 const Function& function) {
666 // Resolve result type. 695 // Resolve result type.
(...skipping 499 matching lines...) Expand 10 before | Expand all | Expand 10 after
1166 const Array& fields_array = Array::Handle(cls.fields()); 1195 const Array& fields_array = Array::Handle(cls.fields());
1167 Field& field = Field::Handle(); 1196 Field& field = Field::Handle();
1168 len = fields_array.Length(); 1197 len = fields_array.Length();
1169 for (intptr_t i = 0; i < len; i++) { 1198 for (intptr_t i = 0; i < len; i++) {
1170 field ^= fields_array.At(i); 1199 field ^= fields_array.At(i);
1171 OS::Print(" %s\n", field.ToCString()); 1200 OS::Print(" %s\n", field.ToCString());
1172 } 1201 }
1173 } 1202 }
1174 1203
1175 1204
1176 void ClassFinalizer::FinalizeMalformedType(const Class& cls, 1205 void ClassFinalizer::FinalizeMalformedType(const Error& prev_error,
1206 const Class& cls,
1177 const Type& type, 1207 const Type& type,
1178 FinalizationKind finalization, 1208 FinalizationKind finalization,
1179 const char* format, ...) { 1209 const char* format, ...) {
1180 va_list args; 1210 va_list args;
1181 va_start(args, format); 1211 va_start(args, format);
1182 LanguageError& error = LanguageError::Handle(); 1212 LanguageError& error = LanguageError::Handle();
1183 if ((finalization == kFinalizeWellFormed) || FLAG_enable_type_checks) { 1213 if ((finalization == kFinalizeWellFormed) || FLAG_enable_type_checks) {
1184 const Script& script = Script::Handle(cls.script()); 1214 const Script& script = Script::Handle(cls.script());
1185 error ^= 1215 if (prev_error.IsNull()) {
1186 Parser::FormatError(script, type.token_index(), "Error", format, args); 1216 error ^= Parser::FormatError(
1217 script, type.token_index(), "Error", format, args);
1218 } else {
1219 error ^= Parser::FormatErrorWithAppend(
1220 prev_error, script, type.token_index(), "Error", format, args);
1221 }
1187 if (finalization == kFinalizeWellFormed) { 1222 if (finalization == kFinalizeWellFormed) {
1188 ReportError(error); 1223 ReportError(error);
1189 } 1224 }
1190 } 1225 }
1191 // Replace malformed type with Dynamic type. 1226 // Replace malformed type with Dynamic type.
1192 type.set_type_class(Class::Handle(Object::dynamic_class())); 1227 type.set_type_class(Class::Handle(Object::dynamic_class()));
1193 type.set_arguments(AbstractTypeArguments::Handle()); 1228 type.set_arguments(AbstractTypeArguments::Handle());
1194 if (FLAG_enable_type_checks) { 1229 if (FLAG_enable_type_checks) {
1195 // In checked mode, mark type as malformed. 1230 // In checked mode, mark type as malformed.
1196 type.set_malformed_error(error); 1231 type.set_malformed_error(error);
1197 } 1232 }
1198 type.set_is_finalized(); 1233 if (!type.IsFinalized()) {
1199 type.Canonicalize(); 1234 type.set_is_finalized();
1235 type.Canonicalize();
1236 } else {
1237 // The only case where the malformed type was already finalized is when its
1238 // type arguments are not within bounds. In that case, we have a prev_error.
1239 ASSERT(!prev_error.IsNull());
1240 }
1200 } 1241 }
1201 1242
1202 1243
1203 void ClassFinalizer::ReportError(const Error& error) { 1244 void ClassFinalizer::ReportError(const Error& error) {
1204 Isolate::Current()->long_jump_base()->Jump(1, error); 1245 Isolate::Current()->long_jump_base()->Jump(1, error);
1205 UNREACHABLE(); 1246 UNREACHABLE();
1206 } 1247 }
1207 1248
1208 1249
1209 void ClassFinalizer::ReportError(const Script& script, 1250 void ClassFinalizer::ReportError(const Script& script,
(...skipping 10 matching lines...) Expand all
1220 void ClassFinalizer::ReportError(const char* format, ...) { 1261 void ClassFinalizer::ReportError(const char* format, ...) {
1221 va_list args; 1262 va_list args;
1222 va_start(args, format); 1263 va_start(args, format);
1223 const Error& error = Error::Handle( 1264 const Error& error = Error::Handle(
1224 Parser::FormatError(Script::Handle(), -1, "Error", format, args)); 1265 Parser::FormatError(Script::Handle(), -1, "Error", format, args));
1225 va_end(args); 1266 va_end(args);
1226 ReportError(error); 1267 ReportError(error);
1227 } 1268 }
1228 1269
1229 } // namespace dart 1270 } // namespace dart
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698