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 1347 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1358 ReportError(cls, field.token_pos(), | 1358 ReportError(cls, field.token_pos(), |
1359 "field '%s' of class '%s' conflicts with method '%s' " | 1359 "field '%s' of class '%s' conflicts with method '%s' " |
1360 "of super class '%s'", | 1360 "of super class '%s'", |
1361 name.ToCString(), | 1361 name.ToCString(), |
1362 class_name.ToCString(), | 1362 class_name.ToCString(), |
1363 name.ToCString(), | 1363 name.ToCString(), |
1364 super_class_name.ToCString()); | 1364 super_class_name.ToCString()); |
1365 } | 1365 } |
1366 } | 1366 } |
1367 if (field.is_static() && | 1367 if (field.is_static() && |
1368 (field.value() != Object::null()) && | 1368 (field.StaticFieldValue() != Object::null()) && |
1369 (field.value() != Object::sentinel().raw())) { | 1369 (field.StaticFieldValue() != Object::sentinel().raw())) { |
1370 // The parser does not preset the value if the type is a type parameter or | 1370 // The parser does not preset the value if the type is a type parameter or |
1371 // is parameterized unless the value is null. | 1371 // is parameterized unless the value is null. |
1372 Error& error = Error::Handle(Z); | 1372 Error& error = Error::Handle(Z); |
1373 if (type.IsMalformedOrMalbounded()) { | 1373 if (type.IsMalformedOrMalbounded()) { |
1374 error = type.error(); | 1374 error = type.error(); |
1375 } else { | 1375 } else { |
1376 ASSERT(type.IsInstantiated()); | 1376 ASSERT(type.IsInstantiated()); |
1377 } | 1377 } |
1378 const Instance& const_value = Instance::Handle(Z, field.value()); | 1378 const Instance& const_value = |
| 1379 Instance::Handle(Z, field.StaticFieldValue()); |
1379 if (!error.IsNull() || | 1380 if (!error.IsNull() || |
1380 (!type.IsDynamicType() && | 1381 (!type.IsDynamicType() && |
1381 !const_value.IsInstanceOf(type, | 1382 !const_value.IsInstanceOf(type, |
1382 Object::null_type_arguments(), | 1383 Object::null_type_arguments(), |
1383 &error))) { | 1384 &error))) { |
1384 if (Isolate::Current()->flags().error_on_bad_type()) { | 1385 if (Isolate::Current()->flags().error_on_bad_type()) { |
1385 const AbstractType& const_value_type = AbstractType::Handle( | 1386 const AbstractType& const_value_type = AbstractType::Handle( |
1386 Z, const_value.GetType()); | 1387 Z, const_value.GetType()); |
1387 const String& const_value_type_name = String::Handle( | 1388 const String& const_value_type_name = String::Handle( |
1388 Z, const_value_type.UserVisibleName()); | 1389 Z, const_value_type.UserVisibleName()); |
(...skipping 21 matching lines...) Expand all Loading... |
1410 /* is_static = */ true, | 1411 /* is_static = */ true, |
1411 /* is_const = */ field.is_const(), | 1412 /* is_const = */ field.is_const(), |
1412 /* is_abstract = */ false, | 1413 /* is_abstract = */ false, |
1413 /* is_external = */ false, | 1414 /* is_external = */ false, |
1414 /* is_native = */ false, | 1415 /* is_native = */ false, |
1415 cls, | 1416 cls, |
1416 field.token_pos())); | 1417 field.token_pos())); |
1417 getter.set_result_type(type); | 1418 getter.set_result_type(type); |
1418 getter.set_is_debuggable(false); | 1419 getter.set_is_debuggable(false); |
1419 cls.AddFunction(getter); | 1420 cls.AddFunction(getter); |
1420 field.set_value(Object::sentinel()); | 1421 field.SetStaticFieldValue(Object::sentinel(), true); |
1421 } | 1422 } |
1422 } | 1423 } |
1423 } | 1424 } |
1424 } | 1425 } |
1425 // Collect interfaces, super interfaces, and super classes of this class. | 1426 // Collect interfaces, super interfaces, and super classes of this class. |
1426 GrowableArray<const Class*> interfaces(Z, 4); | 1427 GrowableArray<const Class*> interfaces(Z, 4); |
1427 CollectInterfaces(cls, &interfaces); | 1428 CollectInterfaces(cls, &interfaces); |
1428 // Include superclasses in list of interfaces and super interfaces. | 1429 // Include superclasses in list of interfaces and super interfaces. |
1429 super_class = cls.SuperClass(); | 1430 super_class = cls.SuperClass(); |
1430 while (!super_class.IsNull()) { | 1431 while (!super_class.IsNull()) { |
(...skipping 995 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2426 // getter function object for each enumeration value and for the | 2427 // getter function object for each enumeration value and for the |
2427 // values field. We also don't have to generate the code for these getters | 2428 // values field. We also don't have to generate the code for these getters |
2428 // from thin air (no source code is available). | 2429 // from thin air (no source code is available). |
2429 void ClassFinalizer::AllocateEnumValues(const Class &enum_cls) { | 2430 void ClassFinalizer::AllocateEnumValues(const Class &enum_cls) { |
2430 const Field& index_field = | 2431 const Field& index_field = |
2431 Field::Handle(enum_cls.LookupInstanceField(Symbols::Index())); | 2432 Field::Handle(enum_cls.LookupInstanceField(Symbols::Index())); |
2432 ASSERT(!index_field.IsNull()); | 2433 ASSERT(!index_field.IsNull()); |
2433 const Field& values_field = | 2434 const Field& values_field = |
2434 Field::Handle(enum_cls.LookupStaticField(Symbols::Values())); | 2435 Field::Handle(enum_cls.LookupStaticField(Symbols::Values())); |
2435 ASSERT(!values_field.IsNull()); | 2436 ASSERT(!values_field.IsNull()); |
2436 ASSERT(Instance::Handle(values_field.value()).IsArray()); | 2437 ASSERT(Instance::Handle(values_field.StaticFieldValue()).IsArray()); |
2437 Array& values_list = Array::Handle(Array::RawCast(values_field.value())); | 2438 Array& values_list = Array::Handle( |
| 2439 Array::RawCast(values_field.StaticFieldValue())); |
2438 | 2440 |
2439 const Array& fields = Array::Handle(enum_cls.fields()); | 2441 const Array& fields = Array::Handle(enum_cls.fields()); |
2440 Field& field = Field::Handle(); | 2442 Field& field = Field::Handle(); |
2441 Instance& ordinal_value = Instance::Handle(); | 2443 Instance& ordinal_value = Instance::Handle(); |
2442 Instance& enum_value = Instance::Handle(); | 2444 Instance& enum_value = Instance::Handle(); |
2443 | 2445 |
2444 for (intptr_t i = 0; i < fields.Length(); i++) { | 2446 for (intptr_t i = 0; i < fields.Length(); i++) { |
2445 field = Field::RawCast(fields.At(i)); | 2447 field = Field::RawCast(fields.At(i)); |
2446 if (!field.is_static()) continue; | 2448 if (!field.is_static()) continue; |
2447 ordinal_value = field.value(); | 2449 ordinal_value = field.StaticFieldValue(); |
2448 // The static fields that need to be initialized with enum instances | 2450 // The static fields that need to be initialized with enum instances |
2449 // contain the smi value of the ordinal number, which was stored in | 2451 // contain the smi value of the ordinal number, which was stored in |
2450 // the field by the parser. Other fields contain non-smi values. | 2452 // the field by the parser. Other fields contain non-smi values. |
2451 if (!ordinal_value.IsSmi()) continue; | 2453 if (!ordinal_value.IsSmi()) continue; |
2452 enum_value = Instance::New(enum_cls, Heap::kOld); | 2454 enum_value = Instance::New(enum_cls, Heap::kOld); |
2453 enum_value.SetField(index_field, ordinal_value); | 2455 enum_value.SetField(index_field, ordinal_value); |
2454 const char* error_msg = ""; | 2456 const char* error_msg = ""; |
2455 enum_value = enum_value.CheckAndCanonicalize(&error_msg); | 2457 enum_value = enum_value.CheckAndCanonicalize(&error_msg); |
2456 if (enum_value.IsNull()) { | 2458 if (enum_value.IsNull()) { |
2457 ReportError(enum_cls, enum_cls.token_pos(), "Failed finalizing values."); | 2459 ReportError(enum_cls, enum_cls.token_pos(), "Failed finalizing values."); |
2458 UNREACHABLE(); | 2460 UNREACHABLE(); |
2459 } | 2461 } |
2460 ASSERT(enum_value.IsCanonical()); | 2462 ASSERT(enum_value.IsCanonical()); |
2461 field.set_value(enum_value); | 2463 field.SetStaticFieldValue(enum_value, true); |
2462 field.RecordStore(enum_value); | 2464 field.RecordStore(enum_value); |
2463 intptr_t ord = Smi::Cast(ordinal_value).Value(); | 2465 intptr_t ord = Smi::Cast(ordinal_value).Value(); |
2464 ASSERT(ord < values_list.Length()); | 2466 ASSERT(ord < values_list.Length()); |
2465 values_list.SetAt(ord, enum_value); | 2467 values_list.SetAt(ord, enum_value); |
2466 } | 2468 } |
2467 values_list.MakeImmutable(); | 2469 values_list.MakeImmutable(); |
2468 } | 2470 } |
2469 | 2471 |
2470 | 2472 |
2471 bool ClassFinalizer::IsSuperCycleFree(const Class& cls) { | 2473 bool ClassFinalizer::IsSuperCycleFree(const Class& cls) { |
(...skipping 694 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3166 cid <= kTypedDataFloat32x4ArrayViewCid; | 3168 cid <= kTypedDataFloat32x4ArrayViewCid; |
3167 cid++) { | 3169 cid++) { |
3168 cls = class_table.At(cid); // Get the TypedDataView class. | 3170 cls = class_table.At(cid); // Get the TypedDataView class. |
3169 error = cls.EnsureIsFinalized(isolate); | 3171 error = cls.EnsureIsFinalized(isolate); |
3170 ASSERT(error.IsNull()); | 3172 ASSERT(error.IsNull()); |
3171 cls = cls.SuperClass(); // Get it's super class '_TypedListView'. | 3173 cls = cls.SuperClass(); // Get it's super class '_TypedListView'. |
3172 cls = cls.SuperClass(); | 3174 cls = cls.SuperClass(); |
3173 fields_array ^= cls.fields(); | 3175 fields_array ^= cls.fields(); |
3174 ASSERT(fields_array.Length() == TypedDataView::NumberOfFields()); | 3176 ASSERT(fields_array.Length() == TypedDataView::NumberOfFields()); |
3175 field ^= fields_array.At(0); | 3177 field ^= fields_array.At(0); |
3176 ASSERT(field.Offset() == TypedDataView::data_offset()); | 3178 ASSERT(field.InstanceFieldOffset() == TypedDataView::data_offset()); |
3177 name ^= field.name(); | 3179 name ^= field.name(); |
3178 expected_name ^= String::New("_typedData"); | 3180 expected_name ^= String::New("_typedData"); |
3179 ASSERT(String::EqualsIgnoringPrivateKey(name, expected_name)); | 3181 ASSERT(String::EqualsIgnoringPrivateKey(name, expected_name)); |
3180 field ^= fields_array.At(1); | 3182 field ^= fields_array.At(1); |
3181 ASSERT(field.Offset() == TypedDataView::offset_in_bytes_offset()); | 3183 ASSERT(field.InstanceFieldOffset() == |
| 3184 TypedDataView::offset_in_bytes_offset()); |
3182 name ^= field.name(); | 3185 name ^= field.name(); |
3183 ASSERT(name.Equals("offsetInBytes")); | 3186 ASSERT(name.Equals("offsetInBytes")); |
3184 field ^= fields_array.At(2); | 3187 field ^= fields_array.At(2); |
3185 ASSERT(field.Offset() == TypedDataView::length_offset()); | 3188 ASSERT(field.InstanceFieldOffset() == TypedDataView::length_offset()); |
3186 name ^= field.name(); | 3189 name ^= field.name(); |
3187 ASSERT(name.Equals("length")); | 3190 ASSERT(name.Equals("length")); |
3188 } | 3191 } |
3189 | 3192 |
3190 // Now verify field offsets of '_ByteDataView' class. | 3193 // Now verify field offsets of '_ByteDataView' class. |
3191 cls = class_table.At(kByteDataViewCid); | 3194 cls = class_table.At(kByteDataViewCid); |
3192 error = cls.EnsureIsFinalized(isolate); | 3195 error = cls.EnsureIsFinalized(isolate); |
3193 ASSERT(error.IsNull()); | 3196 ASSERT(error.IsNull()); |
3194 fields_array ^= cls.fields(); | 3197 fields_array ^= cls.fields(); |
3195 ASSERT(fields_array.Length() == TypedDataView::NumberOfFields()); | 3198 ASSERT(fields_array.Length() == TypedDataView::NumberOfFields()); |
3196 field ^= fields_array.At(0); | 3199 field ^= fields_array.At(0); |
3197 ASSERT(field.Offset() == TypedDataView::data_offset()); | 3200 ASSERT(field.InstanceFieldOffset() == TypedDataView::data_offset()); |
3198 name ^= field.name(); | 3201 name ^= field.name(); |
3199 expected_name ^= String::New("_typedData"); | 3202 expected_name ^= String::New("_typedData"); |
3200 ASSERT(String::EqualsIgnoringPrivateKey(name, expected_name)); | 3203 ASSERT(String::EqualsIgnoringPrivateKey(name, expected_name)); |
3201 field ^= fields_array.At(1); | 3204 field ^= fields_array.At(1); |
3202 ASSERT(field.Offset() == TypedDataView::offset_in_bytes_offset()); | 3205 ASSERT(field.InstanceFieldOffset() == |
| 3206 TypedDataView::offset_in_bytes_offset()); |
3203 name ^= field.name(); | 3207 name ^= field.name(); |
3204 expected_name ^= String::New("_offset"); | 3208 expected_name ^= String::New("_offset"); |
3205 ASSERT(String::EqualsIgnoringPrivateKey(name, expected_name)); | 3209 ASSERT(String::EqualsIgnoringPrivateKey(name, expected_name)); |
3206 field ^= fields_array.At(2); | 3210 field ^= fields_array.At(2); |
3207 ASSERT(field.Offset() == TypedDataView::length_offset()); | 3211 ASSERT(field.InstanceFieldOffset() == TypedDataView::length_offset()); |
3208 name ^= field.name(); | 3212 name ^= field.name(); |
3209 ASSERT(name.Equals("length")); | 3213 ASSERT(name.Equals("length")); |
3210 | 3214 |
3211 // Now verify field offsets of '_ByteBuffer' class. | 3215 // Now verify field offsets of '_ByteBuffer' class. |
3212 cls = class_table.At(kByteBufferCid); | 3216 cls = class_table.At(kByteBufferCid); |
3213 error = cls.EnsureIsFinalized(isolate); | 3217 error = cls.EnsureIsFinalized(isolate); |
3214 ASSERT(error.IsNull()); | 3218 ASSERT(error.IsNull()); |
3215 fields_array ^= cls.fields(); | 3219 fields_array ^= cls.fields(); |
3216 ASSERT(fields_array.Length() == ByteBuffer::NumberOfFields()); | 3220 ASSERT(fields_array.Length() == ByteBuffer::NumberOfFields()); |
3217 field ^= fields_array.At(0); | 3221 field ^= fields_array.At(0); |
3218 ASSERT(field.Offset() == ByteBuffer::data_offset()); | 3222 ASSERT(field.InstanceFieldOffset() == ByteBuffer::data_offset()); |
3219 name ^= field.name(); | 3223 name ^= field.name(); |
3220 expected_name ^= String::New("_data"); | 3224 expected_name ^= String::New("_data"); |
3221 ASSERT(String::EqualsIgnoringPrivateKey(name, expected_name)); | 3225 ASSERT(String::EqualsIgnoringPrivateKey(name, expected_name)); |
3222 #endif | 3226 #endif |
3223 } | 3227 } |
3224 | 3228 |
3225 } // namespace dart | 3229 } // namespace dart |
OLD | NEW |