OLD | NEW |
---|---|
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, 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/object.h" | 5 #include "vm/object.h" |
6 | 6 |
7 #include "platform/assert.h" | 7 #include "platform/assert.h" |
8 #include "vm/assembler.h" | 8 #include "vm/assembler.h" |
9 #include "vm/bigint_operations.h" | 9 #include "vm/bigint_operations.h" |
10 #include "vm/bootstrap.h" | 10 #include "vm/bootstrap.h" |
(...skipping 364 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
375 unwind_error_class_ = cls.raw(); | 375 unwind_error_class_ = cls.raw(); |
376 | 376 |
377 ASSERT(class_class() != null_); | 377 ASSERT(class_class() != null_); |
378 } | 378 } |
379 | 379 |
380 | 380 |
381 RawClass* Object::CreateAndRegisterInterface(const char* cname, | 381 RawClass* Object::CreateAndRegisterInterface(const char* cname, |
382 const Script& script, | 382 const Script& script, |
383 const Library& lib) { | 383 const Library& lib) { |
384 const String& name = String::Handle(String::NewSymbol(cname)); | 384 const String& name = String::Handle(String::NewSymbol(cname)); |
385 const Class& cls = Class::Handle(Class::NewInterface(name, script)); | 385 const intptr_t kPos = 0; // Dummy token index for unspecified position. |
386 const Class& cls = Class::Handle(Class::NewInterface(name, script, kPos)); | |
386 lib.AddClass(cls); | 387 lib.AddClass(cls); |
387 return cls.raw(); | 388 return cls.raw(); |
388 } | 389 } |
389 | 390 |
390 | 391 |
391 void Object::RegisterClass(const Class& cls, | 392 void Object::RegisterClass(const Class& cls, |
392 const char* cname, | 393 const char* cname, |
393 const Script& script, | 394 const Script& script, |
394 const Library& lib) { | 395 const Library& lib) { |
395 const String& name = String::Handle(String::NewSymbol(cname)); | 396 const String& name = String::Handle(String::NewSymbol(cname)); |
(...skipping 418 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
814 // A signature class extends class Instance and is parameterized in the same | 815 // A signature class extends class Instance and is parameterized in the same |
815 // way as the owner class of its non-static signature function. | 816 // way as the owner class of its non-static signature function. |
816 // It is not type parameterized if its signature function is static. | 817 // It is not type parameterized if its signature function is static. |
817 // See Class::NewSignatureClass() for the setup of its type parameters. | 818 // See Class::NewSignatureClass() for the setup of its type parameters. |
818 // During type finalization, the type arguments of the super class of the | 819 // During type finalization, the type arguments of the super class of the |
819 // owner class of its signature function will be prepended to the type | 820 // owner class of its signature function will be prepended to the type |
820 // argument vector. Therefore, we only need to set the type arguments | 821 // argument vector. Therefore, we only need to set the type arguments |
821 // matching the type parameters here. | 822 // matching the type parameters here. |
822 if (num_type_params > 0) { | 823 if (num_type_params > 0) { |
823 const Array& type_params = Array::Handle(type_parameters()); | 824 const Array& type_params = Array::Handle(type_parameters()); |
825 // TODO(regis): Simply use the type parameters as type arguments, once type | |
826 // parameters are stored as an array of TypeParameter, rather than String. | |
824 signature_type_arguments = TypeArguments::New(num_type_params); | 827 signature_type_arguments = TypeArguments::New(num_type_params); |
825 String& type_param_name = String::Handle(); | 828 String& type_param_name = String::Handle(); |
826 AbstractType& type_param = AbstractType::Handle(); | 829 AbstractType& type_param = AbstractType::Handle(); |
827 for (int i = 0; i < num_type_params; i++) { | 830 for (int i = 0; i < num_type_params; i++) { |
828 type_param_name ^= type_params.At(i); | 831 type_param_name ^= type_params.At(i); |
829 type_param = AbstractType::NewTypeParameter(i, type_param_name); | 832 // TODO(regis): Use dummy token index 1 for now; see TODO above. |
siva
2012/02/06 18:13:08
The comment says use dummy token index 1 but in th
regis
2012/02/06 19:43:16
I tried to use 0 for a non-existing source and 1 f
| |
833 type_param = AbstractType::NewTypeParameter(i, type_param_name, 1); | |
830 signature_type_arguments.SetTypeAt(i, type_param); | 834 signature_type_arguments.SetTypeAt(i, type_param); |
831 } | 835 } |
832 } | 836 } |
833 const Type& signature_type = Type::Handle( | 837 const Type& signature_type = Type::Handle( |
834 Type::New(*this, signature_type_arguments)); | 838 Type::New(*this, signature_type_arguments, token_index())); |
835 | 839 |
836 // Return the still unfinalized signature type. | 840 // Return the still unfinalized signature type. |
837 ASSERT(!signature_type.IsFinalized()); | 841 ASSERT(!signature_type.IsFinalized()); |
838 return signature_type.raw(); | 842 return signature_type.raw(); |
839 } | 843 } |
840 | 844 |
841 | 845 |
842 template <class FakeObject> | 846 template <class FakeObject> |
843 RawClass* Class::New() { | 847 RawClass* Class::New() { |
844 Class& class_class = Class::Handle(Object::class_class()); | 848 Class& class_class = Class::Handle(Object::class_class()); |
(...skipping 15 matching lines...) Expand all Loading... | |
860 result.set_instance_size(FakeObject::InstanceSize()); | 864 result.set_instance_size(FakeObject::InstanceSize()); |
861 result.set_next_field_offset(FakeObject::InstanceSize()); | 865 result.set_next_field_offset(FakeObject::InstanceSize()); |
862 result.set_instance_kind(FakeObject::kInstanceKind); | 866 result.set_instance_kind(FakeObject::kInstanceKind); |
863 result.raw_ptr()->is_const_ = false; | 867 result.raw_ptr()->is_const_ = false; |
864 result.raw_ptr()->is_interface_ = false; | 868 result.raw_ptr()->is_interface_ = false; |
865 // VM backed classes are almost ready: run checks and resolve class | 869 // VM backed classes are almost ready: run checks and resolve class |
866 // references, but do not recompute size. | 870 // references, but do not recompute size. |
867 result.raw_ptr()->class_state_ = RawClass::kPreFinalized; | 871 result.raw_ptr()->class_state_ = RawClass::kPreFinalized; |
868 result.raw_ptr()->type_arguments_instance_field_offset_ = kNoTypeArguments; | 872 result.raw_ptr()->type_arguments_instance_field_offset_ = kNoTypeArguments; |
869 result.raw_ptr()->num_native_fields_ = 0; | 873 result.raw_ptr()->num_native_fields_ = 0; |
874 const intptr_t kPos = 0; // Dummy token index for unspecified position. | |
siva
2012/02/06 18:13:08
Ditto comment regarding dummy token index.
regis
2012/02/06 19:43:16
Done.
| |
875 result.raw_ptr()->token_index_ = kPos; | |
870 result.InitEmptyFields(); | 876 result.InitEmptyFields(); |
871 return result.raw(); | 877 return result.raw(); |
872 } | 878 } |
873 | 879 |
874 | 880 |
875 // Initialize class fields of type Array with empty array. | 881 // Initialize class fields of type Array with empty array. |
876 void Class::InitEmptyFields() { | 882 void Class::InitEmptyFields() { |
877 const Array& empty_array = Array::Handle(Array::Empty()); | 883 const Array& empty_array = Array::Handle(Array::Empty()); |
878 if (empty_array.IsNull()) { | 884 if (empty_array.IsNull()) { |
879 // The empty array has not been initialized yet. | 885 // The empty array has not been initialized yet. |
(...skipping 137 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1017 } | 1023 } |
1018 | 1024 |
1019 | 1025 |
1020 void Class::set_factory_class(const Object& value) const { | 1026 void Class::set_factory_class(const Object& value) const { |
1021 StorePointer(&raw_ptr()->factory_class_, value.raw()); | 1027 StorePointer(&raw_ptr()->factory_class_, value.raw()); |
1022 } | 1028 } |
1023 | 1029 |
1024 | 1030 |
1025 // Return a TypeParameter if the type_name is a type parameter of this class. | 1031 // Return a TypeParameter if the type_name is a type parameter of this class. |
1026 // Return null otherwise. | 1032 // Return null otherwise. |
1027 RawTypeParameter* Class::LookupTypeParameter(const String& type_name) const { | 1033 RawTypeParameter* Class::LookupTypeParameter(const String& type_name, |
1034 intptr_t token_index) const { | |
1028 ASSERT(!type_name.IsNull()); | 1035 ASSERT(!type_name.IsNull()); |
1029 const Array& type_params = Array::Handle(type_parameters()); | 1036 const Array& type_params = Array::Handle(type_parameters()); |
1030 if (!type_params.IsNull()) { | 1037 if (!type_params.IsNull()) { |
1031 intptr_t num_type_params = type_params.Length(); | 1038 intptr_t num_type_params = type_params.Length(); |
1032 String& type_param = String::Handle(); | 1039 String& type_param = String::Handle(); |
1033 for (intptr_t i = 0; i < num_type_params; i++) { | 1040 for (intptr_t i = 0; i < num_type_params; i++) { |
1034 type_param ^= type_params.At(i); | 1041 type_param ^= type_params.At(i); |
1035 if (type_param.Equals(type_name)) { | 1042 if (type_param.Equals(type_name)) { |
1036 return TypeParameter::New(i, type_name); | 1043 return TypeParameter::New(i, type_name, token_index); |
1037 } | 1044 } |
1038 } | 1045 } |
1039 } | 1046 } |
1040 return TypeParameter::null(); | 1047 return TypeParameter::null(); |
1041 } | 1048 } |
1042 | 1049 |
1043 | 1050 |
1044 void Class::CalculateFieldOffsets() const { | 1051 void Class::CalculateFieldOffsets() const { |
1045 Array& flds = Array::Handle(fields()); | 1052 Array& flds = Array::Handle(fields()); |
1046 const Class& super = Class::Handle(SuperClass()); | 1053 const Class& super = Class::Handle(SuperClass()); |
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1107 // Only static const fields may contain the Object::sentinel value. | 1114 // Only static const fields may contain the Object::sentinel value. |
1108 ASSERT(!(field.is_static() && field.is_final()) || | 1115 ASSERT(!(field.is_static() && field.is_final()) || |
1109 (field.value() == Object::sentinel())); | 1116 (field.value() == Object::sentinel())); |
1110 } | 1117 } |
1111 // The value of static fields is already initialized to null. | 1118 // The value of static fields is already initialized to null. |
1112 StorePointer(&raw_ptr()->fields_, value.raw()); | 1119 StorePointer(&raw_ptr()->fields_, value.raw()); |
1113 } | 1120 } |
1114 | 1121 |
1115 | 1122 |
1116 template <class FakeInstance> | 1123 template <class FakeInstance> |
1117 RawClass* Class::New(const String& name, const Script& script) { | 1124 RawClass* Class::New(const String& name, |
1125 const Script& script, | |
1126 intptr_t token_index) { | |
1127 ASSERT(token_index >= 0); | |
1118 Class& class_class = Class::Handle(Object::class_class()); | 1128 Class& class_class = Class::Handle(Object::class_class()); |
1119 Class& result = Class::Handle(); | 1129 Class& result = Class::Handle(); |
1120 { | 1130 { |
1121 RawObject* raw = Object::Allocate(class_class, | 1131 RawObject* raw = Object::Allocate(class_class, |
1122 Class::InstanceSize(), | 1132 Class::InstanceSize(), |
1123 Heap::kOld); | 1133 Heap::kOld); |
1124 NoGCScope no_gc; | 1134 NoGCScope no_gc; |
1125 result ^= raw; | 1135 result ^= raw; |
1126 } | 1136 } |
1127 FakeInstance fake; | 1137 FakeInstance fake; |
1128 ASSERT(fake.IsInstance()); | 1138 ASSERT(fake.IsInstance()); |
1129 result.set_handle_vtable(fake.vtable()); | 1139 result.set_handle_vtable(fake.vtable()); |
1130 result.set_instance_size(FakeInstance::InstanceSize()); | 1140 result.set_instance_size(FakeInstance::InstanceSize()); |
1131 result.set_next_field_offset(FakeInstance::InstanceSize()); | 1141 result.set_next_field_offset(FakeInstance::InstanceSize()); |
1132 result.set_instance_kind(FakeInstance::kInstanceKind); | 1142 result.set_instance_kind(FakeInstance::kInstanceKind); |
1133 result.set_name(name); | 1143 result.set_name(name); |
1134 result.set_script(script); | 1144 result.set_script(script); |
1145 result.set_token_index(token_index); | |
1135 result.raw_ptr()->is_const_ = false; | 1146 result.raw_ptr()->is_const_ = false; |
1136 result.raw_ptr()->is_interface_ = false; | 1147 result.raw_ptr()->is_interface_ = false; |
1137 result.raw_ptr()->class_state_ = RawClass::kAllocated; | 1148 result.raw_ptr()->class_state_ = RawClass::kAllocated; |
1138 result.raw_ptr()->type_arguments_instance_field_offset_ = kNoTypeArguments; | 1149 result.raw_ptr()->type_arguments_instance_field_offset_ = kNoTypeArguments; |
1139 result.raw_ptr()->num_native_fields_ = 0; | 1150 result.raw_ptr()->num_native_fields_ = 0; |
1140 result.InitEmptyFields(); | 1151 result.InitEmptyFields(); |
1141 return result.raw(); | 1152 return result.raw(); |
1142 } | 1153 } |
1143 | 1154 |
1144 | 1155 |
1145 RawClass* Class::New(const String& name, const Script& script) { | 1156 RawClass* Class::New(const String& name, |
1146 Class& result = Class::Handle(New<Instance>(name, script)); | 1157 const Script& script, |
1158 intptr_t token_index) { | |
1159 Class& result = Class::Handle(New<Instance>(name, script, token_index)); | |
1147 return result.raw(); | 1160 return result.raw(); |
1148 } | 1161 } |
1149 | 1162 |
1150 | 1163 |
1151 RawClass* Class::NewInterface(const String& name, const Script& script) { | 1164 RawClass* Class::NewInterface(const String& name, |
1152 Class& result = Class::Handle(New<Instance>(name, script)); | 1165 const Script& script, |
1166 intptr_t token_index) { | |
1167 Class& result = Class::Handle(New<Instance>(name, script, token_index)); | |
1153 result.set_is_interface(); | 1168 result.set_is_interface(); |
1154 return result.raw(); | 1169 return result.raw(); |
1155 } | 1170 } |
1156 | 1171 |
1157 | 1172 |
1158 RawClass* Class::NewSignatureClass(const String& name, | 1173 RawClass* Class::NewSignatureClass(const String& name, |
1159 const Function& signature_function, | 1174 const Function& signature_function, |
1160 const Script& script) { | 1175 const Script& script) { |
1161 ASSERT(!signature_function.IsNull()); | 1176 ASSERT(!signature_function.IsNull()); |
1162 const Class& owner_class = Class::Handle(signature_function.owner()); | 1177 const Class& owner_class = Class::Handle(signature_function.owner()); |
1163 ASSERT(!owner_class.IsNull()); | 1178 ASSERT(!owner_class.IsNull()); |
1164 Array& type_parameters = Array::Handle(); | 1179 Array& type_parameters = Array::Handle(); |
1165 TypeArguments& type_parameter_extends = TypeArguments::Handle(); | 1180 TypeArguments& type_parameter_extends = TypeArguments::Handle(); |
1166 // A signature class extends class Instance and is parameterized in the same | 1181 // A signature class extends class Instance and is parameterized in the same |
1167 // way as the owner class of its non-static signature function. | 1182 // way as the owner class of its non-static signature function. |
1168 // It is not type parameterized if its signature function is static. | 1183 // It is not type parameterized if its signature function is static. |
1169 if (!signature_function.is_static()) { | 1184 if (!signature_function.is_static()) { |
1170 if ((owner_class.NumTypeParameters() > 0) && | 1185 if ((owner_class.NumTypeParameters() > 0) && |
1171 !signature_function.HasInstantiatedSignature()) { | 1186 !signature_function.HasInstantiatedSignature()) { |
1172 type_parameters = owner_class.type_parameters(); | 1187 type_parameters = owner_class.type_parameters(); |
1173 type_parameter_extends = owner_class.type_parameter_extends(); | 1188 type_parameter_extends = owner_class.type_parameter_extends(); |
1174 } | 1189 } |
1175 } | 1190 } |
1176 Class& result = Class::Handle(New<Closure>(name, script)); | 1191 const intptr_t token_index = signature_function.token_index(); |
1192 Class& result = Class::Handle(New<Closure>(name, script, token_index)); | |
1177 const Type& super_type = Type::Handle(Type::ObjectType()); | 1193 const Type& super_type = Type::Handle(Type::ObjectType()); |
1178 ASSERT(!super_type.IsNull()); | 1194 ASSERT(!super_type.IsNull()); |
1179 result.set_super_type(super_type); | 1195 result.set_super_type(super_type); |
1180 result.set_signature_function(signature_function); | 1196 result.set_signature_function(signature_function); |
1181 result.set_type_parameters(type_parameters); | 1197 result.set_type_parameters(type_parameters); |
1182 result.set_type_parameter_extends(type_parameter_extends); | 1198 result.set_type_parameter_extends(type_parameter_extends); |
1183 result.SetFields(Array::Handle(Array::Empty())); | 1199 result.SetFields(Array::Handle(Array::Empty())); |
1184 result.SetFunctions(Array::Handle(Array::Empty())); | 1200 result.SetFunctions(Array::Handle(Array::Empty())); |
1185 // Implements interface "Function". | 1201 // Implements interface "Function". |
1186 const Type& function_interface = Type::Handle(Type::FunctionInterface()); | 1202 const Type& function_interface = Type::Handle(Type::FunctionInterface()); |
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1269 } | 1285 } |
1270 return Class::null(); | 1286 return Class::null(); |
1271 } | 1287 } |
1272 | 1288 |
1273 | 1289 |
1274 RawClass* Class::NewNativeWrapper(Library* library, | 1290 RawClass* Class::NewNativeWrapper(Library* library, |
1275 const String& name, | 1291 const String& name, |
1276 int field_count) { | 1292 int field_count) { |
1277 Class& cls = Class::Handle(library->LookupClass(name)); | 1293 Class& cls = Class::Handle(library->LookupClass(name)); |
1278 if (cls.IsNull()) { | 1294 if (cls.IsNull()) { |
1279 cls = New<Instance>(name, Script::Handle()); | 1295 const intptr_t kPos = 0; // Dummy token index for unspecified position. |
siva
2012/02/06 18:13:08
Ditto comment (0 or 1)?
regis
2012/02/06 19:43:16
Done.
| |
1296 cls = New<Instance>(name, Script::Handle(), kPos); | |
1280 cls.SetFields(Array::Handle(Array::Empty())); | 1297 cls.SetFields(Array::Handle(Array::Empty())); |
1281 cls.SetFunctions(Array::Handle(Array::Empty())); | 1298 cls.SetFunctions(Array::Handle(Array::Empty())); |
1282 // Set super class to Object. | 1299 // Set super class to Object. |
1283 cls.set_super_type(Type::Handle(Type::ObjectType())); | 1300 cls.set_super_type(Type::Handle(Type::ObjectType())); |
1284 // Compute instance size. | 1301 // Compute instance size. |
1285 intptr_t instance_size = (field_count * kWordSize) + sizeof(RawObject); | 1302 intptr_t instance_size = (field_count * kWordSize) + sizeof(RawObject); |
1286 cls.set_instance_size(RoundedAllocationSize(instance_size)); | 1303 cls.set_instance_size(RoundedAllocationSize(instance_size)); |
1287 cls.set_next_field_offset(instance_size); | 1304 cls.set_next_field_offset(instance_size); |
1288 cls.set_num_native_fields(field_count); | 1305 cls.set_num_native_fields(field_count); |
1289 cls.set_is_finalized(); | 1306 cls.set_is_finalized(); |
1290 library->AddClass(cls); | 1307 library->AddClass(cls); |
1291 return cls.raw(); | 1308 return cls.raw(); |
1292 } else { | 1309 } else { |
1293 return Class::null(); | 1310 return Class::null(); |
1294 } | 1311 } |
1295 } | 1312 } |
1296 | 1313 |
1297 | 1314 |
1298 void Class::set_name(const String& value) const { | 1315 void Class::set_name(const String& value) const { |
1299 ASSERT(value.IsSymbol()); | 1316 ASSERT(value.IsSymbol()); |
1300 StorePointer(&raw_ptr()->name_, value.raw()); | 1317 StorePointer(&raw_ptr()->name_, value.raw()); |
1301 } | 1318 } |
1302 | 1319 |
1303 | 1320 |
1304 void Class::set_script(const Script& value) const { | 1321 void Class::set_script(const Script& value) const { |
1305 StorePointer(&raw_ptr()->script_, value.raw()); | 1322 StorePointer(&raw_ptr()->script_, value.raw()); |
1306 } | 1323 } |
1307 | 1324 |
1308 | 1325 |
1326 void Class::set_token_index(intptr_t token_index) const { | |
1327 ASSERT(token_index >= 0); | |
1328 raw_ptr()->token_index_ = token_index; | |
1329 } | |
1330 | |
1331 | |
1309 void Class::set_is_interface() const { | 1332 void Class::set_is_interface() const { |
1310 raw_ptr()->is_interface_ = true; | 1333 raw_ptr()->is_interface_ = true; |
1311 } | 1334 } |
1312 | 1335 |
1313 | 1336 |
1314 void Class::set_is_const() const { | 1337 void Class::set_is_const() const { |
1315 raw_ptr()->is_const_ = true; | 1338 raw_ptr()->is_const_ = true; |
1316 } | 1339 } |
1317 | 1340 |
1318 | 1341 |
(...skipping 430 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1749 const Array& new_canonical_list = | 1772 const Array& new_canonical_list = |
1750 Array::Handle(Array::Grow(canonical_list, new_length, Heap::kOld)); | 1773 Array::Handle(Array::Grow(canonical_list, new_length, Heap::kOld)); |
1751 set_constants(new_canonical_list); | 1774 set_constants(new_canonical_list); |
1752 new_canonical_list.SetAt(index, constant); | 1775 new_canonical_list.SetAt(index, constant); |
1753 } else { | 1776 } else { |
1754 canonical_list.SetAt(index, constant); | 1777 canonical_list.SetAt(index, constant); |
1755 } | 1778 } |
1756 } | 1779 } |
1757 | 1780 |
1758 | 1781 |
1759 RawUnresolvedClass* UnresolvedClass::New(intptr_t token_index, | 1782 RawUnresolvedClass* UnresolvedClass::New(const LibraryPrefix& library_prefix, |
1760 const LibraryPrefix& library_prefix, | 1783 const String& ident, |
1761 const String& ident) { | 1784 intptr_t token_index) { |
1762 const UnresolvedClass& type = UnresolvedClass::Handle(UnresolvedClass::New()); | 1785 const UnresolvedClass& type = UnresolvedClass::Handle(UnresolvedClass::New()); |
1763 type.set_token_index(token_index); | |
1764 type.set_library_prefix(library_prefix); | 1786 type.set_library_prefix(library_prefix); |
1765 type.set_ident(ident); | 1787 type.set_ident(ident); |
1788 type.set_token_index(token_index); | |
1766 return type.raw(); | 1789 return type.raw(); |
1767 } | 1790 } |
1768 | 1791 |
1769 | 1792 |
1770 RawUnresolvedClass* UnresolvedClass::New() { | 1793 RawUnresolvedClass* UnresolvedClass::New() { |
1771 const Class& unresolved_class_class = | 1794 const Class& unresolved_class_class = |
1772 Class::Handle(Object::unresolved_class_class()); | 1795 Class::Handle(Object::unresolved_class_class()); |
1773 RawObject* raw = Object::Allocate(unresolved_class_class, | 1796 RawObject* raw = Object::Allocate(unresolved_class_class, |
1774 UnresolvedClass::InstanceSize(), | 1797 UnresolvedClass::InstanceSize(), |
1775 Heap::kNew); | 1798 Heap::kNew); |
1776 return reinterpret_cast<RawUnresolvedClass*>(raw); | 1799 return reinterpret_cast<RawUnresolvedClass*>(raw); |
1777 } | 1800 } |
1778 | 1801 |
1779 | 1802 |
1780 void UnresolvedClass::set_token_index(intptr_t token_index) const { | 1803 void UnresolvedClass::set_token_index(intptr_t token_index) const { |
1804 ASSERT(token_index >= 0); | |
1781 raw_ptr()->token_index_ = token_index; | 1805 raw_ptr()->token_index_ = token_index; |
1782 } | 1806 } |
1783 | 1807 |
1784 | 1808 |
1785 void UnresolvedClass::set_ident(const String& ident) const { | 1809 void UnresolvedClass::set_ident(const String& ident) const { |
1786 StorePointer(&raw_ptr()->ident_, ident.raw()); | 1810 StorePointer(&raw_ptr()->ident_, ident.raw()); |
1787 } | 1811 } |
1788 | 1812 |
1789 | 1813 |
1790 void UnresolvedClass::set_library_prefix( | 1814 void UnresolvedClass::set_library_prefix( |
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1848 } | 1872 } |
1849 | 1873 |
1850 | 1874 |
1851 RawAbstractTypeArguments* AbstractType::arguments() const { | 1875 RawAbstractTypeArguments* AbstractType::arguments() const { |
1852 // AbstractType is an abstract class. | 1876 // AbstractType is an abstract class. |
1853 UNREACHABLE(); | 1877 UNREACHABLE(); |
1854 return NULL; | 1878 return NULL; |
1855 } | 1879 } |
1856 | 1880 |
1857 | 1881 |
1882 intptr_t AbstractType::token_index() const { | |
1883 // AbstractType is an abstract class. | |
1884 UNREACHABLE(); | |
1885 return -1; | |
1886 } | |
1887 | |
1888 | |
1858 bool AbstractType::IsInstantiated() const { | 1889 bool AbstractType::IsInstantiated() const { |
1859 // AbstractType is an abstract class. | 1890 // AbstractType is an abstract class. |
1860 UNREACHABLE(); | 1891 UNREACHABLE(); |
1861 return false; | 1892 return false; |
1862 } | 1893 } |
1863 | 1894 |
1864 | 1895 |
1865 bool AbstractType::IsFinalized() const { | 1896 bool AbstractType::IsFinalized() const { |
1866 // AbstractType is an abstract class. | 1897 // AbstractType is an abstract class. |
1867 UNREACHABLE(); | 1898 UNREACHABLE(); |
(...skipping 196 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2064 AbstractTypeArguments::Handle(other.arguments())); | 2095 AbstractTypeArguments::Handle(other.arguments())); |
2065 } else { | 2096 } else { |
2066 ASSERT(test == kIsAssignableTo); | 2097 ASSERT(test == kIsAssignableTo); |
2067 return cls.IsAssignableTo(AbstractTypeArguments::Handle(arguments()), | 2098 return cls.IsAssignableTo(AbstractTypeArguments::Handle(arguments()), |
2068 Class::Handle(other.type_class()), | 2099 Class::Handle(other.type_class()), |
2069 AbstractTypeArguments::Handle(other.arguments())); | 2100 AbstractTypeArguments::Handle(other.arguments())); |
2070 } | 2101 } |
2071 } | 2102 } |
2072 | 2103 |
2073 RawAbstractType* AbstractType::NewTypeParameter( | 2104 RawAbstractType* AbstractType::NewTypeParameter( |
2074 intptr_t index, const String& name) { | 2105 intptr_t index, const String& name, intptr_t token_index) { |
2075 return TypeParameter::New(index, name); | 2106 return TypeParameter::New(index, name, token_index); |
2076 } | 2107 } |
2077 | 2108 |
2078 | 2109 |
2079 RawAbstractType* AbstractType::NewInstantiatedType( | 2110 RawAbstractType* AbstractType::NewInstantiatedType( |
2080 const AbstractType& uninstantiated_type, | 2111 const AbstractType& uninstantiated_type, |
2081 const AbstractTypeArguments& instantiator_type_arguments) { | 2112 const AbstractTypeArguments& instantiator_type_arguments) { |
2082 return InstantiatedType::New(uninstantiated_type, | 2113 return InstantiatedType::New(uninstantiated_type, |
2083 instantiator_type_arguments); | 2114 instantiator_type_arguments); |
2084 } | 2115 } |
2085 | 2116 |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2139 RawType* Type::FunctionInterface() { | 2170 RawType* Type::FunctionInterface() { |
2140 return Isolate::Current()->object_store()->function_interface(); | 2171 return Isolate::Current()->object_store()->function_interface(); |
2141 } | 2172 } |
2142 | 2173 |
2143 | 2174 |
2144 RawType* Type::ListInterface() { | 2175 RawType* Type::ListInterface() { |
2145 return Isolate::Current()->object_store()->list_interface(); | 2176 return Isolate::Current()->object_store()->list_interface(); |
2146 } | 2177 } |
2147 | 2178 |
2148 | 2179 |
2149 RawType* Type::NewRawType(const Class& type_class) { | 2180 RawType* Type::NewRawType(const Class& type_class, intptr_t token_index) { |
2150 const AbstractTypeArguments& type_arguments = | 2181 const AbstractTypeArguments& type_arguments = |
2151 AbstractTypeArguments::Handle(type_class.type_parameter_extends()); | 2182 AbstractTypeArguments::Handle(type_class.type_parameter_extends()); |
2152 return New(Object::Handle(type_class.raw()), type_arguments); | 2183 return New(Object::Handle(type_class.raw()), type_arguments, token_index); |
2153 } | 2184 } |
2154 | 2185 |
2155 | 2186 |
2156 RawType* Type::NewNonParameterizedType( | 2187 RawType* Type::NewNonParameterizedType( |
2157 const Class& type_class) { | 2188 const Class& type_class) { |
2158 ASSERT(!type_class.HasTypeArguments()); | 2189 ASSERT(!type_class.HasTypeArguments()); |
2159 const TypeArguments& no_type_arguments = TypeArguments::Handle(); | 2190 const TypeArguments& no_type_arguments = TypeArguments::Handle(); |
2191 const intptr_t kPos = 0; // Dummy token index for unspecified position. | |
2160 Type& type = Type::Handle(); | 2192 Type& type = Type::Handle(); |
2161 type ^= Type::New( | 2193 type ^= Type::New(Object::Handle(type_class.raw()), no_type_arguments, kPos); |
2162 Object::Handle(type_class.raw()), no_type_arguments); | |
2163 type.set_is_finalized(); | 2194 type.set_is_finalized(); |
2164 type ^= type.Canonicalize(); | 2195 type ^= type.Canonicalize(); |
2165 return type.raw(); | 2196 return type.raw(); |
2166 } | 2197 } |
2167 | 2198 |
2168 | 2199 |
2169 void Type::set_is_finalized() const { | 2200 void Type::set_is_finalized() const { |
2170 ASSERT(!IsFinalized()); | 2201 ASSERT(!IsFinalized()); |
2171 set_type_state(RawType::kFinalized); | 2202 set_type_state(RawType::kFinalized); |
2172 } | 2203 } |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2228 | 2259 |
2229 RawAbstractType* Type::InstantiateFrom( | 2260 RawAbstractType* Type::InstantiateFrom( |
2230 const AbstractTypeArguments& instantiator_type_arguments) const { | 2261 const AbstractTypeArguments& instantiator_type_arguments) const { |
2231 ASSERT(IsFinalized()); | 2262 ASSERT(IsFinalized()); |
2232 ASSERT(!IsInstantiated()); | 2263 ASSERT(!IsInstantiated()); |
2233 AbstractTypeArguments& type_arguments = | 2264 AbstractTypeArguments& type_arguments = |
2234 AbstractTypeArguments::Handle(arguments()); | 2265 AbstractTypeArguments::Handle(arguments()); |
2235 type_arguments = type_arguments.InstantiateFrom(instantiator_type_arguments); | 2266 type_arguments = type_arguments.InstantiateFrom(instantiator_type_arguments); |
2236 const Class& cls = Class::Handle(type_class()); | 2267 const Class& cls = Class::Handle(type_class()); |
2237 ASSERT(cls.is_finalized()); | 2268 ASSERT(cls.is_finalized()); |
2238 Type& instantiated_type = Type::Handle(Type::New(cls, type_arguments)); | 2269 Type& instantiated_type = Type::Handle( |
2270 Type::New(cls, type_arguments, token_index())); | |
2239 ASSERT(type_arguments.IsNull() || | 2271 ASSERT(type_arguments.IsNull() || |
2240 (type_arguments.Length() == cls.NumTypeArguments())); | 2272 (type_arguments.Length() == cls.NumTypeArguments())); |
2241 instantiated_type.set_is_finalized(); | 2273 instantiated_type.set_is_finalized(); |
2242 return instantiated_type.raw(); | 2274 return instantiated_type.raw(); |
2243 } | 2275 } |
2244 | 2276 |
2245 | 2277 |
2246 bool Type::Equals(const AbstractType& other) const { | 2278 bool Type::Equals(const AbstractType& other) const { |
2247 ASSERT(IsFinalized() && other.IsFinalized()); | 2279 ASSERT(IsFinalized() && other.IsFinalized()); |
2248 if (raw() == other.raw()) { | 2280 if (raw() == other.raw()) { |
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2324 RawType* Type::New() { | 2356 RawType* Type::New() { |
2325 const Class& type_class = Class::Handle(Object::type_class()); | 2357 const Class& type_class = Class::Handle(Object::type_class()); |
2326 RawObject* raw = Object::Allocate(type_class, | 2358 RawObject* raw = Object::Allocate(type_class, |
2327 Type::InstanceSize(), | 2359 Type::InstanceSize(), |
2328 Heap::kOld); | 2360 Heap::kOld); |
2329 return reinterpret_cast<RawType*>(raw); | 2361 return reinterpret_cast<RawType*>(raw); |
2330 } | 2362 } |
2331 | 2363 |
2332 | 2364 |
2333 RawType* Type::New(const Object& clazz, | 2365 RawType* Type::New(const Object& clazz, |
2334 const AbstractTypeArguments& arguments) { | 2366 const AbstractTypeArguments& arguments, |
2367 intptr_t token_index) { | |
2335 const Type& result = Type::Handle(Type::New()); | 2368 const Type& result = Type::Handle(Type::New()); |
2336 result.set_type_class(clazz); | 2369 result.set_type_class(clazz); |
2337 result.set_arguments(arguments); | 2370 result.set_arguments(arguments); |
2371 result.set_token_index(token_index); | |
2338 result.raw_ptr()->type_state_ = RawType::kAllocated; | 2372 result.raw_ptr()->type_state_ = RawType::kAllocated; |
2339 return result.raw(); | 2373 return result.raw(); |
2340 } | 2374 } |
2341 | 2375 |
2342 | 2376 |
2377 void Type::set_token_index(intptr_t token_index) const { | |
2378 ASSERT(token_index >= 0); | |
2379 raw_ptr()->token_index_ = token_index; | |
2380 } | |
2381 | |
2382 | |
2343 void Type::set_type_state(int8_t state) const { | 2383 void Type::set_type_state(int8_t state) const { |
2344 ASSERT(state == RawType::kAllocated || | 2384 ASSERT(state == RawType::kAllocated || |
2345 state == RawType::kBeingFinalized || | 2385 state == RawType::kBeingFinalized || |
2346 state == RawType::kFinalized); | 2386 state == RawType::kFinalized); |
2347 raw_ptr()->type_state_ = state; | 2387 raw_ptr()->type_state_ = state; |
2348 } | 2388 } |
2349 | 2389 |
2350 | 2390 |
2351 const char* Type::ToCString() const { | 2391 const char* Type::ToCString() const { |
2352 if (IsResolved()) { | 2392 if (IsResolved()) { |
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2423 RawTypeParameter* TypeParameter::New() { | 2463 RawTypeParameter* TypeParameter::New() { |
2424 const Class& type_parameter_class = | 2464 const Class& type_parameter_class = |
2425 Class::Handle(Object::type_parameter_class()); | 2465 Class::Handle(Object::type_parameter_class()); |
2426 RawObject* raw = Object::Allocate(type_parameter_class, | 2466 RawObject* raw = Object::Allocate(type_parameter_class, |
2427 TypeParameter::InstanceSize(), | 2467 TypeParameter::InstanceSize(), |
2428 Heap::kOld); | 2468 Heap::kOld); |
2429 return reinterpret_cast<RawTypeParameter*>(raw); | 2469 return reinterpret_cast<RawTypeParameter*>(raw); |
2430 } | 2470 } |
2431 | 2471 |
2432 | 2472 |
2433 RawTypeParameter* TypeParameter::New(intptr_t index, const String& name) { | 2473 RawTypeParameter* TypeParameter::New( |
2474 intptr_t index, const String& name, intptr_t token_index) { | |
2434 const TypeParameter& result = TypeParameter::Handle(TypeParameter::New()); | 2475 const TypeParameter& result = TypeParameter::Handle(TypeParameter::New()); |
2435 result.set_index(index); | 2476 result.set_index(index); |
2436 result.set_name(name); | 2477 result.set_name(name); |
2478 result.set_token_index(token_index); | |
2437 result.raw_ptr()->type_state_ = RawTypeParameter::kAllocated; | 2479 result.raw_ptr()->type_state_ = RawTypeParameter::kAllocated; |
2438 return result.raw(); | 2480 return result.raw(); |
2439 } | 2481 } |
2440 | 2482 |
2441 | 2483 |
2484 void TypeParameter::set_token_index(intptr_t token_index) const { | |
2485 ASSERT(token_index >= 0); | |
2486 raw_ptr()->token_index_ = token_index; | |
2487 } | |
2488 | |
2489 | |
2442 void TypeParameter::set_type_state(int8_t state) const { | 2490 void TypeParameter::set_type_state(int8_t state) const { |
2443 ASSERT(state == RawTypeParameter::kAllocated || | 2491 ASSERT(state == RawTypeParameter::kAllocated || |
2444 state == RawTypeParameter::kBeingFinalized || | 2492 state == RawTypeParameter::kBeingFinalized || |
2445 state == RawTypeParameter::kFinalized); | 2493 state == RawTypeParameter::kFinalized); |
2446 raw_ptr()->type_state_ = state; | 2494 raw_ptr()->type_state_ = state; |
2447 } | 2495 } |
2448 | 2496 |
2449 | 2497 |
2450 const char* TypeParameter::ToCString() const { | 2498 const char* TypeParameter::ToCString() const { |
2451 const char* format = "TypeParameter: name %s; index: %d"; | 2499 const char* format = "TypeParameter: name %s; index: %d"; |
(...skipping 12 matching lines...) Expand all Loading... | |
2464 | 2512 |
2465 | 2513 |
2466 RawAbstractTypeArguments* InstantiatedType::arguments() const { | 2514 RawAbstractTypeArguments* InstantiatedType::arguments() const { |
2467 return InstantiatedTypeArguments::New( | 2515 return InstantiatedTypeArguments::New( |
2468 AbstractTypeArguments::Handle(AbstractType::Handle( | 2516 AbstractTypeArguments::Handle(AbstractType::Handle( |
2469 uninstantiated_type()).arguments()), | 2517 uninstantiated_type()).arguments()), |
2470 AbstractTypeArguments::Handle(instantiator_type_arguments())); | 2518 AbstractTypeArguments::Handle(instantiator_type_arguments())); |
2471 } | 2519 } |
2472 | 2520 |
2473 | 2521 |
2522 intptr_t InstantiatedType::token_index() const { | |
2523 return AbstractType::Handle(uninstantiated_type()).token_index(); | |
2524 } | |
2525 | |
2526 | |
2474 void InstantiatedType::set_uninstantiated_type( | 2527 void InstantiatedType::set_uninstantiated_type( |
2475 const AbstractType& value) const { | 2528 const AbstractType& value) const { |
2476 StorePointer(&raw_ptr()->uninstantiated_type_, value.raw()); | 2529 StorePointer(&raw_ptr()->uninstantiated_type_, value.raw()); |
2477 } | 2530 } |
2478 | 2531 |
2479 | 2532 |
2480 void InstantiatedType::set_instantiator_type_arguments( | 2533 void InstantiatedType::set_instantiator_type_arguments( |
2481 const AbstractTypeArguments& value) const { | 2534 const AbstractTypeArguments& value) const { |
2482 StorePointer(&raw_ptr()->instantiator_type_arguments_, value.raw()); | 2535 StorePointer(&raw_ptr()->instantiator_type_arguments_, value.raw()); |
2483 } | 2536 } |
(...skipping 915 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3399 const Script& script = Script::Handle(owner_class.script()); | 3452 const Script& script = Script::Handle(owner_class.script()); |
3400 signature_class = Class::NewSignatureClass(signature, | 3453 signature_class = Class::NewSignatureClass(signature, |
3401 closure_function, | 3454 closure_function, |
3402 script); | 3455 script); |
3403 library.AddClass(signature_class); | 3456 library.AddClass(signature_class); |
3404 } else { | 3457 } else { |
3405 closure_function.set_signature_class(signature_class); | 3458 closure_function.set_signature_class(signature_class); |
3406 } | 3459 } |
3407 const Type& signature_type = Type::Handle(signature_class.SignatureType()); | 3460 const Type& signature_type = Type::Handle(signature_class.SignatureType()); |
3408 if (!signature_type.IsFinalized()) { | 3461 if (!signature_type.IsFinalized()) { |
3409 Error& error = Error::Handle(); | 3462 ClassFinalizer::FinalizeType(signature_class, signature_type); |
3410 ClassFinalizer::FinalizeAndCanonicalizeType(signature_class, | |
3411 signature_type, | |
3412 &error); | |
3413 ASSERT(error.IsNull()); | |
3414 } | 3463 } |
3415 ASSERT(closure_function.signature_class() == signature_class.raw()); | 3464 ASSERT(closure_function.signature_class() == signature_class.raw()); |
3416 set_implicit_closure_function(closure_function); | 3465 set_implicit_closure_function(closure_function); |
3417 ASSERT(closure_function.IsImplicitClosureFunction()); | 3466 ASSERT(closure_function.IsImplicitClosureFunction()); |
3418 return closure_function.raw(); | 3467 return closure_function.raw(); |
3419 } | 3468 } |
3420 | 3469 |
3421 | 3470 |
3422 template<typename T> | 3471 template<typename T> |
3423 static RawArray* NewArray(const GrowableArray<T*>& objs) { | 3472 static RawArray* NewArray(const GrowableArray<T*>& objs) { |
(...skipping 2086 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
5510 | 5559 |
5511 RawType* Instance::GetType() const { | 5560 RawType* Instance::GetType() const { |
5512 if (IsNull()) { | 5561 if (IsNull()) { |
5513 return Type::NullType(); | 5562 return Type::NullType(); |
5514 } | 5563 } |
5515 const Class& cls = Class::Handle(clazz()); | 5564 const Class& cls = Class::Handle(clazz()); |
5516 AbstractTypeArguments& type_arguments = AbstractTypeArguments::Handle(); | 5565 AbstractTypeArguments& type_arguments = AbstractTypeArguments::Handle(); |
5517 if (cls.HasTypeArguments()) { | 5566 if (cls.HasTypeArguments()) { |
5518 type_arguments = GetTypeArguments(); | 5567 type_arguments = GetTypeArguments(); |
5519 } | 5568 } |
5520 const Type& type = Type::Handle(Type::New(cls, type_arguments)); | 5569 const intptr_t kPos = 0; // Dummy token index for unspecified position. |
5570 const Type& type = Type::Handle(Type::New(cls, type_arguments, kPos)); | |
5521 type.set_is_finalized(); | 5571 type.set_is_finalized(); |
5522 return type.raw(); | 5572 return type.raw(); |
5523 } | 5573 } |
5524 | 5574 |
5525 | 5575 |
5526 RawAbstractTypeArguments* Instance::GetTypeArguments() const { | 5576 RawAbstractTypeArguments* Instance::GetTypeArguments() const { |
5527 const Class& cls = Class::Handle(clazz()); | 5577 const Class& cls = Class::Handle(clazz()); |
5528 intptr_t field_offset = cls.type_arguments_instance_field_offset(); | 5578 intptr_t field_offset = cls.type_arguments_instance_field_offset(); |
5529 ASSERT(field_offset != Class::kNoTypeArguments); | 5579 ASSERT(field_offset != Class::kNoTypeArguments); |
5530 AbstractTypeArguments& type_arguments = AbstractTypeArguments::Handle(); | 5580 AbstractTypeArguments& type_arguments = AbstractTypeArguments::Handle(); |
(...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
5651 // Can occur when running disassembler. | 5701 // Can occur when running disassembler. |
5652 return "Instance"; | 5702 return "Instance"; |
5653 } else { | 5703 } else { |
5654 const char* kFormat = "Instance of '%s'"; | 5704 const char* kFormat = "Instance of '%s'"; |
5655 Class& cls = Class::Handle(clazz()); | 5705 Class& cls = Class::Handle(clazz()); |
5656 AbstractTypeArguments& type_arguments = AbstractTypeArguments::Handle(); | 5706 AbstractTypeArguments& type_arguments = AbstractTypeArguments::Handle(); |
5657 const intptr_t num_type_arguments = cls.NumTypeArguments(); | 5707 const intptr_t num_type_arguments = cls.NumTypeArguments(); |
5658 if (num_type_arguments > 0) { | 5708 if (num_type_arguments > 0) { |
5659 type_arguments = GetTypeArguments(); | 5709 type_arguments = GetTypeArguments(); |
5660 } | 5710 } |
5661 const Type& type = Type::Handle(Type::New(cls, type_arguments)); | 5711 const intptr_t kPos = 0; // Dummy token index for unspecified position. |
5712 const Type& type = Type::Handle(Type::New(cls, type_arguments, kPos)); | |
5662 const String& type_name = String::Handle(type.Name()); | 5713 const String& type_name = String::Handle(type.Name()); |
5663 // Calculate the size of the string. | 5714 // Calculate the size of the string. |
5664 intptr_t len = OS::SNPrint(NULL, 0, kFormat, type_name.ToCString()) + 1; | 5715 intptr_t len = OS::SNPrint(NULL, 0, kFormat, type_name.ToCString()) + 1; |
5665 char* chars = reinterpret_cast<char*>( | 5716 char* chars = reinterpret_cast<char*>( |
5666 Isolate::Current()->current_zone()->Allocate(len)); | 5717 Isolate::Current()->current_zone()->Allocate(len)); |
5667 OS::SNPrint(chars, len, kFormat, type_name.ToCString()); | 5718 OS::SNPrint(chars, len, kFormat, type_name.ToCString()); |
5668 return chars; | 5719 return chars; |
5669 } | 5720 } |
5670 } | 5721 } |
5671 | 5722 |
(...skipping 2264 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
7936 const String& str = String::Handle(pattern()); | 7987 const String& str = String::Handle(pattern()); |
7937 const char* format = "JSRegExp: pattern=%s flags=%s"; | 7988 const char* format = "JSRegExp: pattern=%s flags=%s"; |
7938 intptr_t len = OS::SNPrint(NULL, 0, format, str.ToCString(), Flags()); | 7989 intptr_t len = OS::SNPrint(NULL, 0, format, str.ToCString(), Flags()); |
7939 char* chars = reinterpret_cast<char*>( | 7990 char* chars = reinterpret_cast<char*>( |
7940 Isolate::Current()->current_zone()->Allocate(len + 1)); | 7991 Isolate::Current()->current_zone()->Allocate(len + 1)); |
7941 OS::SNPrint(chars, (len + 1), format, str.ToCString(), Flags()); | 7992 OS::SNPrint(chars, (len + 1), format, str.ToCString(), Flags()); |
7942 return chars; | 7993 return chars; |
7943 } | 7994 } |
7944 | 7995 |
7945 } // namespace dart | 7996 } // namespace dart |
OLD | NEW |