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

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

Issue 2485993002: VM: Support bootstrapping core libraries from Kernel binaries instead of source. (Closed)
Patch Set: Done Created 4 years, 1 month 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
OLDNEW
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
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
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
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
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
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698