| OLD | NEW |
| 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 #include "vm/parser.h" |
| 12 | 13 |
| 13 namespace dart { | 14 namespace dart { |
| 14 | 15 |
| 15 DEFINE_FLAG(bool, print_classes, false, "Prints details about loaded classes."); | 16 DEFINE_FLAG(bool, print_classes, false, "Prints details about loaded classes."); |
| 16 DEFINE_FLAG(bool, trace_class_finalization, false, "Trace class finalization."); | 17 DEFINE_FLAG(bool, trace_class_finalization, false, "Trace class finalization."); |
| 17 DEFINE_FLAG(bool, trace_type_finalization, false, "Trace type finalization."); | 18 DEFINE_FLAG(bool, trace_type_finalization, false, "Trace type finalization."); |
| 18 DEFINE_FLAG(bool, verify_implements, false, | 19 DEFINE_FLAG(bool, verify_implements, false, |
| 19 "Verify that all classes implement their interface."); | 20 "Verify that all classes implement their interface."); |
| 20 DECLARE_FLAG(bool, enable_type_checks); | 21 DECLARE_FLAG(bool, enable_type_checks); |
| 21 DECLARE_FLAG(bool, silent_warnings); | 22 DECLARE_FLAG(bool, silent_warnings); |
| (...skipping 274 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 296 String& type_parameter_name = String::Handle(super_type.Name()); | 297 String& type_parameter_name = String::Handle(super_type.Name()); |
| 297 ReportError("'%s' cannot extend or implement type parameter '%s'.\n", | 298 ReportError("'%s' cannot extend or implement type parameter '%s'.\n", |
| 298 class_name.ToCString(), | 299 class_name.ToCString(), |
| 299 type_parameter_name.ToCString()); | 300 type_parameter_name.ToCString()); |
| 300 } | 301 } |
| 301 cls.set_super_type(super_type); | 302 cls.set_super_type(super_type); |
| 302 const Class& super_class = Class::Handle(super_type.type_class()); | 303 const Class& super_class = Class::Handle(super_type.type_class()); |
| 303 if (cls.is_interface() != super_class.is_interface()) { | 304 if (cls.is_interface() != super_class.is_interface()) { |
| 304 String& class_name = String::Handle(cls.Name()); | 305 String& class_name = String::Handle(cls.Name()); |
| 305 String& super_class_name = String::Handle(super_class.Name()); | 306 String& super_class_name = String::Handle(super_class.Name()); |
| 306 ReportError("class '%s' and superclass '%s' are not " | 307 const Script& script = Script::Handle(cls.script()); |
| 308 ReportError(script, -1, |
| 309 "class '%s' and superclass '%s' are not " |
| 307 "both classes or both interfaces.\n", | 310 "both classes or both interfaces.\n", |
| 308 class_name.ToCString(), | 311 class_name.ToCString(), |
| 309 super_class_name.ToCString()); | 312 super_class_name.ToCString()); |
| 310 } | 313 } |
| 311 // If cls belongs to core lib or to core lib's implementation, restrictions | 314 // If cls belongs to core lib or to core lib's implementation, restrictions |
| 312 // about allowed interfaces are lifted. | 315 // about allowed interfaces are lifted. |
| 313 if ((cls.library() != Library::CoreLibrary()) && | 316 if ((cls.library() != Library::CoreLibrary()) && |
| 314 (cls.library() != Library::CoreImplLibrary())) { | 317 (cls.library() != Library::CoreImplLibrary())) { |
| 315 // Prevent extending core implementation classes Bool, Double, ObjectArray, | 318 // Prevent extending core implementation classes Bool, Double, ObjectArray, |
| 316 // ImmutableArray, GrowableObjectArray, IntegerImplementation, Smi, Mint, | 319 // ImmutableArray, GrowableObjectArray, IntegerImplementation, Smi, Mint, |
| (...skipping 14 matching lines...) Expand all Loading... |
| 331 (super_class.raw() == object_store->immutable_array_class()) || | 334 (super_class.raw() == object_store->immutable_array_class()) || |
| 332 (super_class.raw() == growable_object_array_class.raw()) || | 335 (super_class.raw() == growable_object_array_class.raw()) || |
| 333 (super_class.raw() == object_store->byte_buffer_class()) || | 336 (super_class.raw() == object_store->byte_buffer_class()) || |
| 334 (super_class.raw() == integer_implementation_class.raw()) || | 337 (super_class.raw() == integer_implementation_class.raw()) || |
| 335 (super_class.raw() == object_store->smi_class()) || | 338 (super_class.raw() == object_store->smi_class()) || |
| 336 (super_class.raw() == object_store->mint_class()) || | 339 (super_class.raw() == object_store->mint_class()) || |
| 337 (super_class.raw() == object_store->bigint_class()) || | 340 (super_class.raw() == object_store->bigint_class()) || |
| 338 (super_class.raw() == object_store->one_byte_string_class()) || | 341 (super_class.raw() == object_store->one_byte_string_class()) || |
| 339 (super_class.raw() == object_store->two_byte_string_class()) || | 342 (super_class.raw() == object_store->two_byte_string_class()) || |
| 340 (super_class.raw() == object_store->four_byte_string_class())) { | 343 (super_class.raw() == object_store->four_byte_string_class())) { |
| 341 ReportError("'%s' is not allowed to extend '%s'\n", | 344 const Script& script = Script::Handle(cls.script()); |
| 345 ReportError(script, -1, |
| 346 "'%s' is not allowed to extend '%s'\n", |
| 342 String::Handle(cls.Name()).ToCString(), | 347 String::Handle(cls.Name()).ToCString(), |
| 343 String::Handle(super_class.Name()).ToCString()); | 348 String::Handle(super_class.Name()).ToCString()); |
| 344 } | 349 } |
| 345 } | 350 } |
| 346 return; | 351 return; |
| 347 } | 352 } |
| 348 | 353 |
| 349 | 354 |
| 350 void ClassFinalizer::ResolveFactoryClass(const Class& interface) { | 355 void ClassFinalizer::ResolveFactoryClass(const Class& interface) { |
| 351 ASSERT(interface.is_interface()); | 356 ASSERT(interface.is_interface()); |
| 352 if (interface.is_finalized() || | 357 if (interface.is_finalized() || |
| 353 !interface.HasFactoryClass() || | 358 !interface.HasFactoryClass() || |
| 354 interface.HasResolvedFactoryClass()) { | 359 interface.HasResolvedFactoryClass()) { |
| 355 return; | 360 return; |
| 356 } | 361 } |
| 357 const UnresolvedClass& unresolved_factory_class = | 362 const UnresolvedClass& unresolved_factory_class = |
| 358 UnresolvedClass::Handle(interface.UnresolvedFactoryClass()); | 363 UnresolvedClass::Handle(interface.UnresolvedFactoryClass()); |
| 359 | 364 |
| 360 // Lookup the factory class. | 365 // Lookup the factory class. |
| 361 const Class& factory_class = | 366 const Class& factory_class = |
| 362 Class::Handle(ResolveClass(interface, unresolved_factory_class)); | 367 Class::Handle(ResolveClass(interface, unresolved_factory_class)); |
| 363 ASSERT(!factory_class.IsNull()); | 368 ASSERT(!factory_class.IsNull()); |
| 364 if (factory_class.is_interface()) { | 369 if (factory_class.is_interface()) { |
| 365 const String& interface_name = String::Handle(interface.Name()); | 370 const String& interface_name = String::Handle(interface.Name()); |
| 366 const String& factory_name = String::Handle(factory_class.Name()); | 371 const String& factory_name = String::Handle(factory_class.Name()); |
| 367 ReportError("factory clause of interface '%s' names non-class '%s'.\n", | 372 const Script& script = Script::Handle(interface.script()); |
| 373 ReportError(script, unresolved_factory_class.token_index(), |
| 374 "factory clause of interface '%s' names non-class '%s'.\n", |
| 368 interface_name.ToCString(), | 375 interface_name.ToCString(), |
| 369 factory_name.ToCString()); | 376 factory_name.ToCString()); |
| 370 } | 377 } |
| 371 interface.set_factory_class(factory_class); | 378 interface.set_factory_class(factory_class); |
| 372 // Check that the type parameter lists are identical. | 379 // Check that the type parameter lists are identical. |
| 373 const Class& factory_signature_class = Class::Handle( | 380 const Class& factory_signature_class = Class::Handle( |
| 374 unresolved_factory_class.factory_signature_class()); | 381 unresolved_factory_class.factory_signature_class()); |
| 375 ASSERT(!factory_signature_class.IsNull()); | 382 ASSERT(!factory_signature_class.IsNull()); |
| 376 ResolveAndFinalizeUpperBounds(factory_class); | 383 ResolveAndFinalizeUpperBounds(factory_class); |
| 377 ResolveAndFinalizeUpperBounds(factory_signature_class); | 384 ResolveAndFinalizeUpperBounds(factory_signature_class); |
| 378 const intptr_t num_type_params = factory_signature_class.NumTypeParameters(); | 385 const intptr_t num_type_params = factory_signature_class.NumTypeParameters(); |
| 379 bool mismatch = factory_class.NumTypeParameters() != num_type_params; | 386 bool mismatch = factory_class.NumTypeParameters() != num_type_params; |
| 380 if (mismatch && (num_type_params == 0)) { | 387 if (mismatch && (num_type_params == 0)) { |
| 381 // TODO(regis): For now, and until the core lib is fixed, we accept a | 388 // TODO(regis): For now, and until the core lib is fixed, we accept a |
| 382 // factory clause with a class missing its list of type parameters. | 389 // factory clause with a class missing its list of type parameters. |
| 383 // See bug 5408808. | 390 // See bug 5408808. |
| 384 const String& interface_name = String::Handle(interface.Name()); | 391 const String& interface_name = String::Handle(interface.Name()); |
| 385 const String& factory_name = String::Handle(factory_class.Name()); | 392 const String& factory_name = String::Handle(factory_class.Name()); |
| 386 ReportWarning("Warning: class '%s' in factory clause of interface '%s' is " | 393 const Script& script = Script::Handle(interface.script()); |
| 394 ReportWarning(script, unresolved_factory_class.token_index(), |
| 395 "class '%s' in factory clause of interface '%s' is " |
| 387 "missing its type parameter list.\n", | 396 "missing its type parameter list.\n", |
| 388 factory_name.ToCString(), | 397 factory_name.ToCString(), |
| 389 interface_name.ToCString()); | 398 interface_name.ToCString()); |
| 390 return; | 399 return; |
| 391 } | 400 } |
| 392 String& expected_type_name = String::Handle(); | 401 String& expected_type_name = String::Handle(); |
| 393 String& actual_type_name = String::Handle(); | 402 String& actual_type_name = String::Handle(); |
| 394 Type& expected_type_extends = Type::Handle(); | 403 Type& expected_type_extends = Type::Handle(); |
| 395 Type& actual_type_extends = Type::Handle(); | 404 Type& actual_type_extends = Type::Handle(); |
| 396 const Array& expected_type_names = | 405 const Array& expected_type_names = |
| (...skipping 11 matching lines...) Expand all Loading... |
| 408 actual_type_extends = actual_extends_array.TypeAt(i); | 417 actual_type_extends = actual_extends_array.TypeAt(i); |
| 409 if (!expected_type_name.Equals(actual_type_name) || | 418 if (!expected_type_name.Equals(actual_type_name) || |
| 410 !expected_type_extends.Equals(actual_type_extends)) { | 419 !expected_type_extends.Equals(actual_type_extends)) { |
| 411 mismatch = true; | 420 mismatch = true; |
| 412 } | 421 } |
| 413 } | 422 } |
| 414 if (mismatch) { | 423 if (mismatch) { |
| 415 const String& interface_name = String::Handle(interface.Name()); | 424 const String& interface_name = String::Handle(interface.Name()); |
| 416 const String& factory_name = String::Handle(factory_class.Name()); | 425 const String& factory_name = String::Handle(factory_class.Name()); |
| 417 // TODO(regis): Report the filename and position as well. | 426 // TODO(regis): Report the filename and position as well. |
| 418 ReportError("mismatch in number or names of type parameters between " | 427 const Script& script = Script::Handle(interface.script()); |
| 428 ReportError(script, unresolved_factory_class.token_index(), |
| 429 "mismatch in number or names of type parameters between " |
| 419 "factory clause of interface '%s' and actual factory " | 430 "factory clause of interface '%s' and actual factory " |
| 420 "class '%s'.\n", | 431 "class '%s'.\n", |
| 421 interface_name.ToCString(), | 432 interface_name.ToCString(), |
| 422 factory_name.ToCString()); | 433 factory_name.ToCString()); |
| 423 } | 434 } |
| 424 } | 435 } |
| 425 | 436 |
| 426 | 437 |
| 427 // TODO(regis): Now that we do not resolve type parameters anymore, we could | 438 // TODO(regis): Now that we do not resolve type parameters anymore, we could |
| 428 // make this function void and resolve the type in place. | 439 // make this function void and resolve the type in place. |
| (...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 532 if (type.IsInstantiated()) { | 543 if (type.IsInstantiated()) { |
| 533 if (!type_extends.IsInstantiated()) { | 544 if (!type_extends.IsInstantiated()) { |
| 534 type_extends = type_extends.InstantiateFrom(arguments, offset); | 545 type_extends = type_extends.InstantiateFrom(arguments, offset); |
| 535 } | 546 } |
| 536 // TODO(regis): Where do we check the constraints when the type is | 547 // TODO(regis): Where do we check the constraints when the type is |
| 537 // generic? | 548 // generic? |
| 538 if (!type.IsSubtypeOf(type_extends)) { | 549 if (!type.IsSubtypeOf(type_extends)) { |
| 539 const String& type_argument_name = String::Handle(type.Name()); | 550 const String& type_argument_name = String::Handle(type.Name()); |
| 540 const String& class_name = String::Handle(cls.Name()); | 551 const String& class_name = String::Handle(cls.Name()); |
| 541 const String& extends_name = String::Handle(type_extends.Name()); | 552 const String& extends_name = String::Handle(type_extends.Name()); |
| 542 ReportError("type argument '%s' of class '%s' " | 553 const Script& script = Script::Handle(cls.script()); |
| 554 ReportError(script, -1, |
| 555 "type argument '%s' of class '%s' " |
| 543 "does not extend type '%s'\n", | 556 "does not extend type '%s'\n", |
| 544 type_argument_name.ToCString(), | 557 type_argument_name.ToCString(), |
| 545 class_name.ToCString(), | 558 class_name.ToCString(), |
| 546 extends_name.ToCString()); | 559 extends_name.ToCString()); |
| 547 } | 560 } |
| 548 } | 561 } |
| 549 } | 562 } |
| 550 } | 563 } |
| 551 Type& super_type = Type::Handle(cls.super_type()); | 564 Type& super_type = Type::Handle(cls.super_type()); |
| 552 if (!super_type.IsNull()) { | 565 if (!super_type.IsNull()) { |
| (...skipping 162 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 715 if (factory_signature_class.NumTypeParameters() != | 728 if (factory_signature_class.NumTypeParameters() != |
| 716 type_class.NumTypeParameters()) { | 729 type_class.NumTypeParameters()) { |
| 717 const String& function_name = String::Handle(function.name()); | 730 const String& function_name = String::Handle(function.name()); |
| 718 if (factory_signature_class.NumTypeParameters() == 0) { | 731 if (factory_signature_class.NumTypeParameters() == 0) { |
| 719 // TODO(regis): For now, and until the core lib is fixed, we accept a | 732 // TODO(regis): For now, and until the core lib is fixed, we accept a |
| 720 // factory method with missing list of type parameters and use the | 733 // factory method with missing list of type parameters and use the |
| 721 // list of the enclosing class. | 734 // list of the enclosing class. |
| 722 // See bug 5408808. | 735 // See bug 5408808. |
| 723 const Class& enclosing_class = Class::Handle(function.owner()); | 736 const Class& enclosing_class = Class::Handle(function.owner()); |
| 724 function.set_signature_class(enclosing_class); | 737 function.set_signature_class(enclosing_class); |
| 725 ReportWarning("Warning: factory method '%s' should declare a list of " | 738 const Script& script = Script::Handle(enclosing_class.script()); |
| 739 ReportWarning(script, unresolved_type_class.token_index(), |
| 740 "factory method '%s' should declare a list of " |
| 726 "%d type parameter%s.\n", | 741 "%d type parameter%s.\n", |
| 727 function_name.ToCString(), | 742 function_name.ToCString(), |
| 728 type_class.NumTypeParameters(), | 743 type_class.NumTypeParameters(), |
| 729 type_class.NumTypeParameters() > 1 ? "s" : ""); | 744 type_class.NumTypeParameters() > 1 ? "s" : ""); |
| 730 } else { | 745 } else { |
| 731 // TODO(regis): Report the filename and position as well. | 746 const Class& enclosing_class = Class::Handle(function.owner()); |
| 732 ReportError("factory method '%s' must declare %d type parameter%s.\n", | 747 const Script& script = Script::Handle(enclosing_class.script()); |
| 748 ReportError(script, unresolved_type_class.token_index(), |
| 749 "factory method '%s' must declare %d type parameter%s.\n", |
| 733 function_name.ToCString(), | 750 function_name.ToCString(), |
| 734 type_class.NumTypeParameters(), | 751 type_class.NumTypeParameters(), |
| 735 type_class.NumTypeParameters() > 1 ? "s" : ""); | 752 type_class.NumTypeParameters() > 1 ? "s" : ""); |
| 736 } | 753 } |
| 737 } | 754 } |
| 738 } else { | 755 } else { |
| 739 type = ResolveType(cls, type); | 756 type = ResolveType(cls, type); |
| 740 function.set_result_type(type); | 757 function.set_result_type(type); |
| 741 } | 758 } |
| 742 } | 759 } |
| (...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 835 type = field.type(); | 852 type = field.type(); |
| 836 type = ResolveType(cls, type); | 853 type = ResolveType(cls, type); |
| 837 field.set_type(type); | 854 field.set_type(type); |
| 838 type = FinalizeType(type); | 855 type = FinalizeType(type); |
| 839 field.set_type(type); | 856 field.set_type(type); |
| 840 name = field.name(); | 857 name = field.name(); |
| 841 super_class = FindSuperOwnerOfInstanceMember(cls, name); | 858 super_class = FindSuperOwnerOfInstanceMember(cls, name); |
| 842 if (!super_class.IsNull()) { | 859 if (!super_class.IsNull()) { |
| 843 const String& class_name = String::Handle(cls.Name()); | 860 const String& class_name = String::Handle(cls.Name()); |
| 844 const String& super_class_name = String::Handle(super_class.Name()); | 861 const String& super_class_name = String::Handle(super_class.Name()); |
| 845 ReportError("field '%s' of class '%s' conflicts with instance " | 862 const Script& script = Script::Handle(cls.script()); |
| 863 ReportError(script, field.token_index(), |
| 864 "field '%s' of class '%s' conflicts with instance " |
| 846 "member '%s' of super class '%s'.\n", | 865 "member '%s' of super class '%s'.\n", |
| 847 name.ToCString(), | 866 name.ToCString(), |
| 848 class_name.ToCString(), | 867 class_name.ToCString(), |
| 849 name.ToCString(), | 868 name.ToCString(), |
| 850 super_class_name.ToCString()); | 869 super_class_name.ToCString()); |
| 851 } | 870 } |
| 852 } | 871 } |
| 853 // Resolve function signatures and check for conflicts in super classes. | 872 // Resolve function signatures and check for conflicts in super classes. |
| 854 array = cls.functions(); | 873 array = cls.functions(); |
| 855 Function& function = Function::Handle(); | 874 Function& function = Function::Handle(); |
| 856 Function& overridden_function = Function::Handle(); | 875 Function& overridden_function = Function::Handle(); |
| 857 intptr_t num_functions = array.Length(); | 876 intptr_t num_functions = array.Length(); |
| 858 String& function_name = String::Handle(); | 877 String& function_name = String::Handle(); |
| 859 for (intptr_t i = 0; i < num_functions; i++) { | 878 for (intptr_t i = 0; i < num_functions; i++) { |
| 860 function ^= array.At(i); | 879 function ^= array.At(i); |
| 861 ResolveAndFinalizeSignature(cls, function); | 880 ResolveAndFinalizeSignature(cls, function); |
| 862 function_name = function.name(); | 881 function_name = function.name(); |
| 863 if (function.is_static()) { | 882 if (function.is_static()) { |
| 864 super_class = FindSuperOwnerOfInstanceMember(cls, function_name); | 883 super_class = FindSuperOwnerOfInstanceMember(cls, function_name); |
| 865 if (!super_class.IsNull()) { | 884 if (!super_class.IsNull()) { |
| 866 const String& class_name = String::Handle(cls.Name()); | 885 const String& class_name = String::Handle(cls.Name()); |
| 867 const String& super_class_name = String::Handle(super_class.Name()); | 886 const String& super_class_name = String::Handle(super_class.Name()); |
| 868 ReportError("static function '%s' of class '%s' conflicts with " | 887 const Script& script = Script::Handle(cls.script()); |
| 888 ReportError(script, function.token_index(), |
| 889 "static function '%s' of class '%s' conflicts with " |
| 869 "instance member '%s' of super class '%s'.\n", | 890 "instance member '%s' of super class '%s'.\n", |
| 870 function_name.ToCString(), | 891 function_name.ToCString(), |
| 871 class_name.ToCString(), | 892 class_name.ToCString(), |
| 872 function_name.ToCString(), | 893 function_name.ToCString(), |
| 873 super_class_name.ToCString()); | 894 super_class_name.ToCString()); |
| 874 } | 895 } |
| 875 } else { | 896 } else { |
| 876 // TODO(regis): This arity check is still being debated. Revisit. | 897 // TODO(regis): This arity check is still being debated. Revisit. |
| 877 super_class = cls.SuperClass(); | 898 super_class = cls.SuperClass(); |
| 878 while (!super_class.IsNull()) { | 899 while (!super_class.IsNull()) { |
| 879 overridden_function = super_class.LookupDynamicFunction(function_name); | 900 overridden_function = super_class.LookupDynamicFunction(function_name); |
| 880 if (!overridden_function.IsNull() && | 901 if (!overridden_function.IsNull() && |
| 881 !function.HasCompatibleParametersWith(overridden_function)) { | 902 !function.HasCompatibleParametersWith(overridden_function)) { |
| 882 // Function types are purposely not checked for subtyping. | 903 // Function types are purposely not checked for subtyping. |
| 883 const String& class_name = String::Handle(cls.Name()); | 904 const String& class_name = String::Handle(cls.Name()); |
| 884 const String& super_class_name = String::Handle(super_class.Name()); | 905 const String& super_class_name = String::Handle(super_class.Name()); |
| 885 ReportError("class '%s' overrides function '%s' of super class '%s' " | 906 const Script& script = Script::Handle(cls.script()); |
| 907 ReportError(script, function.token_index(), |
| 908 "class '%s' overrides function '%s' of super class '%s' " |
| 886 "with incompatible parameters.\n", | 909 "with incompatible parameters.\n", |
| 887 class_name.ToCString(), | 910 class_name.ToCString(), |
| 888 function_name.ToCString(), | 911 function_name.ToCString(), |
| 889 super_class_name.ToCString()); | 912 super_class_name.ToCString()); |
| 890 } | 913 } |
| 891 super_class = super_class.SuperClass(); | 914 super_class = super_class.SuperClass(); |
| 892 } | 915 } |
| 893 } | 916 } |
| 894 if (function.kind() == RawFunction::kGetterFunction) { | 917 if (function.kind() == RawFunction::kGetterFunction) { |
| 895 name = Field::NameFromGetter(function_name); | 918 name = Field::NameFromGetter(function_name); |
| 896 super_class = FindSuperOwnerOfFunction(cls, name); | 919 super_class = FindSuperOwnerOfFunction(cls, name); |
| 897 if (!super_class.IsNull()) { | 920 if (!super_class.IsNull()) { |
| 898 const String& class_name = String::Handle(cls.Name()); | 921 const String& class_name = String::Handle(cls.Name()); |
| 899 const String& super_class_name = String::Handle(super_class.Name()); | 922 const String& super_class_name = String::Handle(super_class.Name()); |
| 900 ReportError("getter '%s' of class '%s' conflicts with " | 923 const Script& script = Script::Handle(cls.script()); |
| 924 ReportError(script, function.token_index(), |
| 925 "getter '%s' of class '%s' conflicts with " |
| 901 "function '%s' of super class '%s'.\n", | 926 "function '%s' of super class '%s'.\n", |
| 902 name.ToCString(), | 927 name.ToCString(), |
| 903 class_name.ToCString(), | 928 class_name.ToCString(), |
| 904 name.ToCString(), | 929 name.ToCString(), |
| 905 super_class_name.ToCString()); | 930 super_class_name.ToCString()); |
| 906 } | 931 } |
| 907 } else if (function.kind() == RawFunction::kSetterFunction) { | 932 } else if (function.kind() == RawFunction::kSetterFunction) { |
| 908 name = Field::NameFromSetter(function_name); | 933 name = Field::NameFromSetter(function_name); |
| 909 super_class = FindSuperOwnerOfFunction(cls, name); | 934 super_class = FindSuperOwnerOfFunction(cls, name); |
| 910 if (!super_class.IsNull()) { | 935 if (!super_class.IsNull()) { |
| 911 const String& class_name = String::Handle(cls.Name()); | 936 const String& class_name = String::Handle(cls.Name()); |
| 912 const String& super_class_name = String::Handle(super_class.Name()); | 937 const String& super_class_name = String::Handle(super_class.Name()); |
| 913 ReportError("setter '%s' of class '%s' conflicts with " | 938 const Script& script = Script::Handle(cls.script()); |
| 939 ReportError(script, function.token_index(), |
| 940 "setter '%s' of class '%s' conflicts with " |
| 914 "function '%s' of super class '%s'.\n", | 941 "function '%s' of super class '%s'.\n", |
| 915 name.ToCString(), | 942 name.ToCString(), |
| 916 class_name.ToCString(), | 943 class_name.ToCString(), |
| 917 name.ToCString(), | 944 name.ToCString(), |
| 918 super_class_name.ToCString()); | 945 super_class_name.ToCString()); |
| 919 } | 946 } |
| 920 } else { | 947 } else { |
| 921 name = Field::GetterName(function_name); | 948 name = Field::GetterName(function_name); |
| 922 super_class = FindSuperOwnerOfFunction(cls, name); | 949 super_class = FindSuperOwnerOfFunction(cls, name); |
| 923 if (!super_class.IsNull()) { | 950 if (!super_class.IsNull()) { |
| 924 const String& class_name = String::Handle(cls.Name()); | 951 const String& class_name = String::Handle(cls.Name()); |
| 925 const String& super_class_name = String::Handle(super_class.Name()); | 952 const String& super_class_name = String::Handle(super_class.Name()); |
| 926 ReportError("function '%s' of class '%s' conflicts with " | 953 const Script& script = Script::Handle(cls.script()); |
| 954 ReportError(script, function.token_index(), |
| 955 "function '%s' of class '%s' conflicts with " |
| 927 "getter '%s' of super class '%s'.\n", | 956 "getter '%s' of super class '%s'.\n", |
| 928 function_name.ToCString(), | 957 function_name.ToCString(), |
| 929 class_name.ToCString(), | 958 class_name.ToCString(), |
| 930 function_name.ToCString(), | 959 function_name.ToCString(), |
| 931 super_class_name.ToCString()); | 960 super_class_name.ToCString()); |
| 932 } | 961 } |
| 933 name = Field::SetterName(function_name); | 962 name = Field::SetterName(function_name); |
| 934 super_class = FindSuperOwnerOfFunction(cls, name); | 963 super_class = FindSuperOwnerOfFunction(cls, name); |
| 935 if (!super_class.IsNull()) { | 964 if (!super_class.IsNull()) { |
| 936 const String& class_name = String::Handle(cls.Name()); | 965 const String& class_name = String::Handle(cls.Name()); |
| 937 const String& super_class_name = String::Handle(super_class.Name()); | 966 const String& super_class_name = String::Handle(super_class.Name()); |
| 938 ReportError("function '%s' of class '%s' conflicts with " | 967 const Script& script = Script::Handle(cls.script()); |
| 968 ReportError(script, function.token_index(), |
| 969 "function '%s' of class '%s' conflicts with " |
| 939 "setter '%s' of super class '%s'.\n", | 970 "setter '%s' of super class '%s'.\n", |
| 940 function_name.ToCString(), | 971 function_name.ToCString(), |
| 941 class_name.ToCString(), | 972 class_name.ToCString(), |
| 942 function_name.ToCString(), | 973 function_name.ToCString(), |
| 943 super_class_name.ToCString()); | 974 super_class_name.ToCString()); |
| 944 } | 975 } |
| 945 } | 976 } |
| 946 } | 977 } |
| 947 } | 978 } |
| 948 | 979 |
| 949 | 980 |
| 950 void ClassFinalizer::FinalizeClass(const Class& cls) { | 981 void ClassFinalizer::FinalizeClass(const Class& cls) { |
| 951 if (cls.is_finalized()) { | 982 if (cls.is_finalized()) { |
| 952 return; | 983 return; |
| 953 } | 984 } |
| 954 if (FLAG_trace_class_finalization) { | 985 if (FLAG_trace_class_finalization) { |
| 955 OS::Print("Finalize %s\n", cls.ToCString()); | 986 OS::Print("Finalize %s\n", cls.ToCString()); |
| 956 } | 987 } |
| 957 // Signature classes are finalized upon creation. | 988 // Signature classes are finalized upon creation. |
| 958 ASSERT(!cls.IsSignatureClass()); | 989 ASSERT(!cls.IsSignatureClass()); |
| 959 if (!IsSuperCycleFree(cls)) { | 990 if (!IsSuperCycleFree(cls)) { |
| 960 const String& name = String::Handle(cls.Name()); | 991 const String& name = String::Handle(cls.Name()); |
| 961 ReportError("class '%s' has a cycle in its superclass relationship.\n", | 992 const Script& script = Script::Handle(cls.script()); |
| 993 ReportError(script, -1, |
| 994 "class '%s' has a cycle in its superclass relationship.\n", |
| 962 name.ToCString()); | 995 name.ToCString()); |
| 963 } | 996 } |
| 964 GrowableArray<const Class*> visited; | 997 GrowableArray<const Class*> visited; |
| 965 ResolveInterfaces(cls, &visited); | 998 ResolveInterfaces(cls, &visited); |
| 966 Type& super_type = Type::Handle(cls.super_type()); | 999 Type& super_type = Type::Handle(cls.super_type()); |
| 967 if (!super_type.IsNull()) { | 1000 if (!super_type.IsNull()) { |
| 968 const Class& super_class = Class::Handle(super_type.type_class()); | 1001 const Class& super_class = Class::Handle(super_type.type_class()); |
| 969 // Finalize super class and super type. | 1002 // Finalize super class and super type. |
| 970 FinalizeClass(super_class); | 1003 FinalizeClass(super_class); |
| 971 super_type = FinalizeType(super_type); | 1004 super_type = FinalizeType(super_type); |
| (...skipping 29 matching lines...) Expand all Loading... |
| 1001 if (cls.is_const()) { | 1034 if (cls.is_const()) { |
| 1002 CheckForLegalConstClass(cls); | 1035 CheckForLegalConstClass(cls); |
| 1003 } | 1036 } |
| 1004 // Check to ensure we don't have classes with native fields in libraries | 1037 // Check to ensure we don't have classes with native fields in libraries |
| 1005 // which do not have a native resolver. | 1038 // which do not have a native resolver. |
| 1006 if (cls.num_native_fields() != 0) { | 1039 if (cls.num_native_fields() != 0) { |
| 1007 const Library& lib = Library::Handle(cls.library()); | 1040 const Library& lib = Library::Handle(cls.library()); |
| 1008 if (lib.native_entry_resolver() == NULL) { | 1041 if (lib.native_entry_resolver() == NULL) { |
| 1009 const String& cls_name = String::Handle(cls.Name()); | 1042 const String& cls_name = String::Handle(cls.Name()); |
| 1010 const String& lib_name = String::Handle(lib.url()); | 1043 const String& lib_name = String::Handle(lib.url()); |
| 1011 ReportError("class '%s' is trying to extend a native fields class," | 1044 const Script& script = Script::Handle(cls.script()); |
| 1045 ReportError(script, -1, |
| 1046 "class '%s' is trying to extend a native fields class, " |
| 1012 "but library '%s' has no native resolvers", | 1047 "but library '%s' has no native resolvers", |
| 1013 cls_name.ToCString(), lib_name.ToCString()); | 1048 cls_name.ToCString(), lib_name.ToCString()); |
| 1014 } | 1049 } |
| 1015 } | 1050 } |
| 1016 } | 1051 } |
| 1017 | 1052 |
| 1018 | 1053 |
| 1019 bool ClassFinalizer::IsSuperCycleFree(const Class& cls) { | 1054 bool ClassFinalizer::IsSuperCycleFree(const Class& cls) { |
| 1020 Class& test1 = Class::Handle(cls.raw()); | 1055 Class& test1 = Class::Handle(cls.raw()); |
| 1021 Class& test2 = Class::Handle(cls.SuperClass()); | 1056 Class& test2 = Class::Handle(cls.SuperClass()); |
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1081 // remembering interfaces we've visited in each path through the | 1116 // remembering interfaces we've visited in each path through the |
| 1082 // graph. If we visit an interface a second time on a given path, | 1117 // graph. If we visit an interface a second time on a given path, |
| 1083 // we found a loop. | 1118 // we found a loop. |
| 1084 void ClassFinalizer::ResolveInterfaces(const Class& cls, | 1119 void ClassFinalizer::ResolveInterfaces(const Class& cls, |
| 1085 GrowableArray<const Class*>* visited) { | 1120 GrowableArray<const Class*>* visited) { |
| 1086 ASSERT(visited != NULL); | 1121 ASSERT(visited != NULL); |
| 1087 for (int i = 0; i < visited->length(); i++) { | 1122 for (int i = 0; i < visited->length(); i++) { |
| 1088 if ((*visited)[i]->raw() == cls.raw()) { | 1123 if ((*visited)[i]->raw() == cls.raw()) { |
| 1089 // We have already visited interface class 'cls'. We found a cycle. | 1124 // We have already visited interface class 'cls'. We found a cycle. |
| 1090 const String& interface_name = String::Handle(cls.Name()); | 1125 const String& interface_name = String::Handle(cls.Name()); |
| 1091 ReportError("Cyclic reference found for interface '%s'\n", | 1126 const Script& script = Script::Handle(cls.script()); |
| 1127 ReportError(script, -1, |
| 1128 "Cyclic reference found for interface '%s'\n", |
| 1092 interface_name.ToCString()); | 1129 interface_name.ToCString()); |
| 1093 } | 1130 } |
| 1094 } | 1131 } |
| 1095 | 1132 |
| 1096 // If the class/interface has no explicit interfaces, we are done. | 1133 // If the class/interface has no explicit interfaces, we are done. |
| 1097 Array& super_interfaces = Array::Handle(cls.interfaces()); | 1134 Array& super_interfaces = Array::Handle(cls.interfaces()); |
| 1098 if (super_interfaces.Length() == 0) { | 1135 if (super_interfaces.Length() == 0) { |
| 1099 return; | 1136 return; |
| 1100 } | 1137 } |
| 1101 | 1138 |
| 1102 // If cls belongs to core lib or to core lib's implementation, restrictions | 1139 // If cls belongs to core lib or to core lib's implementation, restrictions |
| 1103 // about allowed interfaces are lifted. | 1140 // about allowed interfaces are lifted. |
| 1104 const bool cls_belongs_to_core_lib = | 1141 const bool cls_belongs_to_core_lib = |
| 1105 (cls.library() == Library::CoreLibrary()) || | 1142 (cls.library() == Library::CoreLibrary()) || |
| 1106 (cls.library() == Library::CoreImplLibrary()); | 1143 (cls.library() == Library::CoreImplLibrary()); |
| 1107 | 1144 |
| 1108 // Resolve and check the interfaces of cls. | 1145 // Resolve and check the interfaces of cls. |
| 1109 visited->Add(&cls); | 1146 visited->Add(&cls); |
| 1110 Type& interface = Type::Handle(); | 1147 Type& interface = Type::Handle(); |
| 1111 for (intptr_t i = 0; i < super_interfaces.Length(); i++) { | 1148 for (intptr_t i = 0; i < super_interfaces.Length(); i++) { |
| 1112 interface ^= super_interfaces.At(i); | 1149 interface ^= super_interfaces.At(i); |
| 1113 interface = ResolveType(cls, interface); | 1150 interface = ResolveType(cls, interface); |
| 1114 super_interfaces.SetAt(i, interface); | 1151 super_interfaces.SetAt(i, interface); |
| 1115 if (interface.IsTypeParameter()) { | 1152 if (interface.IsTypeParameter()) { |
| 1116 ReportError("Type parameter '%s' cannot be used as interface\n", | 1153 const Script& script = Script::Handle(cls.script()); |
| 1154 ReportError(script, -1, |
| 1155 "Type parameter '%s' cannot be used as interface\n", |
| 1117 String::Handle(interface.Name()).ToCString()); | 1156 String::Handle(interface.Name()).ToCString()); |
| 1118 } | 1157 } |
| 1119 const Class& interface_class = Class::Handle(interface.type_class()); | 1158 const Class& interface_class = Class::Handle(interface.type_class()); |
| 1120 if (!interface_class.is_interface()) { | 1159 if (!interface_class.is_interface()) { |
| 1121 ReportError("Class '%s' is used where an interface is expected\n", | 1160 const Script& script = Script::Handle(cls.script()); |
| 1161 ReportError(script, -1, |
| 1162 "Class '%s' is used where an interface is expected\n", |
| 1122 String::Handle(interface_class.Name()).ToCString()); | 1163 String::Handle(interface_class.Name()).ToCString()); |
| 1123 } | 1164 } |
| 1124 // Verify that unless cls belongs to core lib, it cannot extend or implement | 1165 // Verify that unless cls belongs to core lib, it cannot extend or implement |
| 1125 // any of bool, num, int, double, String, Function, Dynamic. | 1166 // any of bool, num, int, double, String, Function, Dynamic. |
| 1126 // The exception is signature classes, which are compiler generated and | 1167 // The exception is signature classes, which are compiler generated and |
| 1127 // represent a function type, therefore implementing the Function interface. | 1168 // represent a function type, therefore implementing the Function interface. |
| 1128 if (!cls_belongs_to_core_lib) { | 1169 if (!cls_belongs_to_core_lib) { |
| 1129 if (interface.IsBoolInterface() || | 1170 if (interface.IsBoolInterface() || |
| 1130 interface.IsNumberInterface() || | 1171 interface.IsNumberInterface() || |
| 1131 interface.IsIntInterface() || | 1172 interface.IsIntInterface() || |
| 1132 interface.IsDoubleInterface() || | 1173 interface.IsDoubleInterface() || |
| 1133 interface.IsStringInterface() || | 1174 interface.IsStringInterface() || |
| 1134 (interface.IsFunctionInterface() && !cls.IsSignatureClass()) || | 1175 (interface.IsFunctionInterface() && !cls.IsSignatureClass()) || |
| 1135 interface.IsDynamicType()) { | 1176 interface.IsDynamicType()) { |
| 1136 ReportError("'%s' is not allowed to extend or implement '%s'\n", | 1177 const Script& script = Script::Handle(cls.script()); |
| 1178 ReportError(script, -1, |
| 1179 "'%s' is not allowed to extend or implement '%s'\n", |
| 1137 String::Handle(cls.Name()).ToCString(), | 1180 String::Handle(cls.Name()).ToCString(), |
| 1138 String::Handle(interface_class.Name()).ToCString()); | 1181 String::Handle(interface_class.Name()).ToCString()); |
| 1139 } | 1182 } |
| 1140 } | 1183 } |
| 1141 // Now resolve the super interfaces. | 1184 // Now resolve the super interfaces. |
| 1142 ResolveInterfaces(interface_class, visited); | 1185 ResolveInterfaces(interface_class, visited); |
| 1143 } | 1186 } |
| 1144 visited->RemoveLast(); | 1187 visited->RemoveLast(); |
| 1145 } | 1188 } |
| 1146 | 1189 |
| 1147 | 1190 |
| 1148 // A class is marked as constant if it has one constant constructor. | 1191 // A class is marked as constant if it has one constant constructor. |
| 1149 // A constant class: | 1192 // A constant class: |
| 1150 // - may extend only const classes. | 1193 // - may extend only const classes. |
| 1151 // - has only const instance fields. | 1194 // - has only const instance fields. |
| 1152 // Note: we must check for cycles before checking for const properties. | 1195 // Note: we must check for cycles before checking for const properties. |
| 1153 void ClassFinalizer::CheckForLegalConstClass(const Class& cls) { | 1196 void ClassFinalizer::CheckForLegalConstClass(const Class& cls) { |
| 1154 ASSERT(cls.is_const()); | 1197 ASSERT(cls.is_const()); |
| 1155 const Class& super = Class::Handle(cls.SuperClass()); | 1198 const Class& super = Class::Handle(cls.SuperClass()); |
| 1156 if (!super.IsNull() && !super.is_const()) { | 1199 if (!super.IsNull() && !super.is_const()) { |
| 1157 String& name = String::Handle(super.Name()); | 1200 String& name = String::Handle(super.Name()); |
| 1158 ReportError("superclass '%s' must be const.\n", name.ToCString()); | 1201 const Script& script = Script::Handle(cls.script()); |
| 1202 ReportError(script, -1, |
| 1203 "superclass '%s' must be const.\n", name.ToCString()); |
| 1159 } | 1204 } |
| 1160 const Array& fields_array = Array::Handle(cls.fields()); | 1205 const Array& fields_array = Array::Handle(cls.fields()); |
| 1161 intptr_t len = fields_array.Length(); | 1206 intptr_t len = fields_array.Length(); |
| 1162 Field& field = Field::Handle(); | 1207 Field& field = Field::Handle(); |
| 1163 for (intptr_t i = 0; i < len; i++) { | 1208 for (intptr_t i = 0; i < len; i++) { |
| 1164 field ^= fields_array.At(i); | 1209 field ^= fields_array.At(i); |
| 1165 if (!field.is_static() && !field.is_final()) { | 1210 if (!field.is_static() && !field.is_final()) { |
| 1166 const String& class_name = String::Handle(cls.Name()); | 1211 const String& class_name = String::Handle(cls.Name()); |
| 1167 const String& field_name = String::Handle(field.name()); | 1212 const String& field_name = String::Handle(field.name()); |
| 1168 ReportError("const class '%s' has non-final field '%s'\n", | 1213 const Script& script = Script::Handle(cls.script()); |
| 1214 ReportError(script, field.token_index(), |
| 1215 "const class '%s' has non-final field '%s'\n", |
| 1169 class_name.ToCString(), field_name.ToCString()); | 1216 class_name.ToCString(), field_name.ToCString()); |
| 1170 } | 1217 } |
| 1171 } | 1218 } |
| 1172 } | 1219 } |
| 1173 | 1220 |
| 1174 | 1221 |
| 1175 void ClassFinalizer::PrintClassInformation(const Class& cls) { | 1222 void ClassFinalizer::PrintClassInformation(const Class& cls) { |
| 1176 HANDLESCOPE(); | 1223 HANDLESCOPE(); |
| 1177 const String& class_name = String::Handle(cls.Name()); | 1224 const String& class_name = String::Handle(cls.Name()); |
| 1178 OS::Print("%s '%s'", | 1225 OS::Print("%s '%s'", |
| (...skipping 27 matching lines...) Expand all Loading... |
| 1206 for (intptr_t i = 0; i < len; i++) { | 1253 for (intptr_t i = 0; i < len; i++) { |
| 1207 field ^= fields_array.At(i); | 1254 field ^= fields_array.At(i); |
| 1208 OS::Print(" %s\n", field.ToCString()); | 1255 OS::Print(" %s\n", field.ToCString()); |
| 1209 } | 1256 } |
| 1210 } | 1257 } |
| 1211 | 1258 |
| 1212 | 1259 |
| 1213 void ClassFinalizer::ReportError(const Script& script, | 1260 void ClassFinalizer::ReportError(const Script& script, |
| 1214 intptr_t token_index, | 1261 intptr_t token_index, |
| 1215 const char* format, ...) { | 1262 const char* format, ...) { |
| 1216 static const int kBufferLength = 1024; | 1263 const intptr_t kMessageBufferSize = 512; |
| 1217 Isolate* isolate = Isolate::Current(); | 1264 char message_buffer[kMessageBufferSize]; |
| 1218 ASSERT(isolate != NULL); | |
| 1219 Zone* zone = isolate->current_zone(); | |
| 1220 ASSERT(zone != NULL); | |
| 1221 char* msg_buffer = reinterpret_cast<char*>(zone->Allocate(kBufferLength + 1)); | |
| 1222 | |
| 1223 const String& script_url = String::CheckedHandle(script.url()); | |
| 1224 const int buf_size = 256; | |
| 1225 static char text_buffer[buf_size]; | |
| 1226 intptr_t line, column; | |
| 1227 script.GetTokenLocation(token_index, &line, &column); | |
| 1228 va_list args; | 1265 va_list args; |
| 1229 va_start(args, format); | 1266 va_start(args, format); |
| 1230 OS::VSNPrint(text_buffer, buf_size, format, args); | 1267 Parser::FormatMessage(script, token_index, "Error", |
| 1231 va_end(args); | 1268 message_buffer, kMessageBufferSize, |
| 1232 | 1269 format, args); |
| 1233 intptr_t msg_len = OS::SNPrint(msg_buffer, kBufferLength, | 1270 Isolate::Current()->long_jump_base()->Jump(1, message_buffer); |
| 1234 "'%s': line %d pos %d: %s\n", | |
| 1235 script_url.ToCString(), | |
| 1236 line, column, text_buffer); | |
| 1237 const String& text = String::Handle(script.GetLine(line)); | |
| 1238 ASSERT(!text.IsNull()); | |
| 1239 if (text.Length() < buf_size) { | |
| 1240 OS::SNPrint(msg_buffer + msg_len, (kBufferLength - msg_len), "%s\n%*s\n", | |
| 1241 text.ToCString(), column, "^"); | |
| 1242 } | |
| 1243 isolate->long_jump_base()->Jump(1, msg_buffer); | |
| 1244 UNREACHABLE(); | 1271 UNREACHABLE(); |
| 1245 } | 1272 } |
| 1246 | 1273 |
| 1247 | 1274 |
| 1248 void ClassFinalizer::ReportError(const char* format, ...) { | 1275 void ClassFinalizer::ReportError(const char* format, ...) { |
| 1249 static const int kBufferLength = 1024; | 1276 const intptr_t kMessageBufferSize = 512; |
| 1250 Isolate* isolate = Isolate::Current(); | 1277 char message_buffer[kMessageBufferSize]; |
| 1251 ASSERT(isolate != NULL); | |
| 1252 Zone* zone = isolate->current_zone(); | |
| 1253 ASSERT(zone != NULL); | |
| 1254 char* msg_buffer = reinterpret_cast<char*>(zone->Allocate(kBufferLength + 1)); | |
| 1255 ASSERT(msg_buffer != NULL); | |
| 1256 va_list args; | 1278 va_list args; |
| 1257 va_start(args, format); | 1279 va_start(args, format); |
| 1258 OS::VSNPrint(msg_buffer, kBufferLength, format, args); | 1280 Parser::FormatMessage(Script::Handle(), -1, "Error", |
| 1281 message_buffer, kMessageBufferSize, |
| 1282 format, args); |
| 1259 va_end(args); | 1283 va_end(args); |
| 1260 isolate->long_jump_base()->Jump(1, msg_buffer); | 1284 Isolate::Current()->long_jump_base()->Jump(1, message_buffer); |
| 1261 UNREACHABLE(); | 1285 UNREACHABLE(); |
| 1262 } | 1286 } |
| 1263 | 1287 |
| 1264 void ClassFinalizer::ReportWarning(const char* format, ...) { | 1288 |
| 1289 void ClassFinalizer::ReportWarning(const Script& script, |
| 1290 intptr_t token_index, |
| 1291 const char* format, ...) { |
| 1265 if (FLAG_silent_warnings) return; | 1292 if (FLAG_silent_warnings) return; |
| 1266 static const int kBufferLength = 1024; | 1293 const intptr_t kMessageBufferSize = 512; |
| 1267 Isolate* isolate = Isolate::Current(); | 1294 char message_buffer[kMessageBufferSize]; |
| 1268 ASSERT(isolate != NULL); | |
| 1269 Zone* zone = isolate->current_zone(); | |
| 1270 ASSERT(zone != NULL); | |
| 1271 char* msg_buffer = reinterpret_cast<char*>(zone->Allocate(kBufferLength + 1)); | |
| 1272 ASSERT(msg_buffer != NULL); | |
| 1273 va_list args; | 1295 va_list args; |
| 1274 va_start(args, format); | 1296 va_start(args, format); |
| 1275 OS::VSNPrint(msg_buffer, kBufferLength, format, args); | 1297 Parser::FormatMessage(script, token_index, "Warning", |
| 1298 message_buffer, kMessageBufferSize, |
| 1299 format, args); |
| 1276 va_end(args); | 1300 va_end(args); |
| 1277 if (FLAG_warning_as_error) { | 1301 if (FLAG_warning_as_error) { |
| 1278 isolate->long_jump_base()->Jump(1, msg_buffer); | 1302 Isolate::Current()->long_jump_base()->Jump(1, message_buffer); |
| 1279 UNREACHABLE(); | 1303 UNREACHABLE(); |
| 1280 } else { | 1304 } else { |
| 1281 OS::Print(msg_buffer); | 1305 OS::Print(message_buffer); |
| 1282 } | 1306 } |
| 1283 } | 1307 } |
| 1284 | 1308 |
| 1285 } // namespace dart | 1309 } // namespace dart |
| OLD | NEW |