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

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

Issue 2153143002: Rework how enums are implemented and reloaded (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Created 4 years, 5 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
« no previous file with comments | « runtime/lib/core_patch.dart ('k') | runtime/vm/isolate_reload.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 2503 matching lines...) Expand 10 before | Expand all | Expand 10 after
2514 } 2514 }
2515 } 2515 }
2516 2516
2517 2517
2518 // Allocate instances for each enumeration value, and populate the 2518 // Allocate instances for each enumeration value, and populate the
2519 // static field 'values'. 2519 // static field 'values'.
2520 // By allocating the instances programmatically, we save an implicit final 2520 // By allocating the instances programmatically, we save an implicit final
2521 // getter function object for each enumeration value and for the 2521 // getter function object for each enumeration value and for the
2522 // values field. We also don't have to generate the code for these getters 2522 // values field. We also don't have to generate the code for these getters
2523 // from thin air (no source code is available). 2523 // from thin air (no source code is available).
2524 void ClassFinalizer::AllocateEnumValues(const Class &enum_cls) { 2524 void ClassFinalizer::AllocateEnumValues(const Class& enum_cls) {
2525 Thread* thread = Thread::Current(); 2525 Thread* thread = Thread::Current();
2526 Zone* zone = thread->zone(); 2526 Zone* zone = thread->zone();
2527 const Field& index_field = 2527 const Field& index_field =
2528 Field::Handle(zone, enum_cls.LookupInstanceField(Symbols::Index())); 2528 Field::Handle(zone, enum_cls.LookupInstanceField(Symbols::Index()));
2529 ASSERT(!index_field.IsNull()); 2529 ASSERT(!index_field.IsNull());
2530 const Field& name_field = Field::Handle(zone,
2531 enum_cls.LookupInstanceFieldAllowPrivate(Symbols::_name()));
2532 ASSERT(!name_field.IsNull());
2530 const Field& values_field = 2533 const Field& values_field =
2531 Field::Handle(zone, enum_cls.LookupStaticField(Symbols::Values())); 2534 Field::Handle(zone, enum_cls.LookupStaticField(Symbols::Values()));
2532 ASSERT(!values_field.IsNull()); 2535 ASSERT(!values_field.IsNull());
2533 ASSERT(Instance::Handle(zone, values_field.StaticValue()).IsArray()); 2536 ASSERT(Instance::Handle(zone, values_field.StaticValue()).IsArray());
2534 Array& values_list = Array::Handle( 2537 Array& values_list = Array::Handle(
2535 zone, Array::RawCast(values_field.StaticValue())); 2538 zone, Array::RawCast(values_field.StaticValue()));
2536 2539
2537 const Array& fields = Array::Handle(zone, enum_cls.fields()); 2540 const Array& fields = Array::Handle(zone, enum_cls.fields());
2538 Field& field = Field::Handle(zone); 2541 Field& field = Field::Handle(zone);
2539 Instance& ordinal_value = Instance::Handle(zone); 2542 Instance& ordinal_value = Instance::Handle(zone);
2540 Instance& enum_value = Instance::Handle(zone); 2543 Instance& enum_value = Instance::Handle(zone);
2541 2544
2545 const String& enum_name = String::Handle(enum_cls.ScrubbedName());
2546 const String& name_prefix =
2547 String::Handle(String::Concat(enum_name, Symbols::Dot()));
2548
2549 String& enum_ident = String::Handle();
2542 for (intptr_t i = 0; i < fields.Length(); i++) { 2550 for (intptr_t i = 0; i < fields.Length(); i++) {
2543 field = Field::RawCast(fields.At(i)); 2551 field = Field::RawCast(fields.At(i));
2544 if (!field.is_static()) continue; 2552 if (!field.is_static()) continue;
2545 ordinal_value = field.StaticValue(); 2553 ordinal_value = field.StaticValue();
2546 // The static fields that need to be initialized with enum instances 2554 // The static fields that need to be initialized with enum instances
2547 // contain the smi value of the ordinal number, which was stored in 2555 // contain the smi value of the ordinal number, which was stored in
2548 // the field by the parser. Other fields contain non-smi values. 2556 // the field by the parser. Other fields contain non-smi values.
2549 if (!ordinal_value.IsSmi()) continue; 2557 if (!ordinal_value.IsSmi()) continue;
2558 enum_ident = field.name();
2559 // Construct the string returned by toString.
2560 ASSERT(!enum_ident.IsNull());
2561 // For the user-visible name of the enumeration value, we need to
2562 // unmangle private names.
2563 if (enum_ident.CharAt(0) == '_') {
2564 enum_ident = String::ScrubName(enum_ident);
2565 }
2566 enum_ident = Symbols::FromConcat(thread, name_prefix, enum_ident);
2550 enum_value = Instance::New(enum_cls, Heap::kOld); 2567 enum_value = Instance::New(enum_cls, Heap::kOld);
2551 enum_value.SetField(index_field, ordinal_value); 2568 enum_value.SetField(index_field, ordinal_value);
2569 enum_value.SetField(name_field, enum_ident);
2552 const char* error_msg = ""; 2570 const char* error_msg = "";
2553 enum_value = enum_value.CheckAndCanonicalize(thread, &error_msg); 2571 enum_value = enum_value.CheckAndCanonicalize(thread, &error_msg);
2554 ASSERT(!enum_value.IsNull()); 2572 ASSERT(!enum_value.IsNull());
2555 ASSERT(enum_value.IsCanonical()); 2573 ASSERT(enum_value.IsCanonical());
2556 field.SetStaticValue(enum_value, true); 2574 field.SetStaticValue(enum_value, true);
2557 field.RecordStore(enum_value); 2575 field.RecordStore(enum_value);
2558 intptr_t ord = Smi::Cast(ordinal_value).Value(); 2576 intptr_t ord = Smi::Cast(ordinal_value).Value();
2559 ASSERT(ord < values_list.Length()); 2577 ASSERT(ord < values_list.Length());
2560 values_list.SetAt(ord, enum_value); 2578 values_list.SetAt(ord, enum_value);
2561 } 2579 }
(...skipping 762 matching lines...) Expand 10 before | Expand all | Expand 10 after
3324 ASSERT(fields_array.Length() == ByteBuffer::NumberOfFields()); 3342 ASSERT(fields_array.Length() == ByteBuffer::NumberOfFields());
3325 field ^= fields_array.At(0); 3343 field ^= fields_array.At(0);
3326 ASSERT(field.Offset() == ByteBuffer::data_offset()); 3344 ASSERT(field.Offset() == ByteBuffer::data_offset());
3327 name ^= field.name(); 3345 name ^= field.name();
3328 expected_name ^= String::New("_data"); 3346 expected_name ^= String::New("_data");
3329 ASSERT(String::EqualsIgnoringPrivateKey(name, expected_name)); 3347 ASSERT(String::EqualsIgnoringPrivateKey(name, expected_name));
3330 #endif 3348 #endif
3331 } 3349 }
3332 3350
3333 } // namespace dart 3351 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/lib/core_patch.dart ('k') | runtime/vm/isolate_reload.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698