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

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

Issue 735723003: Implement enum types in VM (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 6 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
OLDNEW
1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2013, 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/code_generator.h" 7 #include "vm/code_generator.h"
8 #include "vm/flags.h" 8 #include "vm/flags.h"
9 #include "vm/heap.h" 9 #include "vm/heap.h"
10 #include "vm/isolate.h" 10 #include "vm/isolate.h"
(...skipping 2328 matching lines...) Expand 10 before | Expand all | Expand 10 after
2339 // Run additional checks after all types are finalized. 2339 // Run additional checks after all types are finalized.
2340 if (cls.is_const()) { 2340 if (cls.is_const()) {
2341 CheckForLegalConstClass(cls); 2341 CheckForLegalConstClass(cls);
2342 } 2342 }
2343 if (FLAG_use_cha) { 2343 if (FLAG_use_cha) {
2344 GrowableArray<intptr_t> cids; 2344 GrowableArray<intptr_t> cids;
2345 CollectFinalizedSuperClasses(cls, &cids); 2345 CollectFinalizedSuperClasses(cls, &cids);
2346 CollectImmediateSuperInterfaces(cls, &cids); 2346 CollectImmediateSuperInterfaces(cls, &cids);
2347 RemoveCHAOptimizedCode(cids); 2347 RemoveCHAOptimizedCode(cids);
2348 } 2348 }
2349 if (cls.is_enum_class()) {
2350 AllocateEnumValues(cls);
2351 }
2352 }
2353
2354
2355 // Allocate instances for each enumeration value, and populate the
2356 // static field 'values'.
2357 // By allocating the instances programmatically, we save an implicit final
2358 // getter function object for each enumeration value and for the
2359 // values field. We also don't have to generate the code for these getters
2360 // from thin air (no source code is available).
2361 void ClassFinalizer::AllocateEnumValues(const Class &enum_cls) {
2362 const Field& index_field =
2363 Field::Handle(enum_cls.LookupInstanceField(Symbols::Index()));
2364 ASSERT(!index_field.IsNull());
2365 const Field& values_field =
2366 Field::Handle(enum_cls.LookupStaticField(Symbols::Values()));
2367 ASSERT(!values_field.IsNull());
2368 ASSERT(Instance::Handle(values_field.value()).IsArray());
2369 Array& values_list = Array::Handle(Array::RawCast(values_field.value()));
2370
2371 const Array& fields = Array::Handle(enum_cls.fields());
2372 Field& field = Field::Handle();
2373 Instance& ordinal_value = Instance::Handle();
2374 Instance& enum_value = Instance::Handle();
2375
2376 for (intptr_t i = 0; i < fields.Length(); i++) {
2377 field = Field::RawCast(fields.At(i));
2378 if (!field.is_static()) continue;
2379 ordinal_value = field.value();
2380 // The static fields that need to be initialized with enum instances
2381 // contain the smi value of the ordinal number, which was stored in
2382 // the field by the parser. Other fields contain non-smi values.
2383 if (!ordinal_value.IsSmi()) continue;
2384 enum_value = Instance::New(enum_cls, Heap::kOld);
2385 enum_value.SetField(index_field, ordinal_value);
2386 field.set_value(enum_value);
2387 field.RecordStore(enum_value);
2388 intptr_t ord = Smi::Cast(ordinal_value).Value();
2389 ASSERT(ord < values_list.Length());
2390 values_list.SetAt(ord, enum_value);
2391 }
2392 values_list.MakeImmutable();
2349 } 2393 }
2350 2394
2351 2395
2352 bool ClassFinalizer::IsSuperCycleFree(const Class& cls) { 2396 bool ClassFinalizer::IsSuperCycleFree(const Class& cls) {
2353 Class& test1 = Class::Handle(cls.raw()); 2397 Class& test1 = Class::Handle(cls.raw());
2354 Class& test2 = Class::Handle(cls.SuperClass()); 2398 Class& test2 = Class::Handle(cls.SuperClass());
2355 // A finalized class has been checked for cycles. 2399 // A finalized class has been checked for cycles.
2356 // Using the hare and tortoise algorithm for locating cycles. 2400 // Using the hare and tortoise algorithm for locating cycles.
2357 while (!test1.is_type_finalized() && 2401 while (!test1.is_type_finalized() &&
2358 !test2.IsNull() && !test2.is_type_finalized()) { 2402 !test2.IsNull() && !test2.is_type_finalized()) {
(...skipping 360 matching lines...) Expand 10 before | Expand all | Expand 10 after
2719 ReportError(cls, cls.token_pos(), 2763 ReportError(cls, cls.token_pos(),
2720 "class '%s' may not extend 'dynamic'", 2764 "class '%s' may not extend 'dynamic'",
2721 String::Handle(isolate, cls.Name()).ToCString()); 2765 String::Handle(isolate, cls.Name()).ToCString());
2722 } 2766 }
2723 interface_class = super_type.type_class(); 2767 interface_class = super_type.type_class();
2724 if (interface_class.IsSignatureClass()) { 2768 if (interface_class.IsSignatureClass()) {
2725 ReportError(cls, cls.token_pos(), 2769 ReportError(cls, cls.token_pos(),
2726 "class '%s' may not extend function type alias '%s'", 2770 "class '%s' may not extend function type alias '%s'",
2727 String::Handle(isolate, cls.Name()).ToCString(), 2771 String::Handle(isolate, cls.Name()).ToCString(),
2728 String::Handle(isolate, 2772 String::Handle(isolate,
2729 super_type.UserVisibleName()).ToCString()); 2773 super_type.UserVisibleName()).ToCString());
2774 }
2775 if (interface_class.is_enum_class()) {
2776 ReportError(cls, cls.token_pos(),
2777 "class '%s' may not extend enum '%s'",
2778 String::Handle(isolate, cls.Name()).ToCString(),
2779 String::Handle(isolate, interface_class.Name()).ToCString());
2730 } 2780 }
2731 2781
2732 // If cls belongs to core lib or to core lib's implementation, restrictions 2782 // If cls belongs to core lib or to core lib's implementation, restrictions
2733 // about allowed interfaces are lifted. 2783 // about allowed interfaces are lifted.
2734 if (!cls_belongs_to_core_lib) { 2784 if (!cls_belongs_to_core_lib) {
2735 // Prevent extending core implementation classes. 2785 // Prevent extending core implementation classes.
2736 bool is_error = false; 2786 bool is_error = false;
2737 switch (interface_class.id()) { 2787 switch (interface_class.id()) {
2738 case kNumberCid: 2788 case kNumberCid:
2739 case kIntegerCid: // Class Integer, not int. 2789 case kIntegerCid: // Class Integer, not int.
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
2796 "'dynamic' may not be used as interface"); 2846 "'dynamic' may not be used as interface");
2797 } 2847 }
2798 interface_class = interface.type_class(); 2848 interface_class = interface.type_class();
2799 if (interface_class.IsSignatureClass()) { 2849 if (interface_class.IsSignatureClass()) {
2800 const String& interface_name = String::Handle(isolate, 2850 const String& interface_name = String::Handle(isolate,
2801 interface_class.Name()); 2851 interface_class.Name());
2802 ReportError(cls, cls.token_pos(), 2852 ReportError(cls, cls.token_pos(),
2803 "function type alias '%s' may not be used as interface", 2853 "function type alias '%s' may not be used as interface",
2804 interface_name.ToCString()); 2854 interface_name.ToCString());
2805 } 2855 }
2856 if (interface_class.is_enum_class()) {
2857 const String& interface_name = String::Handle(isolate,
2858 interface_class.Name());
2859 ReportError(cls, cls.token_pos(),
2860 "enum '%s' may not be used as interface",
2861 interface_name.ToCString());
2862 }
2806 // Verify that unless cls belongs to core lib, it cannot extend, implement, 2863 // Verify that unless cls belongs to core lib, it cannot extend, implement,
2807 // or mixin any of Null, bool, num, int, double, String, dynamic. 2864 // or mixin any of Null, bool, num, int, double, String, dynamic.
2808 if (!cls_belongs_to_core_lib) { 2865 if (!cls_belongs_to_core_lib) {
2809 if (interface.IsBoolType() || 2866 if (interface.IsBoolType() ||
2810 interface.IsNullType() || 2867 interface.IsNullType() ||
2811 interface.IsNumberType() || 2868 interface.IsNumberType() ||
2812 interface.IsIntType() || 2869 interface.IsIntType() ||
2813 interface.IsDoubleType() || 2870 interface.IsDoubleType() ||
2814 interface.IsStringType() || 2871 interface.IsStringType() ||
2815 interface.IsDynamicType()) { 2872 interface.IsDynamicType()) {
(...skipping 267 matching lines...) Expand 10 before | Expand all | Expand 10 after
3083 ASSERT(fields_array.Length() == ByteBuffer::NumberOfFields()); 3140 ASSERT(fields_array.Length() == ByteBuffer::NumberOfFields());
3084 field ^= fields_array.At(0); 3141 field ^= fields_array.At(0);
3085 ASSERT(field.Offset() == ByteBuffer::data_offset()); 3142 ASSERT(field.Offset() == ByteBuffer::data_offset());
3086 name ^= field.name(); 3143 name ^= field.name();
3087 expected_name ^= String::New("_data"); 3144 expected_name ^= String::New("_data");
3088 ASSERT(String::EqualsIgnoringPrivateKey(name, expected_name)); 3145 ASSERT(String::EqualsIgnoringPrivateKey(name, expected_name));
3089 #endif 3146 #endif
3090 } 3147 }
3091 3148
3092 } // namespace dart 3149 } // namespace dart
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698