| 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 919 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 930 // encountered here. | 930 // encountered here. |
| 931 ASSERT(!type.IsBeingFinalized()); | 931 ASSERT(!type.IsBeingFinalized()); |
| 932 | 932 |
| 933 // A malformed type gets mapped to a finalized type. | 933 // A malformed type gets mapped to a finalized type. |
| 934 ResolveType(cls, type); | 934 ResolveType(cls, type); |
| 935 if (type.IsMalformed()) { | 935 if (type.IsMalformed()) { |
| 936 ASSERT(type.IsFinalized()); | 936 ASSERT(type.IsFinalized()); |
| 937 return type.raw(); | 937 return type.raw(); |
| 938 } | 938 } |
| 939 | 939 |
| 940 Isolate* isolate = Isolate::Current(); | 940 Zone* Z = Thread::Current()->zone(); |
| 941 if (FLAG_trace_type_finalization) { | 941 if (FLAG_trace_type_finalization) { |
| 942 ISL_Print("Finalizing type '%s' for class '%s'\n", | 942 ISL_Print("Finalizing type '%s' for class '%s'\n", |
| 943 String::Handle(isolate, type.Name()).ToCString(), | 943 String::Handle(Z, type.Name()).ToCString(), |
| 944 cls.ToCString()); | 944 cls.ToCString()); |
| 945 } | 945 } |
| 946 | 946 |
| 947 if (type.IsTypeParameter()) { | 947 if (type.IsTypeParameter()) { |
| 948 const TypeParameter& type_parameter = TypeParameter::Cast(type); | 948 const TypeParameter& type_parameter = TypeParameter::Cast(type); |
| 949 const Class& parameterized_class = | 949 const Class& parameterized_class = |
| 950 Class::Handle(isolate, type_parameter.parameterized_class()); | 950 Class::Handle(Z, type_parameter.parameterized_class()); |
| 951 ASSERT(!parameterized_class.IsNull()); | 951 ASSERT(!parameterized_class.IsNull()); |
| 952 // The index must reflect the position of this type parameter in the type | 952 // The index must reflect the position of this type parameter in the type |
| 953 // arguments vector of its parameterized class. The offset to add is the | 953 // arguments vector of its parameterized class. The offset to add is the |
| 954 // number of type arguments in the super type, which is equal to the | 954 // number of type arguments in the super type, which is equal to the |
| 955 // difference in number of type arguments and type parameters of the | 955 // difference in number of type arguments and type parameters of the |
| 956 // parameterized class. | 956 // parameterized class. |
| 957 const intptr_t offset = parameterized_class.NumTypeArguments() - | 957 const intptr_t offset = parameterized_class.NumTypeArguments() - |
| 958 parameterized_class.NumTypeParameters(); | 958 parameterized_class.NumTypeParameters(); |
| 959 // Calling NumTypeParameters() may finalize this type parameter if it | 959 // Calling NumTypeParameters() may finalize this type parameter if it |
| 960 // belongs to a mixin application class. | 960 // belongs to a mixin application class. |
| 961 if (!type_parameter.IsFinalized()) { | 961 if (!type_parameter.IsFinalized()) { |
| 962 type_parameter.set_index(type_parameter.index() + offset); | 962 type_parameter.set_index(type_parameter.index() + offset); |
| 963 type_parameter.set_is_finalized(); | 963 type_parameter.set_is_finalized(); |
| 964 } else { | 964 } else { |
| 965 ASSERT(cls.IsMixinApplication()); | 965 ASSERT(cls.IsMixinApplication()); |
| 966 } | 966 } |
| 967 | 967 |
| 968 if (FLAG_trace_type_finalization) { | 968 if (FLAG_trace_type_finalization) { |
| 969 ISL_Print("Done finalizing type parameter '%s' with index %" Pd "\n", | 969 ISL_Print("Done finalizing type parameter '%s' with index %" Pd "\n", |
| 970 String::Handle(isolate, type_parameter.name()).ToCString(), | 970 String::Handle(Z, type_parameter.name()).ToCString(), |
| 971 type_parameter.index()); | 971 type_parameter.index()); |
| 972 } | 972 } |
| 973 | 973 |
| 974 // We do not canonicalize type parameters. | 974 // We do not canonicalize type parameters. |
| 975 return type_parameter.raw(); | 975 return type_parameter.raw(); |
| 976 } | 976 } |
| 977 | 977 |
| 978 // At this point, we can only have a parameterized_type. | 978 // At this point, we can only have a parameterized_type. |
| 979 const Type& parameterized_type = Type::Cast(type); | 979 const Type& parameterized_type = Type::Cast(type); |
| 980 | 980 |
| 981 // This type is the root type of the type graph if no pending types queue is | 981 // This type is the root type of the type graph if no pending types queue is |
| 982 // allocated yet. | 982 // allocated yet. |
| 983 const bool is_root_type = (pending_types == NULL); | 983 const bool is_root_type = (pending_types == NULL); |
| 984 GrowableObjectArray& types = GrowableObjectArray::Handle(isolate); | 984 GrowableObjectArray& types = GrowableObjectArray::Handle(Z); |
| 985 if (is_root_type) { | 985 if (is_root_type) { |
| 986 types = GrowableObjectArray::New(); | 986 types = GrowableObjectArray::New(); |
| 987 pending_types = &types; | 987 pending_types = &types; |
| 988 } | 988 } |
| 989 | 989 |
| 990 // The type class does not need to be finalized in order to finalize the type, | 990 // The type class does not need to be finalized in order to finalize the type, |
| 991 // however, it must at least be resolved (this was done as part of resolving | 991 // however, it must at least be resolved (this was done as part of resolving |
| 992 // the type itself, a precondition to calling FinalizeType). | 992 // the type itself, a precondition to calling FinalizeType). |
| 993 // Also, the interfaces of the type class must be resolved and the type | 993 // Also, the interfaces of the type class must be resolved and the type |
| 994 // parameters of the type class must be finalized. | 994 // parameters of the type class must be finalized. |
| 995 Class& type_class = Class::Handle(isolate, parameterized_type.type_class()); | 995 Class& type_class = Class::Handle(Z, parameterized_type.type_class()); |
| 996 if (!type_class.is_type_finalized()) { | 996 if (!type_class.is_type_finalized()) { |
| 997 FinalizeTypeParameters(type_class, pending_types); | 997 FinalizeTypeParameters(type_class, pending_types); |
| 998 ResolveUpperBounds(type_class); | 998 ResolveUpperBounds(type_class); |
| 999 } | 999 } |
| 1000 | 1000 |
| 1001 // The finalized type argument vector needs num_type_arguments types. | 1001 // The finalized type argument vector needs num_type_arguments types. |
| 1002 const intptr_t num_type_arguments = type_class.NumTypeArguments(); | 1002 const intptr_t num_type_arguments = type_class.NumTypeArguments(); |
| 1003 // The type class has num_type_parameters type parameters. | 1003 // The type class has num_type_parameters type parameters. |
| 1004 const intptr_t num_type_parameters = type_class.NumTypeParameters(); | 1004 const intptr_t num_type_parameters = type_class.NumTypeParameters(); |
| 1005 | 1005 |
| 1006 // Initialize the type argument vector. | 1006 // Initialize the type argument vector. |
| 1007 // Check the number of parsed type arguments, if any. | 1007 // Check the number of parsed type arguments, if any. |
| 1008 // Specifying no type arguments indicates a raw type, which is not an error. | 1008 // Specifying no type arguments indicates a raw type, which is not an error. |
| 1009 // However, type parameter bounds are checked below, even for a raw type. | 1009 // However, type parameter bounds are checked below, even for a raw type. |
| 1010 TypeArguments& arguments = | 1010 TypeArguments& arguments = |
| 1011 TypeArguments::Handle(isolate, parameterized_type.arguments()); | 1011 TypeArguments::Handle(Z, parameterized_type.arguments()); |
| 1012 if (!arguments.IsNull() && (arguments.Length() != num_type_parameters)) { | 1012 if (!arguments.IsNull() && (arguments.Length() != num_type_parameters)) { |
| 1013 // Wrong number of type arguments. The type is mapped to the raw type. | 1013 // Wrong number of type arguments. The type is mapped to the raw type. |
| 1014 if (Isolate::Current()->flags().error_on_bad_type()) { | 1014 if (Isolate::Current()->flags().error_on_bad_type()) { |
| 1015 const String& type_class_name = | 1015 const String& type_class_name = |
| 1016 String::Handle(isolate, type_class.Name()); | 1016 String::Handle(Z, type_class.Name()); |
| 1017 ReportError(cls, parameterized_type.token_pos(), | 1017 ReportError(cls, parameterized_type.token_pos(), |
| 1018 "wrong number of type arguments for class '%s'", | 1018 "wrong number of type arguments for class '%s'", |
| 1019 type_class_name.ToCString()); | 1019 type_class_name.ToCString()); |
| 1020 } | 1020 } |
| 1021 // Make the type raw and continue without reporting any error. | 1021 // Make the type raw and continue without reporting any error. |
| 1022 // A static warning should have been reported. | 1022 // A static warning should have been reported. |
| 1023 arguments = TypeArguments::null(); | 1023 arguments = TypeArguments::null(); |
| 1024 parameterized_type.set_arguments(arguments); | 1024 parameterized_type.set_arguments(arguments); |
| 1025 } | 1025 } |
| 1026 | 1026 |
| 1027 // Mark the type as being finalized in order to detect self reference and | 1027 // Mark the type as being finalized in order to detect self reference and |
| 1028 // postpone bound checking until after all types in the graph of | 1028 // postpone bound checking until after all types in the graph of |
| 1029 // mutually recursive types are finalized. | 1029 // mutually recursive types are finalized. |
| 1030 parameterized_type.set_is_being_finalized(); | 1030 parameterized_type.set_is_being_finalized(); |
| 1031 pending_types->Add(parameterized_type); | 1031 pending_types->Add(parameterized_type); |
| 1032 | 1032 |
| 1033 // The full type argument vector consists of the type arguments of the | 1033 // The full type argument vector consists of the type arguments of the |
| 1034 // super types of type_class, which are initialized from the parsed | 1034 // super types of type_class, which are initialized from the parsed |
| 1035 // type arguments, followed by the parsed type arguments. | 1035 // type arguments, followed by the parsed type arguments. |
| 1036 TypeArguments& full_arguments = TypeArguments::Handle(isolate); | 1036 TypeArguments& full_arguments = TypeArguments::Handle(Z); |
| 1037 Error& bound_error = Error::Handle(isolate); | 1037 Error& bound_error = Error::Handle(Z); |
| 1038 if (num_type_arguments > 0) { | 1038 if (num_type_arguments > 0) { |
| 1039 // If no type arguments were parsed and if the super types do not prepend | 1039 // If no type arguments were parsed and if the super types do not prepend |
| 1040 // type arguments to the vector, we can leave the vector as null. | 1040 // type arguments to the vector, we can leave the vector as null. |
| 1041 if (!arguments.IsNull() || (num_type_arguments > num_type_parameters)) { | 1041 if (!arguments.IsNull() || (num_type_arguments > num_type_parameters)) { |
| 1042 full_arguments = TypeArguments::New(num_type_arguments); | 1042 full_arguments = TypeArguments::New(num_type_arguments); |
| 1043 // Copy the parsed type arguments at the correct offset in the full type | 1043 // Copy the parsed type arguments at the correct offset in the full type |
| 1044 // argument vector. | 1044 // argument vector. |
| 1045 const intptr_t offset = num_type_arguments - num_type_parameters; | 1045 const intptr_t offset = num_type_arguments - num_type_parameters; |
| 1046 AbstractType& type_arg = | 1046 AbstractType& type_arg = |
| 1047 AbstractType::Handle(isolate, Type::DynamicType()); | 1047 AbstractType::Handle(Z, Type::DynamicType()); |
| 1048 // Leave the temporary type arguments at indices [0..offset[ as null. | 1048 // Leave the temporary type arguments at indices [0..offset[ as null. |
| 1049 for (intptr_t i = 0; i < num_type_parameters; i++) { | 1049 for (intptr_t i = 0; i < num_type_parameters; i++) { |
| 1050 // If no type parameters were provided, a raw type is desired, so we | 1050 // If no type parameters were provided, a raw type is desired, so we |
| 1051 // create a vector of dynamic. | 1051 // create a vector of dynamic. |
| 1052 if (!arguments.IsNull()) { | 1052 if (!arguments.IsNull()) { |
| 1053 type_arg = arguments.TypeAt(i); | 1053 type_arg = arguments.TypeAt(i); |
| 1054 // The parsed type_arg may or may not be finalized. | 1054 // The parsed type_arg may or may not be finalized. |
| 1055 } | 1055 } |
| 1056 full_arguments.SetTypeAt(offset + i, type_arg); | 1056 full_arguments.SetTypeAt(offset + i, type_arg); |
| 1057 } | 1057 } |
| (...skipping 18 matching lines...) Expand all Loading... |
| 1076 } | 1076 } |
| 1077 } | 1077 } |
| 1078 // If the type class is a signature class, the full argument vector | 1078 // If the type class is a signature class, the full argument vector |
| 1079 // must include the argument vector of the super type. | 1079 // must include the argument vector of the super type. |
| 1080 // If the signature class is a function type alias, it is also the owner | 1080 // If the signature class is a function type alias, it is also the owner |
| 1081 // of its signature function and no super type is involved. | 1081 // of its signature function and no super type is involved. |
| 1082 // If the signature class is canonical (not an alias), the owner of its | 1082 // If the signature class is canonical (not an alias), the owner of its |
| 1083 // signature function may either be an alias or the enclosing class of a | 1083 // signature function may either be an alias or the enclosing class of a |
| 1084 // local function, in which case the super type of the enclosing class is | 1084 // local function, in which case the super type of the enclosing class is |
| 1085 // also considered when filling up the argument vector. | 1085 // also considered when filling up the argument vector. |
| 1086 Class& owner_class = Class::Handle(isolate); | 1086 Class& owner_class = Class::Handle(Z); |
| 1087 if (type_class.IsSignatureClass()) { | 1087 if (type_class.IsSignatureClass()) { |
| 1088 const Function& signature_fun = | 1088 const Function& signature_fun = |
| 1089 Function::Handle(isolate, type_class.signature_function()); | 1089 Function::Handle(Z, type_class.signature_function()); |
| 1090 ASSERT(!signature_fun.is_static()); | 1090 ASSERT(!signature_fun.is_static()); |
| 1091 owner_class = signature_fun.Owner(); | 1091 owner_class = signature_fun.Owner(); |
| 1092 } else { | 1092 } else { |
| 1093 owner_class = type_class.raw(); | 1093 owner_class = type_class.raw(); |
| 1094 } | 1094 } |
| 1095 if (offset > 0) { | 1095 if (offset > 0) { |
| 1096 TrailPtr trail = new Trail(4); | 1096 TrailPtr trail = new Trail(Z, 4); |
| 1097 FinalizeTypeArguments(owner_class, full_arguments, offset, | 1097 FinalizeTypeArguments(owner_class, full_arguments, offset, |
| 1098 &bound_error, pending_types, trail); | 1098 &bound_error, pending_types, trail); |
| 1099 } | 1099 } |
| 1100 if (full_arguments.IsRaw(0, num_type_arguments)) { | 1100 if (full_arguments.IsRaw(0, num_type_arguments)) { |
| 1101 // The parameterized_type is raw. Set its argument vector to null, which | 1101 // The parameterized_type is raw. Set its argument vector to null, which |
| 1102 // is more efficient in type tests. | 1102 // is more efficient in type tests. |
| 1103 full_arguments = TypeArguments::null(); | 1103 full_arguments = TypeArguments::null(); |
| 1104 } | 1104 } |
| 1105 parameterized_type.set_arguments(full_arguments); | 1105 parameterized_type.set_arguments(full_arguments); |
| 1106 } else { | 1106 } else { |
| 1107 ASSERT(full_arguments.IsNull()); // Use null vector for raw type. | 1107 ASSERT(full_arguments.IsNull()); // Use null vector for raw type. |
| 1108 } | 1108 } |
| 1109 } | 1109 } |
| 1110 | 1110 |
| 1111 // Self referencing types may get finalized indirectly. | 1111 // Self referencing types may get finalized indirectly. |
| 1112 if (!parameterized_type.IsFinalized()) { | 1112 if (!parameterized_type.IsFinalized()) { |
| 1113 ASSERT(full_arguments.IsNull() || | 1113 ASSERT(full_arguments.IsNull() || |
| 1114 !full_arguments.IsRaw(0, num_type_arguments)); | 1114 !full_arguments.IsRaw(0, num_type_arguments)); |
| 1115 // Mark the type as finalized. | 1115 // Mark the type as finalized. |
| 1116 parameterized_type.SetIsFinalized(); | 1116 parameterized_type.SetIsFinalized(); |
| 1117 // Do not yet remove the type from the pending_types array. | 1117 // Do not yet remove the type from the pending_types array. |
| 1118 } | 1118 } |
| 1119 | 1119 |
| 1120 // If we are done finalizing a graph of mutually recursive types, check their | 1120 // If we are done finalizing a graph of mutually recursive types, check their |
| 1121 // bounds. | 1121 // bounds. |
| 1122 if (is_root_type) { | 1122 if (is_root_type) { |
| 1123 Type& type = Type::Handle(isolate); | 1123 Type& type = Type::Handle(Z); |
| 1124 for (intptr_t i = types.Length() - 1; i >= 0; i--) { | 1124 for (intptr_t i = types.Length() - 1; i >= 0; i--) { |
| 1125 type ^= types.At(i); | 1125 type ^= types.At(i); |
| 1126 CheckTypeBounds(cls, type); | 1126 CheckTypeBounds(cls, type); |
| 1127 if (FLAG_trace_type_finalization && type.IsRecursive()) { | 1127 if (FLAG_trace_type_finalization && type.IsRecursive()) { |
| 1128 ISL_Print("Done finalizing recursive type '%s': %s\n", | 1128 ISL_Print("Done finalizing recursive type '%s': %s\n", |
| 1129 String::Handle(isolate, type.Name()).ToCString(), | 1129 String::Handle(Z, type.Name()).ToCString(), |
| 1130 type.ToCString()); | 1130 type.ToCString()); |
| 1131 } | 1131 } |
| 1132 } | 1132 } |
| 1133 } | 1133 } |
| 1134 | 1134 |
| 1135 // If the type class is a signature class, we are currently finalizing a | 1135 // If the type class is a signature class, we are currently finalizing a |
| 1136 // signature type, i.e. finalizing the result type and parameter types of the | 1136 // signature type, i.e. finalizing the result type and parameter types of the |
| 1137 // signature function of this signature type. | 1137 // signature function of this signature type. |
| 1138 // We do this after marking this type as finalized in order to allow a | 1138 // We do this after marking this type as finalized in order to allow a |
| 1139 // function type to refer to itself via its parameter types and result type. | 1139 // function type to refer to itself via its parameter types and result type. |
| 1140 if (type_class.IsSignatureClass()) { | 1140 if (type_class.IsSignatureClass()) { |
| 1141 // The class may be created while parsing a function body, after all | 1141 // The class may be created while parsing a function body, after all |
| 1142 // pending classes have already been finalized. | 1142 // pending classes have already been finalized. |
| 1143 FinalizeTypesInClass(type_class); | 1143 FinalizeTypesInClass(type_class); |
| 1144 } | 1144 } |
| 1145 | 1145 |
| 1146 if (FLAG_trace_type_finalization) { | 1146 if (FLAG_trace_type_finalization) { |
| 1147 ISL_Print("Done finalizing type '%s' with %" Pd " type args: %s\n", | 1147 ISL_Print("Done finalizing type '%s' with %" Pd " type args: %s\n", |
| 1148 String::Handle(isolate, parameterized_type.Name()).ToCString(), | 1148 String::Handle(Z, parameterized_type.Name()).ToCString(), |
| 1149 parameterized_type.arguments() == TypeArguments::null() ? | 1149 parameterized_type.arguments() == TypeArguments::null() ? |
| 1150 0 : num_type_arguments, | 1150 0 : num_type_arguments, |
| 1151 parameterized_type.ToCString()); | 1151 parameterized_type.ToCString()); |
| 1152 } | 1152 } |
| 1153 | 1153 |
| 1154 if (finalization >= kCanonicalize) { | 1154 if (finalization >= kCanonicalize) { |
| 1155 if (FLAG_trace_type_finalization && parameterized_type.IsRecursive()) { | 1155 if (FLAG_trace_type_finalization && parameterized_type.IsRecursive()) { |
| 1156 AbstractType& type = Type::Handle(isolate); | 1156 AbstractType& type = Type::Handle(Z); |
| 1157 type = parameterized_type.Canonicalize(); | 1157 type = parameterized_type.Canonicalize(); |
| 1158 ISL_Print("Done canonicalizing recursive type '%s': %s\n", | 1158 ISL_Print("Done canonicalizing recursive type '%s': %s\n", |
| 1159 String::Handle(isolate, type.Name()).ToCString(), | 1159 String::Handle(Z, type.Name()).ToCString(), |
| 1160 type.ToCString()); | 1160 type.ToCString()); |
| 1161 return type.raw(); | 1161 return type.raw(); |
| 1162 } | 1162 } |
| 1163 return parameterized_type.Canonicalize(); | 1163 return parameterized_type.Canonicalize(); |
| 1164 } else { | 1164 } else { |
| 1165 return parameterized_type.raw(); | 1165 return parameterized_type.raw(); |
| 1166 } | 1166 } |
| 1167 } | 1167 } |
| 1168 | 1168 |
| 1169 | 1169 |
| (...skipping 2046 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3216 ASSERT(fields_array.Length() == ByteBuffer::NumberOfFields()); | 3216 ASSERT(fields_array.Length() == ByteBuffer::NumberOfFields()); |
| 3217 field ^= fields_array.At(0); | 3217 field ^= fields_array.At(0); |
| 3218 ASSERT(field.Offset() == ByteBuffer::data_offset()); | 3218 ASSERT(field.Offset() == ByteBuffer::data_offset()); |
| 3219 name ^= field.name(); | 3219 name ^= field.name(); |
| 3220 expected_name ^= String::New("_data"); | 3220 expected_name ^= String::New("_data"); |
| 3221 ASSERT(String::EqualsIgnoringPrivateKey(name, expected_name)); | 3221 ASSERT(String::EqualsIgnoringPrivateKey(name, expected_name)); |
| 3222 #endif | 3222 #endif |
| 3223 } | 3223 } |
| 3224 | 3224 |
| 3225 } // namespace dart | 3225 } // namespace dart |
| OLD | NEW |