OLD | NEW |
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 Loading... |
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 Loading... |
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 |
OLD | NEW |