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

Unified 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 side-by-side diff with in-line comments
Download patch
Index: runtime/vm/class_finalizer.cc
===================================================================
--- runtime/vm/class_finalizer.cc (revision 41810)
+++ runtime/vm/class_finalizer.cc (working copy)
@@ -2346,9 +2346,53 @@
CollectImmediateSuperInterfaces(cls, &cids);
RemoveCHAOptimizedCode(cids);
}
+ if (cls.is_enum_class()) {
+ AllocateEnumValues(cls);
+ }
}
+// Allocate instances for each enumeration value, and populate the
+// static field 'values'.
+// By allocating the instances programmatically, we save an implicit final
+// getter function object for each enumeration value and for the
+// values field. We also don't have to generate the code for these getters
+// from thin air (no source code is available).
+void ClassFinalizer::AllocateEnumValues(const Class &enum_cls) {
+ const Field& index_field =
+ Field::Handle(enum_cls.LookupInstanceField(Symbols::Index()));
+ ASSERT(!index_field.IsNull());
+ const Field& values_field =
+ Field::Handle(enum_cls.LookupStaticField(Symbols::Values()));
+ ASSERT(!values_field.IsNull());
+ ASSERT(Instance::Handle(values_field.value()).IsArray());
+ Array& values_list = Array::Handle(Array::RawCast(values_field.value()));
+
+ const Array& fields = Array::Handle(enum_cls.fields());
+ Field& field = Field::Handle();
+ Instance& ordinal_value = Instance::Handle();
+ Instance& enum_value = Instance::Handle();
+
+ for (intptr_t i = 0; i < fields.Length(); i++) {
+ field = Field::RawCast(fields.At(i));
+ if (!field.is_static()) continue;
+ ordinal_value = field.value();
+ // The static fields that need to be initialized with enum instances
+ // contain the smi value of the ordinal number, which was stored in
+ // the field by the parser. Other fields contain non-smi values.
+ if (!ordinal_value.IsSmi()) continue;
+ enum_value = Instance::New(enum_cls, Heap::kOld);
+ enum_value.SetField(index_field, ordinal_value);
+ field.set_value(enum_value);
+ field.RecordStore(enum_value);
+ intptr_t ord = Smi::Cast(ordinal_value).Value();
+ ASSERT(ord < values_list.Length());
+ values_list.SetAt(ord, enum_value);
+ }
+ values_list.MakeImmutable();
+}
+
+
bool ClassFinalizer::IsSuperCycleFree(const Class& cls) {
Class& test1 = Class::Handle(cls.raw());
Class& test2 = Class::Handle(cls.SuperClass());
@@ -2726,8 +2770,14 @@
"class '%s' may not extend function type alias '%s'",
String::Handle(isolate, cls.Name()).ToCString(),
String::Handle(isolate,
- super_type.UserVisibleName()).ToCString());
+ super_type.UserVisibleName()).ToCString());
}
+ if (interface_class.is_enum_class()) {
+ ReportError(cls, cls.token_pos(),
+ "class '%s' may not extend enum '%s'",
+ String::Handle(isolate, cls.Name()).ToCString(),
+ String::Handle(isolate, interface_class.Name()).ToCString());
+ }
// If cls belongs to core lib or to core lib's implementation, restrictions
// about allowed interfaces are lifted.
@@ -2803,6 +2853,13 @@
"function type alias '%s' may not be used as interface",
interface_name.ToCString());
}
+ if (interface_class.is_enum_class()) {
+ const String& interface_name = String::Handle(isolate,
+ interface_class.Name());
+ ReportError(cls, cls.token_pos(),
+ "enum '%s' may not be used as interface",
+ interface_name.ToCString());
+ }
// Verify that unless cls belongs to core lib, it cannot extend, implement,
// or mixin any of Null, bool, num, int, double, String, dynamic.
if (!cls_belongs_to_core_lib) {

Powered by Google App Engine
This is Rietveld 408576698