OLD | NEW |
1 // Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2016, 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/kernel_reader.h" | 5 #include "vm/kernel_reader.h" |
6 | 6 |
7 #include <string.h> | 7 #include <string.h> |
8 | 8 |
9 #include "vm/dart_api_impl.h" | 9 #include "vm/dart_api_impl.h" |
10 #include "vm/longjump.h" | 10 #include "vm/longjump.h" |
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
74 const dart::Instance& SimpleValue() { return *simple_value_; } | 74 const dart::Instance& SimpleValue() { return *simple_value_; } |
75 dart::Zone* zone() const { return zone_; } | 75 dart::Zone* zone() const { return zone_; } |
76 | 76 |
77 private: | 77 private: |
78 TranslationHelper translation_helper_; | 78 TranslationHelper translation_helper_; |
79 dart::Zone* zone_; | 79 dart::Zone* zone_; |
80 bool is_simple_; | 80 bool is_simple_; |
81 dart::Instance* simple_value_; | 81 dart::Instance* simple_value_; |
82 }; | 82 }; |
83 | 83 |
84 void BuildingTranslationHelper::SetFinalize(bool finalize) { | |
85 reader_->finalize_ = finalize; | |
86 } | |
87 | 84 |
88 RawLibrary* BuildingTranslationHelper::LookupLibraryByKernelLibrary( | 85 RawLibrary* BuildingTranslationHelper::LookupLibraryByKernelLibrary( |
89 Library* library) { | 86 Library* library) { |
90 return reader_->LookupLibrary(library).raw(); | 87 return reader_->LookupLibrary(library).raw(); |
91 } | 88 } |
92 | 89 |
| 90 |
93 RawClass* BuildingTranslationHelper::LookupClassByKernelClass(Class* klass) { | 91 RawClass* BuildingTranslationHelper::LookupClassByKernelClass(Class* klass) { |
94 return reader_->LookupClass(klass).raw(); | 92 return reader_->LookupClass(klass).raw(); |
95 } | 93 } |
96 | 94 |
| 95 |
97 Object& KernelReader::ReadProgram() { | 96 Object& KernelReader::ReadProgram() { |
98 ASSERT(!bootstrapping_); | 97 ASSERT(!bootstrapping_); |
99 Program* program = ReadPrecompiledKernelFromBuffer(buffer_, buffer_length_); | 98 Program* program = ReadPrecompiledKernelFromBuffer(buffer_, buffer_length_); |
100 if (program == NULL) { | 99 if (program == NULL) { |
101 const dart::String& error = H.DartString("Failed to read .kernell file"); | 100 const dart::String& error = H.DartString("Failed to read .kernell file"); |
102 return Object::Handle(Z, ApiError::New(error)); | 101 return Object::Handle(Z, ApiError::New(error)); |
103 } | 102 } |
104 | 103 |
105 LongJumpScope jump; | 104 LongJumpScope jump; |
106 if (setjmp(*jump.Set()) == 0) { | 105 if (setjmp(*jump.Set()) == 0) { |
107 Procedure* main = program->main_method(); | 106 Procedure* main = program->main_method(); |
108 Library* kernel_main_library = Library::Cast(main->parent()); | 107 Library* kernel_main_library = Library::Cast(main->parent()); |
109 | 108 |
110 intptr_t length = program->libraries().length(); | 109 intptr_t length = program->libraries().length(); |
111 for (intptr_t i = 0; i < length; i++) { | 110 for (intptr_t i = 0; i < length; i++) { |
112 Library* kernel_library = program->libraries()[i]; | 111 Library* kernel_library = program->libraries()[i]; |
113 ReadLibrary(kernel_library); | 112 ReadLibrary(kernel_library); |
114 } | 113 } |
115 | 114 |
116 // We finalize classes after we've constructed all classes since we | |
117 // currently don't construct them in pre-order of the class hierarchy (and | |
118 // finalization of a class needs all of its superclasses to be finalized). | |
119 dart::String& name = dart::String::Handle(Z); | |
120 for (intptr_t i = 0; i < length; i++) { | 115 for (intptr_t i = 0; i < length; i++) { |
121 Library* kernel_library = program->libraries()[i]; | 116 dart::Library& library = LookupLibrary(program->libraries()[i]); |
122 dart::Library& library = LookupLibrary(kernel_library); | 117 if (!library.Loaded()) library.SetLoaded(); |
123 name = library.url(); | 118 } |
124 | 119 |
125 // TODO(27590) unskip this library when we fix underlying issue. | 120 if (!ClassFinalizer::ProcessPendingClasses(/*from_kernel=*/true)) { |
126 if (name.Equals("dart:vmservice_io")) { | 121 FATAL("Error in class finalization during bootstrapping."); |
127 continue; | |
128 } | |
129 | |
130 if (!library.Loaded()) { | |
131 dart::Class& klass = dart::Class::Handle(Z); | |
132 for (intptr_t i = 0; i < kernel_library->classes().length(); i++) { | |
133 klass = LookupClass(kernel_library->classes()[i]).raw(); | |
134 ClassFinalizer::FinalizeTypesInClass(klass); | |
135 ClassFinalizer::FinalizeClass(klass); | |
136 } | |
137 library.SetLoaded(); | |
138 } | |
139 } | 122 } |
140 | 123 |
141 dart::Library& library = LookupLibrary(kernel_main_library); | 124 dart::Library& library = LookupLibrary(kernel_main_library); |
142 | 125 |
143 // Sanity check that we can find the main entrypoint. | 126 // Sanity check that we can find the main entrypoint. |
144 Object& main_obj = Object::Handle( | 127 Object& main_obj = Object::Handle( |
145 Z, library.LookupObjectAllowPrivate(H.DartSymbol("main"))); | 128 Z, library.LookupObjectAllowPrivate(H.DartSymbol("main"))); |
146 ASSERT(!main_obj.IsNull()); | 129 ASSERT(!main_obj.IsNull()); |
147 return library; | 130 return library; |
148 } else { | 131 } else { |
149 // Everything else is a compile-time error. We don't use the [error] since | 132 // Everything else is a compile-time error. We don't use the [error] since |
150 // it sometimes causes the higher-level error handling to try to read the | 133 // it sometimes causes the higher-level error handling to try to read the |
151 // script and token position (which we don't have) to produce a nice error | 134 // script and token position (which we don't have) to produce a nice error |
152 // message. | 135 // message. |
153 Error& error = Error::Handle(Z); | 136 Error& error = Error::Handle(Z); |
154 error = thread_->sticky_error(); | 137 error = thread_->sticky_error(); |
155 thread_->clear_sticky_error(); | 138 thread_->clear_sticky_error(); |
156 | 139 |
157 // Instead we simply make a non-informative error message. | 140 // Instead we simply make a non-informative error message. |
158 const dart::String& error_message = | 141 const dart::String& error_message = |
159 H.DartString("Failed to read .kernell file => CompileTimeError."); | 142 H.DartString("Failed to read .kernell file => CompileTimeError."); |
160 return Object::Handle(Z, LanguageError::New(error_message)); | 143 return Object::Handle(Z, LanguageError::New(error_message)); |
161 } | 144 } |
162 } | 145 } |
163 | 146 |
| 147 |
164 void KernelReader::ReadLibrary(Library* kernel_library) { | 148 void KernelReader::ReadLibrary(Library* kernel_library) { |
165 dart::Library& library = LookupLibrary(kernel_library); | 149 dart::Library& library = LookupLibrary(kernel_library); |
166 if (library.Loaded()) return; | 150 if (library.Loaded()) return; |
167 | 151 |
168 // The bootstrapper will take care of creating the native wrapper classes, but | 152 // The bootstrapper will take care of creating the native wrapper classes, but |
169 // we will add the synthetic constructors to them here. | 153 // we will add the synthetic constructors to them here. |
170 if (library.name() == | 154 if (library.name() == |
171 Symbols::Symbol(Symbols::kDartNativeWrappersLibNameId).raw()) { | 155 Symbols::Symbol(Symbols::kDartNativeWrappersLibNameId).raw()) { |
172 ASSERT(library.LoadInProgress()); | 156 ASSERT(library.LoadInProgress()); |
173 } else { | 157 } else { |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
209 toplevel_class.AddField(field); | 193 toplevel_class.AddField(field); |
210 library.AddObject(field, name); | 194 library.AddObject(field, name); |
211 } | 195 } |
212 | 196 |
213 // Load toplevel procedures. | 197 // Load toplevel procedures. |
214 for (intptr_t i = 0; i < kernel_library->procedures().length(); i++) { | 198 for (intptr_t i = 0; i < kernel_library->procedures().length(); i++) { |
215 Procedure* kernel_procedure = kernel_library->procedures()[i]; | 199 Procedure* kernel_procedure = kernel_library->procedures()[i]; |
216 ReadProcedure(library, toplevel_class, kernel_procedure); | 200 ReadProcedure(library, toplevel_class, kernel_procedure); |
217 } | 201 } |
218 | 202 |
| 203 const GrowableObjectArray& classes = |
| 204 GrowableObjectArray::Handle(I->object_store()->pending_classes()); |
| 205 |
219 // Load all classes. | 206 // Load all classes. |
220 for (intptr_t i = 0; i < kernel_library->classes().length(); i++) { | 207 for (intptr_t i = 0; i < kernel_library->classes().length(); i++) { |
221 Class* kernel_klass = kernel_library->classes()[i]; | 208 Class* kernel_klass = kernel_library->classes()[i]; |
222 ReadClass(library, kernel_klass); | 209 classes.Add(ReadClass(library, kernel_klass), Heap::kOld); |
223 } | 210 } |
224 } | 211 } |
225 | 212 |
| 213 |
226 void KernelReader::ReadPreliminaryClass(dart::Class* klass, | 214 void KernelReader::ReadPreliminaryClass(dart::Class* klass, |
227 Class* kernel_klass) { | 215 Class* kernel_klass) { |
228 ASSERT(kernel_klass->IsNormalClass()); | 216 ASSERT(kernel_klass->IsNormalClass()); |
229 NormalClass* kernel_normal_class = NormalClass::Cast(kernel_klass); | 217 NormalClass* kernel_normal_class = NormalClass::Cast(kernel_klass); |
230 | 218 |
231 ActiveClassScope active_class_scope(&active_class_, kernel_klass, klass); | 219 ActiveClassScope active_class_scope(&active_class_, kernel_klass, klass); |
232 | 220 |
233 // First setup the type parameters, so if any of the following code uses it | 221 // First setup the type parameters, so if any of the following code uses it |
234 // (in a recursive way) we're fine. | 222 // (in a recursive way) we're fine. |
235 TypeArguments& type_parameters = | 223 TypeArguments& type_parameters = |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
276 AbstractType& super_type = T.TranslateTypeWithoutFinalization( | 264 AbstractType& super_type = T.TranslateTypeWithoutFinalization( |
277 kernel_normal_class->super_class()); | 265 kernel_normal_class->super_class()); |
278 if (super_type.IsMalformed()) H.ReportError("Malformed super type"); | 266 if (super_type.IsMalformed()) H.ReportError("Malformed super type"); |
279 klass->set_super_type(super_type); | 267 klass->set_super_type(super_type); |
280 } | 268 } |
281 | 269 |
282 // Build implemented interface types | 270 // Build implemented interface types |
283 intptr_t interface_count = kernel_klass->implemented_classes().length(); | 271 intptr_t interface_count = kernel_klass->implemented_classes().length(); |
284 const dart::Array& interfaces = | 272 const dart::Array& interfaces = |
285 dart::Array::Handle(Z, dart::Array::New(interface_count)); | 273 dart::Array::Handle(Z, dart::Array::New(interface_count)); |
286 dart::Class& interface_class = dart::Class::Handle(Z); | |
287 for (intptr_t i = 0; i < interface_count; i++) { | 274 for (intptr_t i = 0; i < interface_count; i++) { |
288 InterfaceType* kernel_interface_type = | 275 InterfaceType* kernel_interface_type = |
289 kernel_klass->implemented_classes()[i]; | 276 kernel_klass->implemented_classes()[i]; |
290 const AbstractType& type = | 277 const AbstractType& type = |
291 T.TranslateTypeWithoutFinalization(kernel_interface_type); | 278 T.TranslateTypeWithoutFinalization(kernel_interface_type); |
292 if (type.IsMalformed()) H.ReportError("Malformed interface type."); | 279 if (type.IsMalformed()) H.ReportError("Malformed interface type."); |
293 interfaces.SetAt(i, type); | 280 interfaces.SetAt(i, type); |
294 | |
295 // NOTE: Normally the DartVM keeps a list of pending classes and iterates | |
296 // through them later on using `ClassFinalizer::ProcessPendingClasses()`. | |
297 // This involes calling `ClassFinalizer::ResolveSuperTypeAndInterfaces()` | |
298 // which does a lot of error validation (e.g. cycle checks) which we don't | |
299 // need here. But we do need to do one thing which this resolving phase | |
300 // normally does for us: set the `is_implemented` boolean. | |
301 | |
302 // TODO(27590): Maybe we can do this differently once we have | |
303 // "bootstrapping from kernel"-support. | |
304 interface_class = type.type_class(); | |
305 interface_class.set_is_implemented(); | |
306 } | 281 } |
307 klass->set_interfaces(interfaces); | 282 klass->set_interfaces(interfaces); |
308 if (kernel_klass->is_abstract()) klass->set_is_abstract(); | 283 if (kernel_klass->is_abstract()) klass->set_is_abstract(); |
309 klass->set_is_cycle_free(); | |
310 | |
311 // When bootstrapping we should not finalize types yet because they will be | |
312 // finalized when the object store's pending_classes list is drained by | |
313 // ClassFinalizer::ProcessPendingClasses. Even when not bootstrapping we are | |
314 // careful not to eagerly finalize types that may introduce a circularity | |
315 // (such as type arguments, interface types, field types, etc.). | |
316 if (finalize_) ClassFinalizer::FinalizeTypesInClass(*klass); | |
317 } | 284 } |
318 | 285 |
319 void KernelReader::ReadClass(const dart::Library& library, | 286 |
320 Class* kernel_klass) { | 287 dart::Class& KernelReader::ReadClass(const dart::Library& library, |
| 288 Class* kernel_klass) { |
321 // This will trigger a call to [ReadPreliminaryClass] if not already done. | 289 // This will trigger a call to [ReadPreliminaryClass] if not already done. |
322 dart::Class& klass = LookupClass(kernel_klass); | 290 dart::Class& klass = LookupClass(kernel_klass); |
323 | 291 |
324 ActiveClassScope active_class_scope(&active_class_, kernel_klass, &klass); | 292 ActiveClassScope active_class_scope(&active_class_, kernel_klass, &klass); |
325 | 293 |
326 TokenPosition pos(0); | 294 TokenPosition pos(0); |
327 | 295 |
328 for (intptr_t i = 0; i < kernel_klass->fields().length(); i++) { | 296 for (intptr_t i = 0; i < kernel_klass->fields().length(); i++) { |
329 Field* kernel_field = kernel_klass->fields()[i]; | 297 Field* kernel_field = kernel_klass->fields()[i]; |
330 ActiveMemberScope active_member_scope(&active_class_, kernel_field); | 298 ActiveMemberScope active_member_scope(&active_class_, kernel_field); |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
375 Procedure* kernel_procedure = kernel_klass->procedures()[i]; | 343 Procedure* kernel_procedure = kernel_klass->procedures()[i]; |
376 ActiveMemberScope active_member_scope(&active_class_, kernel_procedure); | 344 ActiveMemberScope active_member_scope(&active_class_, kernel_procedure); |
377 ReadProcedure(library, klass, kernel_procedure, kernel_klass); | 345 ReadProcedure(library, klass, kernel_procedure, kernel_klass); |
378 } | 346 } |
379 | 347 |
380 if (bootstrapping_ && !klass.is_marked_for_parsing()) { | 348 if (bootstrapping_ && !klass.is_marked_for_parsing()) { |
381 klass.set_is_marked_for_parsing(); | 349 klass.set_is_marked_for_parsing(); |
382 GrowableObjectArray::Handle(Z, I->object_store()->pending_classes()) | 350 GrowableObjectArray::Handle(Z, I->object_store()->pending_classes()) |
383 .Add(klass, Heap::kOld); | 351 .Add(klass, Heap::kOld); |
384 } | 352 } |
| 353 |
| 354 return klass; |
385 } | 355 } |
386 | 356 |
| 357 |
387 void KernelReader::ReadProcedure(const dart::Library& library, | 358 void KernelReader::ReadProcedure(const dart::Library& library, |
388 const dart::Class& owner, | 359 const dart::Class& owner, |
389 Procedure* kernel_procedure, | 360 Procedure* kernel_procedure, |
390 Class* kernel_klass) { | 361 Class* kernel_klass) { |
391 ActiveClassScope active_class_scope(&active_class_, kernel_klass, &owner); | 362 ActiveClassScope active_class_scope(&active_class_, kernel_klass, &owner); |
392 ActiveMemberScope active_member_scope(&active_class_, kernel_procedure); | 363 ActiveMemberScope active_member_scope(&active_class_, kernel_procedure); |
393 ActiveFunctionScope active_function_scope(&active_class_, | 364 ActiveFunctionScope active_function_scope(&active_class_, |
394 kernel_procedure->function()); | 365 kernel_procedure->function()); |
395 | 366 |
396 const dart::String& name = H.DartProcedureName(kernel_procedure); | 367 const dart::String& name = H.DartProcedureName(kernel_procedure); |
(...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
516 false, // is_native | 487 false, // is_native |
517 klass, pos)); | 488 klass, pos)); |
518 klass.AddFunction(setter); | 489 klass.AddFunction(setter); |
519 setter.set_kernel_function(kernel_field); | 490 setter.set_kernel_function(kernel_field); |
520 setter.set_result_type(Object::void_type()); | 491 setter.set_result_type(Object::void_type()); |
521 setter.set_is_debuggable(false); | 492 setter.set_is_debuggable(false); |
522 SetupFieldAccessorFunction(klass, setter); | 493 SetupFieldAccessorFunction(klass, setter); |
523 } | 494 } |
524 } | 495 } |
525 | 496 |
| 497 |
526 void KernelReader::SetupFunctionParameters(TranslationHelper translation_helper, | 498 void KernelReader::SetupFunctionParameters(TranslationHelper translation_helper, |
527 DartTypeTranslator type_translator, | 499 DartTypeTranslator type_translator, |
528 const dart::Class& klass, | 500 const dart::Class& klass, |
529 const dart::Function& function, | 501 const dart::Function& function, |
530 FunctionNode* node, bool is_method, | 502 FunctionNode* node, bool is_method, |
531 bool is_closure) { | 503 bool is_closure) { |
532 dart::Zone* zone = translation_helper.zone(); | 504 dart::Zone* zone = translation_helper.zone(); |
533 | 505 |
534 ASSERT(!(is_method && is_closure)); | 506 ASSERT(!(is_method && is_closure)); |
535 bool is_factory = function.IsFactory(); | 507 bool is_factory = function.IsFactory(); |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
585 function.SetParameterNameAt( | 557 function.SetParameterNameAt( |
586 pos, translation_helper.DartSymbol(named_expression->name())); | 558 pos, translation_helper.DartSymbol(named_expression->name())); |
587 } | 559 } |
588 | 560 |
589 const AbstractType& return_type = | 561 const AbstractType& return_type = |
590 type_translator.TranslateType(node->return_type()); | 562 type_translator.TranslateType(node->return_type()); |
591 function.set_result_type(return_type.IsMalformed() ? Type::dynamic_type() | 563 function.set_result_type(return_type.IsMalformed() ? Type::dynamic_type() |
592 : return_type); | 564 : return_type); |
593 } | 565 } |
594 | 566 |
| 567 |
595 void KernelReader::SetupFieldAccessorFunction(const dart::Class& klass, | 568 void KernelReader::SetupFieldAccessorFunction(const dart::Class& klass, |
596 const dart::Function& function) { | 569 const dart::Function& function) { |
597 bool is_setter = function.IsImplicitSetterFunction(); | 570 bool is_setter = function.IsImplicitSetterFunction(); |
598 bool is_method = !function.IsStaticFunction(); | 571 bool is_method = !function.IsStaticFunction(); |
599 intptr_t num_parameters = (is_method ? 1 : 0) + (is_setter ? 1 : 0); | 572 intptr_t num_parameters = (is_method ? 1 : 0) + (is_setter ? 1 : 0); |
600 | 573 |
601 function.SetNumOptionalParameters(0, false); | 574 function.SetNumOptionalParameters(0, false); |
602 function.set_num_fixed_parameters(num_parameters); | 575 function.set_num_fixed_parameters(num_parameters); |
603 function.set_parameter_types( | 576 function.set_parameter_types( |
604 Array::Handle(Z, Array::New(num_parameters, Heap::kOld))); | 577 Array::Handle(Z, Array::New(num_parameters, Heap::kOld))); |
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
670 // we do not risk allocating the class again by calling LookupClass | 643 // we do not risk allocating the class again by calling LookupClass |
671 // recursively from ReadPreliminaryClass for the same class. | 644 // recursively from ReadPreliminaryClass for the same class. |
672 classes_.Insert(klass, handle); | 645 classes_.Insert(klass, handle); |
673 if (!handle->is_type_finalized()) { | 646 if (!handle->is_type_finalized()) { |
674 ReadPreliminaryClass(handle, klass); | 647 ReadPreliminaryClass(handle, klass); |
675 } | 648 } |
676 } | 649 } |
677 return *handle; | 650 return *handle; |
678 } | 651 } |
679 | 652 |
| 653 |
680 RawFunction::Kind KernelReader::GetFunctionType(Procedure* kernel_procedure) { | 654 RawFunction::Kind KernelReader::GetFunctionType(Procedure* kernel_procedure) { |
681 intptr_t lookuptable[] = { | 655 intptr_t lookuptable[] = { |
682 RawFunction::kRegularFunction, // Procedure::kMethod | 656 RawFunction::kRegularFunction, // Procedure::kMethod |
683 RawFunction::kGetterFunction, // Procedure::kGetter | 657 RawFunction::kGetterFunction, // Procedure::kGetter |
684 RawFunction::kSetterFunction, // Procedure::kSetter | 658 RawFunction::kSetterFunction, // Procedure::kSetter |
685 RawFunction::kRegularFunction, // Procedure::kOperator | 659 RawFunction::kRegularFunction, // Procedure::kOperator |
686 RawFunction::kConstructor, // Procedure::kFactory | 660 RawFunction::kConstructor, // Procedure::kFactory |
687 }; | 661 }; |
688 intptr_t kind = static_cast<int>(kernel_procedure->kind()); | 662 intptr_t kind = static_cast<int>(kernel_procedure->kind()); |
689 if (kind == Procedure::kIncompleteProcedure) { | 663 if (kind == Procedure::kIncompleteProcedure) { |
690 return RawFunction::kSignatureFunction; | 664 return RawFunction::kSignatureFunction; |
691 } else { | 665 } else { |
692 ASSERT(0 <= kind && kind <= Procedure::kFactory); | 666 ASSERT(0 <= kind && kind <= Procedure::kFactory); |
693 return static_cast<RawFunction::Kind>(lookuptable[kind]); | 667 return static_cast<RawFunction::Kind>(lookuptable[kind]); |
694 } | 668 } |
695 } | 669 } |
696 | 670 |
| 671 |
697 } // namespace kernel | 672 } // namespace kernel |
698 } // namespace dart | 673 } // namespace dart |
OLD | NEW |