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

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

Issue 23094003: Make sure type information is not lost in snapshots created in production mode, (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 7 years, 4 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 | Annotate | Revision Log
« no previous file with comments | « no previous file | runtime/vm/parser.cc » ('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/flags.h" 7 #include "vm/flags.h"
8 #include "vm/heap.h" 8 #include "vm/heap.h"
9 #include "vm/isolate.h" 9 #include "vm/isolate.h"
10 #include "vm/longjump.h" 10 #include "vm/longjump.h"
(...skipping 1054 matching lines...) Expand 10 before | Expand all | Expand 10 after
1065 ReportError(Error::Handle(), // No previous error. 1065 ReportError(Error::Handle(), // No previous error.
1066 script, field.token_pos(), 1066 script, field.token_pos(),
1067 "field '%s' of class '%s' conflicts with method '%s' " 1067 "field '%s' of class '%s' conflicts with method '%s' "
1068 "of super class '%s'", 1068 "of super class '%s'",
1069 name.ToCString(), 1069 name.ToCString(),
1070 class_name.ToCString(), 1070 class_name.ToCString(),
1071 name.ToCString(), 1071 name.ToCString(),
1072 super_class_name.ToCString()); 1072 super_class_name.ToCString());
1073 } 1073 }
1074 } 1074 }
1075 if ((FLAG_enable_type_checks || FLAG_error_on_malformed_type) && 1075 if (field.is_static() && (field.is_const() || field.is_final()) &&
1076 field.is_static() && field.is_const() &&
1077 (field.value() != Object::null()) && 1076 (field.value() != Object::null()) &&
1078 (field.value() != Object::sentinel().raw())) { 1077 (field.value() != Object::sentinel().raw())) {
1079 // The parser does not preset the value if the type is a type parameter or 1078 // The parser does not preset the value if the type is a type parameter or
1080 // is parameterized unless the value is null. 1079 // is parameterized unless the value is null.
1081 Error& malformed_error = Error::Handle(); 1080 Error& malformed_error = Error::Handle();
1082 if (type.IsMalformed()) { 1081 if (type.IsMalformed()) {
1083 malformed_error = type.malformed_error(); 1082 malformed_error = type.malformed_error();
1084 } else { 1083 } else {
1085 ASSERT(type.IsInstantiated()); 1084 ASSERT(type.IsInstantiated());
1086 } 1085 }
1087 const Instance& const_value = Instance::Handle(field.value()); 1086 const Instance& const_value = Instance::Handle(field.value());
1088 if (!malformed_error.IsNull() || 1087 if (!malformed_error.IsNull() ||
1089 (!type.IsDynamicType() && 1088 (!type.IsDynamicType() &&
1090 !const_value.IsInstanceOf(type, 1089 !const_value.IsInstanceOf(type,
1091 AbstractTypeArguments::Handle(), 1090 AbstractTypeArguments::Handle(),
1092 &malformed_error))) { 1091 &malformed_error))) {
1093 const AbstractType& const_value_type = AbstractType::Handle( 1092 if (FLAG_error_on_malformed_type) {
1094 const_value.GetType()); 1093 const AbstractType& const_value_type = AbstractType::Handle(
1095 const String& const_value_type_name = String::Handle( 1094 const_value.GetType());
1096 const_value_type.UserVisibleName()); 1095 const String& const_value_type_name = String::Handle(
1097 const String& type_name = String::Handle(type.UserVisibleName()); 1096 const_value_type.UserVisibleName());
1098 const Script& script = Script::Handle(cls.script()); 1097 const String& type_name = String::Handle(type.UserVisibleName());
1099 ReportError(malformed_error, script, field.token_pos(), 1098 const Script& script = Script::Handle(cls.script());
1100 "error initializing const field '%s': type '%s' is not a " 1099 ReportError(malformed_error, script, field.token_pos(),
1101 "subtype of type '%s'", 1100 "error initializing static %s field '%s': "
1102 name.ToCString(), 1101 "type '%s' is not a subtype of type '%s'",
1103 const_value_type_name.ToCString(), 1102 field.is_const() ? "const" : "final",
1104 type_name.ToCString()); 1103 name.ToCString(),
1104 const_value_type_name.ToCString(),
1105 type_name.ToCString());
1106 } else {
1107 // Do not report an error yet, even in checked mode, since the field
1108 // may not actually be used.
1109 // Also, we may be generating a snapshot in production mode that will
1110 // later be executed in checked mode, in which case an error needs to
1111 // be reported, should the field be accessed.
1112 // Therefore, we undo the optimization performed by the parser, i.e.
1113 // we create an implicit static final getter and reset the field value
1114 // to the sentinel value.
1115 const String& getter_name = String::Handle(Field::GetterSymbol(name));
1116 const Function& getter = Function::Handle(
1117 Function::New(getter_name,
1118 RawFunction::kImplicitStaticFinalGetter,
1119 /* is_static = */ true,
1120 /* is_const = */ field.is_const(),
1121 /* is_abstract = */ false,
1122 /* is_external = */ false,
1123 cls,
1124 field.token_pos()));
1125 getter.set_result_type(type);
1126 cls.AddFunction(getter);
1127 field.set_value(Instance::Handle(Object::sentinel().raw()));
1128 }
1105 } 1129 }
1106 } 1130 }
1107 } 1131 }
1108 // Collect interfaces, super interfaces, and super classes of this class. 1132 // Collect interfaces, super interfaces, and super classes of this class.
1109 const GrowableObjectArray& interfaces = 1133 const GrowableObjectArray& interfaces =
1110 GrowableObjectArray::Handle(GrowableObjectArray::New()); 1134 GrowableObjectArray::Handle(GrowableObjectArray::New());
1111 CollectInterfaces(cls, interfaces); 1135 CollectInterfaces(cls, interfaces);
1112 // Include superclasses in list of interfaces and super interfaces. 1136 // Include superclasses in list of interfaces and super interfaces.
1113 super_class = cls.SuperClass(); 1137 super_class = cls.SuperClass();
1114 while (!super_class.IsNull()) { 1138 while (!super_class.IsNull()) {
(...skipping 1104 matching lines...) Expand 10 before | Expand all | Expand 10 after
2219 expected_name ^= String::New("_offset"); 2243 expected_name ^= String::New("_offset");
2220 ASSERT(String::EqualsIgnoringPrivateKey(name, expected_name)); 2244 ASSERT(String::EqualsIgnoringPrivateKey(name, expected_name));
2221 field ^= fields_array.At(2); 2245 field ^= fields_array.At(2);
2222 ASSERT(field.Offset() == TypedDataView::length_offset()); 2246 ASSERT(field.Offset() == TypedDataView::length_offset());
2223 name ^= field.name(); 2247 name ^= field.name();
2224 ASSERT(name.Equals("length")); 2248 ASSERT(name.Equals("length"));
2225 #endif 2249 #endif
2226 } 2250 }
2227 2251
2228 } // namespace dart 2252 } // namespace dart
OLDNEW
« no previous file with comments | « no previous file | runtime/vm/parser.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698