| 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/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 1103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1114 // class Object. | 1114 // class Object. |
| 1115 const Type& mixin_super_type = Type::Handle(mixin_cls.super_type()); | 1115 const Type& mixin_super_type = Type::Handle(mixin_cls.super_type()); |
| 1116 if (!mixin_super_type.IsObjectType()) { | 1116 if (!mixin_super_type.IsObjectType()) { |
| 1117 const Script& script = Script::Handle(cls.script()); | 1117 const Script& script = Script::Handle(cls.script()); |
| 1118 const String& class_name = String::Handle(mixin_cls.Name()); | 1118 const String& class_name = String::Handle(mixin_cls.Name()); |
| 1119 ReportError(script, cls.token_pos(), | 1119 ReportError(script, cls.token_pos(), |
| 1120 "mixin class %s must extend class Object", | 1120 "mixin class %s must extend class Object", |
| 1121 class_name.ToCString()); | 1121 class_name.ToCString()); |
| 1122 } | 1122 } |
| 1123 | 1123 |
| 1124 const Array& functions = Array::Handle(mixin_cls.functions()); | 1124 const GrowableObjectArray& cloned_funcs = |
| 1125 GrowableObjectArray::Handle(GrowableObjectArray::New()); |
| 1126 Array& functions = Array::Handle(); |
| 1125 Function& func = Function::Handle(); | 1127 Function& func = Function::Handle(); |
| 1128 // The parser creates the mixin application class and adds just |
| 1129 // one function, the implicit constructor. |
| 1130 functions = cls.functions(); |
| 1131 ASSERT(functions.Length() == 1); |
| 1132 func ^= functions.At(0); |
| 1133 ASSERT(func.IsImplicitConstructor()); |
| 1134 cloned_funcs.Add(func); |
| 1135 // Now clone the functions from the mixin class. |
| 1136 functions = mixin_cls.functions(); |
| 1126 const intptr_t num_functions = functions.Length(); | 1137 const intptr_t num_functions = functions.Length(); |
| 1127 for (int i = 0; i < num_functions; i++) { | 1138 for (int i = 0; i < num_functions; i++) { |
| 1128 func ^= functions.At(i); | 1139 func ^= functions.At(i); |
| 1129 if (func.IsConstructor()) { | 1140 if (func.IsConstructor()) { |
| 1130 // A mixin class must not have explicit constructors. | 1141 // A mixin class must not have explicit constructors. |
| 1131 if (!func.IsImplicitConstructor()) { | 1142 if (!func.IsImplicitConstructor()) { |
| 1132 const Script& script = Script::Handle(cls.script()); | 1143 const Script& script = Script::Handle(cls.script()); |
| 1133 ReportError(script, cls.token_pos(), | 1144 ReportError(script, cls.token_pos(), |
| 1134 "mixin class %s must not have constructors\n", | 1145 "mixin class %s must not have constructors\n", |
| 1135 String::Handle(mixin_cls.Name()).ToCString()); | 1146 String::Handle(mixin_cls.Name()).ToCString()); |
| 1136 } | 1147 } |
| 1137 continue; // Skip the implicit constructor. | 1148 continue; // Skip the implicit constructor. |
| 1138 } | 1149 } |
| 1139 if (!func.is_static()) { | 1150 if (!func.is_static()) { |
| 1140 func = func.Clone(cls); | 1151 func = func.Clone(cls); |
| 1141 cls.AddFunction(func); | 1152 cloned_funcs.Add(func); |
| 1142 } | 1153 } |
| 1143 } | 1154 } |
| 1155 functions = Array::MakeArray(cloned_funcs); |
| 1156 cls.SetFunctions(functions); |
| 1157 |
| 1158 // Now clone the fields from the mixin class. There should be no |
| 1159 // existing fields in the mixin application class. |
| 1160 ASSERT(Array::Handle(cls.fields()).Length() == 0); |
| 1144 Array& fields = Array::Handle(mixin_cls.fields()); | 1161 Array& fields = Array::Handle(mixin_cls.fields()); |
| 1145 Field& field = Field::Handle(); | 1162 Field& field = Field::Handle(); |
| 1146 const GrowableObjectArray& cloned_fields = | 1163 const GrowableObjectArray& cloned_fields = |
| 1147 GrowableObjectArray::Handle(GrowableObjectArray::New()); | 1164 GrowableObjectArray::Handle(GrowableObjectArray::New()); |
| 1148 const intptr_t num_fields = fields.Length(); | 1165 const intptr_t num_fields = fields.Length(); |
| 1149 for (int i = 0; i < num_fields; i++) { | 1166 for (int i = 0; i < num_fields; i++) { |
| 1150 field ^= fields.At(i); | 1167 field ^= fields.At(i); |
| 1151 if (!field.is_static()) { | 1168 if (!field.is_static()) { |
| 1152 field = field.Clone(cls); | 1169 field = field.Clone(cls); |
| 1153 cloned_fields.Add(field); | 1170 cloned_fields.Add(field); |
| 1154 } | 1171 } |
| 1155 } | 1172 } |
| 1156 fields = Array::MakeArray(cloned_fields); | 1173 fields = Array::MakeArray(cloned_fields); |
| 1157 ASSERT(Array::Handle(cls.fields()).Length() == 0); | |
| 1158 cls.SetFields(fields); | 1174 cls.SetFields(fields); |
| 1159 } | 1175 } |
| 1160 | 1176 |
| 1161 | 1177 |
| 1162 void ClassFinalizer::FinalizeClass(const Class& cls) { | 1178 void ClassFinalizer::FinalizeClass(const Class& cls) { |
| 1163 if (cls.is_finalized()) { | 1179 if (cls.is_finalized()) { |
| 1164 return; | 1180 return; |
| 1165 } | 1181 } |
| 1166 if (FLAG_trace_class_finalization) { | 1182 if (FLAG_trace_class_finalization) { |
| 1167 OS::Print("Finalize %s\n", cls.ToCString()); | 1183 OS::Print("Finalize %s\n", cls.ToCString()); |
| (...skipping 487 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1655 void ClassFinalizer::ReportError(const char* format, ...) { | 1671 void ClassFinalizer::ReportError(const char* format, ...) { |
| 1656 va_list args; | 1672 va_list args; |
| 1657 va_start(args, format); | 1673 va_start(args, format); |
| 1658 const Error& error = Error::Handle( | 1674 const Error& error = Error::Handle( |
| 1659 Parser::FormatError(Script::Handle(), -1, "Error", format, args)); | 1675 Parser::FormatError(Script::Handle(), -1, "Error", format, args)); |
| 1660 va_end(args); | 1676 va_end(args); |
| 1661 ReportError(error); | 1677 ReportError(error); |
| 1662 } | 1678 } |
| 1663 | 1679 |
| 1664 } // namespace dart | 1680 } // namespace dart |
| OLD | NEW |