Flutter Engine
The Flutter Engine
Loading...
Searching...
No Matches
kernel_loader.cc
Go to the documentation of this 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
3// BSD-style license that can be found in the LICENSE file.
4#if !defined(DART_PRECOMPILED_RUNTIME)
5
6#include "vm/kernel_loader.h"
7
8#include <string.h>
9
10#include <memory>
11
16#include "vm/dart_api_impl.h"
17#include "vm/flags.h"
18#include "vm/heap/heap.h"
19#include "vm/kernel_binary.h"
20#include "vm/longjump.h"
21#include "vm/object_store.h"
22#include "vm/parser.h"
23#include "vm/reusable_handles.h"
24#include "vm/service_isolate.h"
25#include "vm/symbols.h"
26#include "vm/thread.h"
27
28namespace dart {
29namespace kernel {
30
31#define Z (zone_)
32#define I (isolate_)
33#define IG (thread_->isolate_group())
34#define T (type_translator_)
35#define H (translation_helper_)
36
37static const char* const kVMServiceIOLibraryUri = "dart:vmservice_io";
38
40 public:
42 KernelReaderHelper* reader_helper)
43 : translation_helper_(*translation_helper),
44 zone_(translation_helper_.zone()),
45 simple_value_(nullptr),
46 helper_(reader_helper) {}
47
48 bool IsSimple(intptr_t kernel_offset) {
49 AlternativeReadingScope alt(&helper_->reader_, kernel_offset);
50 uint8_t payload = 0;
51 Tag tag = helper_->ReadTag(&payload); // read tag.
52 switch (tag) {
53 case kBigIntLiteral: {
54 helper_->ReadPosition();
55 const String& literal_str =
56 H.DartString(helper_->ReadStringReference(),
57 Heap::kOld); // read index into string table.
58 simple_value_ = &Integer::ZoneHandle(Z, Integer::New(literal_str));
59 if (simple_value_->IsNull()) {
60 H.ReportError("Integer literal %s is out of range",
61 literal_str.ToCString());
63 }
64 *simple_value_ = H.Canonicalize(*simple_value_);
65 return true;
66 }
67 case kStringLiteral:
68 helper_->ReadPosition();
69 simple_value_ = &H.DartSymbolPlain(
70 helper_->ReadStringReference()); // read index into string table.
71 return true;
72 case kSpecializedIntLiteral:
73 helper_->ReadPosition();
74 simple_value_ =
75 &Integer::ZoneHandle(Z, Integer::New(static_cast<int32_t>(payload) -
77 Heap::kOld));
78 *simple_value_ = H.Canonicalize(*simple_value_);
79 return true;
80 case kNegativeIntLiteral:
81 helper_->ReadPosition();
82 simple_value_ = &Integer::ZoneHandle(
83 Z, Integer::New(-static_cast<int64_t>(helper_->ReadUInt()),
84 Heap::kOld)); // read value.
85 *simple_value_ = H.Canonicalize(*simple_value_);
86 return true;
87 case kPositiveIntLiteral:
88 helper_->ReadPosition();
89 simple_value_ = &Integer::ZoneHandle(
90 Z, Integer::New(static_cast<int64_t>(helper_->ReadUInt()),
91 Heap::kOld)); // read value.
92 *simple_value_ = H.Canonicalize(*simple_value_);
93 return true;
94 case kDoubleLiteral:
95 helper_->ReadPosition();
96 simple_value_ = &Double::ZoneHandle(
97 Z, Double::New(helper_->ReadDouble(), Heap::kOld)); // read value.
98 *simple_value_ = H.Canonicalize(*simple_value_);
99 return true;
100 case kTrueLiteral:
101 helper_->ReadPosition();
102 simple_value_ = &Bool::Handle(Z, Bool::Get(true).ptr());
103 return true;
104 case kFalseLiteral:
105 helper_->ReadPosition();
106 simple_value_ = &Bool::Handle(Z, Bool::Get(false).ptr());
107 return true;
108 case kNullLiteral:
109 helper_->ReadPosition();
110 simple_value_ = &Instance::ZoneHandle(Z, Instance::null());
111 return true;
112 default:
113 return false;
114 }
115 }
116
117 const Instance& SimpleValue() { return *simple_value_; }
118 Zone* zone() const { return zone_; }
119
120 private:
121 TranslationHelper& translation_helper_;
122 Zone* zone_;
123 Instance* simple_value_;
124 KernelReaderHelper* helper_;
125
127};
128
129ArrayPtr KernelLoader::MakeFieldsArray() {
130 const intptr_t len = fields_.length();
131 const Array& res = Array::Handle(zone_, Array::New(len, Heap::kOld));
132 for (intptr_t i = 0; i < len; i++) {
133 res.SetAt(i, *fields_[i]);
134 }
135 return res.ptr();
136}
137
138ArrayPtr KernelLoader::MakeFunctionsArray() {
139 const intptr_t len = functions_.length();
140 const Array& res = Array::Handle(zone_, Array::New(len, Heap::kOld));
141 for (intptr_t i = 0; i < len; i++) {
142 res.SetAt(i, *functions_[i]);
143 }
144 return res.ptr();
145}
146
148 NameIndex library,
149 bool required) {
150 return loader_->LookupLibrary(library);
151}
152
154 bool required) {
155#if defined(DEBUG)
156 LibraryLookupHandleScope library_lookup_handle_scope(library_lookup_handle_);
157#endif // defined(DEBUG)
158 library_lookup_handle_ = loader_->LookupLibraryFromClass(klass);
159 return loader_->LookupClass(library_lookup_handle_, klass);
160}
161
163 : reader_(kernel_data) {
164 intptr_t data_size = reader_.size();
165
166 procedure_count_ = reader_.ReadUInt32At(data_size - 4);
167 procedure_index_offset_ = data_size - 4 - (procedure_count_ + 1) * 4;
168
169 class_count_ = reader_.ReadUInt32At(procedure_index_offset_ - 4);
170 class_index_offset_ = procedure_index_offset_ - 4 - (class_count_ + 1) * 4;
171
172 source_references_offset_ = -1;
173 source_references_offset_ = reader_.ReadUInt32At(class_index_offset_ - 4);
174}
175
176ClassIndex::ClassIndex(const TypedDataBase& library_kernel_data,
177 intptr_t class_offset,
178 intptr_t class_size)
179 : reader_(library_kernel_data) {
180 Init(class_offset, class_size);
181}
182
183void ClassIndex::Init(intptr_t class_offset, intptr_t class_size) {
184 procedure_count_ = reader_.ReadUInt32At(class_offset + class_size - 4);
185 procedure_index_offset_ =
186 class_offset + class_size - 4 - (procedure_count_ + 1) * 4;
187}
188
190
191KernelLoader::KernelLoader(Program* program,
192 UriToSourceTable* uri_to_source_table)
193 : program_(program),
194 thread_(Thread::Current()),
195 zone_(thread_->zone()),
196 no_active_isolate_scope_(),
197 patch_classes_(Array::Handle(zone_)),
198 active_class_(),
199 library_kernel_offset_(-1), // Set to the correct value in LoadLibrary
200 correction_offset_(-1), // Set to the correct value in LoadLibrary
201 loading_native_wrappers_library_(false),
202 library_kernel_data_(TypedDataView::Handle(zone_)),
203 kernel_program_info_(KernelProgramInfo::Handle(zone_)),
204 translation_helper_(this, thread_, Heap::kOld),
205 helper_(zone_,
206 &translation_helper_,
207 program_->binary(),
208 /*data_program_offset=*/0),
209 constant_reader_(&helper_, &active_class_),
210 type_translator_(&helper_,
211 &constant_reader_,
212 &active_class_,
213 /* finalize= */ false),
214 inferred_type_metadata_helper_(&helper_, &constant_reader_),
215 static_field_value_(Object::Handle(Z)),
216 name_index_handle_(Smi::Handle(Z)),
217 expression_evaluation_library_(Library::Handle(Z)) {
218 if (!program->is_single_program()) {
219 FATAL(
220 "Trying to load a concatenated dill file at a time where that is "
221 "not allowed");
222 }
223 InitializeFields(uri_to_source_table);
224}
225
226void KernelLoader::ReadObfuscationProhibitions() {
228 helper.ReadProhibitions();
229}
230
231void KernelLoader::ReadLoadingUnits() {
232 LoadingUnitsMetadataHelper helper(&helper_);
233 helper.ReadLoadingUnits();
234}
235
236Object& KernelLoader::LoadEntireProgram(Program* program,
237 bool process_pending_classes) {
238 Thread* thread = Thread::Current();
239
240 TIMELINE_DURATION(thread, Isolate, "LoadKernel");
241
242 if (program->is_single_program()) {
243 KernelLoader loader(program, /*uri_to_source_table=*/nullptr);
244 return Object::Handle(loader.LoadProgram(process_pending_classes));
245 }
246
247 GrowableArray<intptr_t> subprogram_file_starts;
248 {
249 kernel::Reader reader(program->binary());
250 index_programs(&reader, &subprogram_file_starts);
251 }
252
253 Zone* zone = thread->zone();
254 Library& library = Library::Handle(zone);
255 intptr_t subprogram_count = subprogram_file_starts.length() - 1;
256
257 // First index all source tables.
258 UriToSourceTable uri_to_source_table;
259 UriToSourceTableEntry wrapper;
260 Thread* thread_ = Thread::Current();
261 Zone* zone_ = thread_->zone();
262 for (intptr_t i = subprogram_count - 1; i >= 0; --i) {
263 intptr_t subprogram_start = subprogram_file_starts.At(i);
264 intptr_t subprogram_end = subprogram_file_starts.At(i + 1);
265 const auto& component = TypedDataBase::Handle(
266 program->binary().ViewFromTo(subprogram_start, subprogram_end));
267 TranslationHelper translation_helper(thread);
268 KernelReaderHelper helper_(zone_, &translation_helper, component, 0);
269 const intptr_t source_table_size = helper_.SourceTableSize();
270 for (intptr_t index = 0; index < source_table_size; ++index) {
271 const String& uri_string = helper_.SourceTableUriFor(index);
272 wrapper.uri = &uri_string;
273 TypedData& line_starts =
274 TypedData::Handle(Z, helper_.GetLineStartsFor(index));
275 if (line_starts.Length() == 0) continue;
276 const String& script_source = helper_.GetSourceFor(index);
277 wrapper.uri = &uri_string;
278 UriToSourceTableEntry* pair = uri_to_source_table.LookupValue(&wrapper);
279 if (pair != nullptr) {
280 // At least two entries with content. Unless the content is the same
281 // that's not valid.
282 const bool src_differ = pair->sources->CompareTo(script_source) != 0;
283 const bool line_starts_differ =
284 !pair->line_starts->CanonicalizeEquals(line_starts);
285 if (src_differ || line_starts_differ) {
286 FATAL(
287 "Invalid kernel binary: Contains at least two source entries "
288 "that do not agree. URI '%s', difference: %s. Subprogram count: "
289 "%" Pd ".",
290 uri_string.ToCString(),
291 src_differ && line_starts_differ
292 ? "src and line starts"
293 : (src_differ ? "src" : "line starts"),
294 subprogram_count);
295 }
296 } else {
298 tmp->uri = &uri_string;
299 tmp->sources = &script_source;
300 tmp->line_starts = &line_starts;
301 uri_to_source_table.Insert(tmp);
302 }
303 }
304 }
305
306 // Create "fake programs" for each sub-program.
307 for (intptr_t i = subprogram_count - 1; i >= 0; --i) {
308 intptr_t subprogram_start = subprogram_file_starts.At(i);
309 intptr_t subprogram_end = subprogram_file_starts.At(i + 1);
310 const auto& component = TypedDataBase::Handle(
311 program->binary().ViewFromTo(subprogram_start, subprogram_end));
312 Reader reader(component);
313 const char* error = nullptr;
314 std::unique_ptr<Program> subprogram = Program::ReadFrom(&reader, &error);
315 if (subprogram == nullptr) {
316 FATAL("Failed to load kernel file: %s", error);
317 }
318 ASSERT(subprogram->is_single_program());
319 KernelLoader loader(subprogram.get(), &uri_to_source_table);
320 Object& load_result = Object::Handle(loader.LoadProgram(false));
321 if (load_result.IsError()) return load_result;
322
323 if (load_result.IsLibrary()) {
324 library ^= load_result.ptr();
325 }
326 }
327
328 if (process_pending_classes && !ClassFinalizer::ProcessPendingClasses()) {
329 // Class finalization failed -> sticky error would be set.
330 return Error::Handle(thread->StealStickyError());
331 }
332
333 return library;
334}
335
336void KernelLoader::index_programs(
337 kernel::Reader* reader,
338 GrowableArray<intptr_t>* subprogram_file_starts) {
339 // Dill files can be concatenated (e.g. cat a.dill b.dill > c.dill), so we
340 // need to first index the (possibly combined) file.
341 // First entry becomes last entry.
342 // Last entry is for ease of calculating size of last subprogram.
343 subprogram_file_starts->Add(reader->size());
344 reader->set_offset(reader->size() - 4);
345 while (reader->offset() > 0) {
346 intptr_t size = reader->ReadUInt32();
347 intptr_t start = reader->offset() - size;
348 if (start < 0) {
349 FATAL("Invalid kernel binary: Indicated size is invalid.");
350 }
351 subprogram_file_starts->Add(start);
352 reader->set_offset(start - 4);
353 }
354 subprogram_file_starts->Reverse();
355}
356
357StringPtr KernelLoader::FindSourceForScript(const uint8_t* kernel_buffer,
358 intptr_t kernel_buffer_length,
359 const String& uri) {
361 kExternalTypedDataUint8ArrayCid, const_cast<uint8_t*>(kernel_buffer),
362 kernel_buffer_length, Heap::kNew));
363
364 Thread* thread = Thread::Current();
365 Zone* zone = thread->zone();
366 TranslationHelper translation_helper(thread);
367 KernelReaderHelper reader(zone, &translation_helper, binary, 0);
368 intptr_t source_table_size = reader.SourceTableSize();
369 for (intptr_t i = 0; i < source_table_size; ++i) {
370 const String& source_uri = reader.SourceTableUriFor(i);
371 if (source_uri.EndsWith(uri)) {
372 return reader.GetSourceFor(i).ptr();
373 }
374 }
375 return String::null();
376}
377
378void KernelLoader::InitializeFields(UriToSourceTable* uri_to_source_table) {
379 const intptr_t source_table_size = helper_.SourceTableSize();
380 const Array& scripts =
381 Array::Handle(Z, Array::New(source_table_size, Heap::kOld));
382
383 const auto& binary = program_->binary();
384
385 // Copy the Kernel string offsets out of the binary and into the VM's heap.
386 ASSERT(program_->string_table_offset() >= 0);
387 Reader reader(binary);
388 reader.set_offset(program_->string_table_offset());
389 intptr_t count = reader.ReadUInt() + 1;
390 const auto& offsets = TypedData::Handle(
391 Z, TypedData::New(kTypedDataUint32ArrayCid, count, Heap::kOld));
392 offsets.SetUint32(0, 0);
393 intptr_t end_offset = 0;
394 for (intptr_t i = 1; i < count; ++i) {
395 end_offset = reader.ReadUInt();
396 offsets.SetUint32(i << 2, end_offset);
397 }
398
399 // Create view of the string data.
400 const auto& string_data = TypedDataView::Handle(
401 reader.ViewFromTo(reader.offset(), reader.offset() + end_offset));
402
403 // Create a view of the constants table.
404 const auto& constants_table = TypedDataView::Handle(reader.ViewFromTo(
405 program_->constant_table_offset(), program_->name_table_offset()));
406
407 // Copy the canonical names into the VM's heap. Encode them as unsigned, so
408 // the parent indexes are adjusted when extracted.
409 reader.set_offset(program_->name_table_offset());
410 count = reader.ReadUInt() * 2;
412 Z, TypedData::New(kTypedDataUint32ArrayCid, count, Heap::kOld));
413 for (intptr_t i = 0; i < count; ++i) {
414 names.SetUint32(i << 2, reader.ReadUInt());
415 }
416
417 // Create view of metadata payloads.
418 const auto& metadata_payloads = TypedDataView::Handle(
419 reader.ViewFromTo(program_->metadata_payloads_offset(),
420 program_->metadata_mappings_offset()));
421
422 ASSERT(Utils::IsAligned(metadata_payloads.DataAddr(0), kWordSize));
423
424 // Create view of metadata mappings.
425 const auto& metadata_mappings = TypedDataView::Handle(reader.ViewFromTo(
426 program_->metadata_mappings_offset(), program_->string_table_offset()));
427
428#if defined(DEBUG)
429 MetadataHelper::VerifyMetadataMappings(metadata_mappings);
430#endif
431
432 const Array& libraries_cache =
433 Array::Handle(Z, HashTables::New<UnorderedHashMap<SmiTraits>>(
434 program_->library_count(), Heap::kOld));
435
436 const intptr_t kClassesPerLibraryGuess = 5;
437 const Array& classes_cache = Array::Handle(
438 Z, HashTables::New<UnorderedHashMap<SmiTraits>>(
439 kClassesPerLibraryGuess * program_->library_count(), Heap::kOld));
440
441 kernel_program_info_ = KernelProgramInfo::New(
442 binary, string_data, metadata_payloads, metadata_mappings,
443 constants_table, offsets, names, scripts, libraries_cache, classes_cache);
444
445 H.InitFromKernelProgramInfo(kernel_program_info_);
446
447 Script& script = Script::Handle(Z);
448 for (intptr_t index = 0; index < source_table_size; ++index) {
449 script = LoadScriptAt(index, uri_to_source_table);
450 scripts.SetAt(index, script);
451 }
452}
453
454KernelLoader::KernelLoader(const KernelProgramInfo& kernel_program_info,
455 const TypedDataBase& kernel_data,
456 intptr_t data_program_offset)
457 : program_(nullptr),
458 thread_(Thread::Current()),
459 zone_(thread_->zone()),
460 no_active_isolate_scope_(),
461 patch_classes_(Array::Handle(zone_)),
462 library_kernel_offset_(data_program_offset),
463 correction_offset_(0),
464 loading_native_wrappers_library_(false),
465 library_kernel_data_(TypedDataView::Handle(zone_)),
466 kernel_program_info_(
467 KernelProgramInfo::Handle(zone_, kernel_program_info.ptr())),
468 translation_helper_(this, thread_, Heap::kOld),
469 helper_(zone_, &translation_helper_, kernel_data, 0),
470 constant_reader_(&helper_, &active_class_),
471 type_translator_(&helper_,
472 &constant_reader_,
473 &active_class_,
474 /* finalize= */ false),
475 inferred_type_metadata_helper_(&helper_, &constant_reader_),
476 static_field_value_(Object::Handle(Z)),
477 name_index_handle_(Smi::Handle(Z)),
478 expression_evaluation_library_(Library::Handle(Z)) {
479 ASSERT(T.active_class_ == &active_class_);
480 T.finalize_ = false;
481 H.InitFromKernelProgramInfo(kernel_program_info_);
482}
483
484bool KernelLoader::IsClassName(NameIndex name,
485 const String& library,
486 const String& klass) {
487 ASSERT(H.IsClass(name));
488 StringIndex class_name_index = H.CanonicalNameString(name);
489
490 if (!H.StringEquals(class_name_index, klass.ToCString())) {
491 return false;
492 }
493 ASSERT(H.IsLibrary(H.CanonicalNameParent(name)));
494 StringIndex library_name_index =
495 H.CanonicalNameString(H.CanonicalNameParent(name));
496 return H.StringEquals(library_name_index, library.ToCString());
497}
498
499ObjectPtr KernelLoader::LoadProgram(bool process_pending_classes) {
500 SafepointWriteRwLocker ml(thread_, thread_->isolate_group()->program_lock());
501 ASSERT(kernel_program_info_.constants() == Array::null());
502
503 if (!program_->is_single_program()) {
504 FATAL(
505 "Trying to load a concatenated dill file at a time where that is "
506 "not allowed");
507 }
508
509 LongJumpScope jump;
510 if (setjmp(*jump.Set()) == 0) {
511 // Note that `problemsAsJson` on Component is implicitly skipped.
512 const intptr_t length = program_->library_count();
513 for (intptr_t i = 0; i < length; i++) {
514 LoadLibrary(i);
515 }
516
517 // Finalize still pending classes if requested.
518 if (process_pending_classes) {
520 // Class finalization failed -> sticky error would be set.
521 return H.thread()->StealStickyError();
522 }
523 }
524
525 // Sets the constants array to an empty array with the length equal to
526 // the number of constants. The array gets filled lazily while reading
527 // constants.
528 ASSERT(kernel_program_info_.constants_table() != ExternalTypedData::null());
529 ConstantReader constant_reader(&helper_, &active_class_);
530 const intptr_t num_consts = constant_reader.NumConstants();
531 const Array& array = Array::Handle(Z, Array::New(num_consts, Heap::kOld));
532 for (intptr_t i = 0; i < num_consts; i++) {
533 array.SetAt(i, Object::sentinel());
534 }
535 kernel_program_info_.set_constants(array);
536 H.SetConstants(array); // for caching
537
538 NameIndex main = program_->main_method();
539 if (main != -1) {
540 NameIndex main_library = H.EnclosingName(main);
541 return LookupLibrary(main_library);
542 }
543
544 return Library::null();
545 }
546
547 // Either class finalization failed or we caught a compile error.
548 // In both cases sticky error would be set.
550}
551
552void KernelLoader::LoadLibrary(const Library& library) {
553 // This will be invoked by VM bootstrapping code.
554 SafepointWriteRwLocker ml(thread_, thread_->isolate_group()->program_lock());
555
556 ASSERT(!library.Loaded());
557
558 const auto& uri = String::Handle(Z, library.url());
559 const intptr_t num_libraries = program_->library_count();
560 for (intptr_t i = 0; i < num_libraries; ++i) {
561 const String& library_uri = LibraryUri(i);
562 if (library_uri.Equals(uri)) {
563 LoadLibrary(i);
564 return;
565 }
566 }
567}
568
570 const String& library_url,
571 const String& klass) {
572 // Find the original context, i.e. library/class, in which the evaluation will
573 // happen.
574 const Library& real_library =
575 Library::Handle(Z, Library::LookupLibrary(thread_, library_url));
576 ASSERT(!real_library.IsNull());
577 const Class& real_class = Class::Handle(
578 Z, klass.IsNull() ? real_library.toplevel_class()
579 : real_library.LookupClassAllowPrivate(klass));
580 ASSERT(!real_class.IsNull());
581
582 const intptr_t num_cids = IG->class_table()->NumCids();
583 const intptr_t num_libs =
584 GrowableObjectArray::Handle(IG->object_store()->libraries()).Length();
585
586 // Load the "evaluate:source" expression evaluation library.
587 ASSERT(expression_evaluation_library_.IsNull());
588 ASSERT(H.GetExpressionEvaluationClass().IsNull());
589 ASSERT(H.GetExpressionEvaluationFunction().IsNull());
590 H.SetExpressionEvaluationRealClass(real_class);
591 const Object& result = Object::Handle(Z, LoadProgram(true));
592 if (result.IsError()) {
593 return result.ptr();
594 }
595 const Function& function = H.GetExpressionEvaluationFunction();
596 ASSERT(!function.IsNull());
597 ASSERT(
598 GrowableObjectArray::Handle(IG->object_store()->libraries()).Length() ==
599 num_libs);
600 ASSERT(IG->class_table()->NumCids() == num_cids);
601
602 // Make the expression evaluation function have the right script,
603 // kernel data and parent.
604 const auto& eval_script = Script::Handle(Z, function.script());
605 ASSERT(!expression_evaluation_library_.IsNull());
606 function.SetKernelLibraryAndEvalScript(
607 eval_script, kernel_program_info_,
608 expression_evaluation_library_.kernel_library_index());
609
610 function.set_owner(real_class);
611
612 ASSERT(real_class.is_finalized());
613 // The owner class has already been marked as finalized so the signature of
614 // this added function must be finalized here, since finalization of member
615 // types will not be called anymore.
616 FunctionType& signature = FunctionType::Handle(Z, function.signature());
617 if (!function.is_static()) {
618 // Patch the illegal receiver type (type class with kIllegalCid) to dynamic.
619 signature.SetParameterTypeAt(0, Object::dynamic_type());
620 }
621 signature ^= ClassFinalizer::FinalizeType(signature);
622 function.SetSignature(signature);
623
624 return function.ptr();
625}
626
628 IsolateGroup* isolate_group,
629 BitVector* modified_libs,
630 bool force_reload,
631 bool* is_empty_program,
632 intptr_t* p_num_classes,
633 intptr_t* p_num_procedures) {
634 LongJumpScope jump;
635 Zone* zone = Thread::Current()->zone();
636 if (setjmp(*jump.Set()) == 0) {
637 if (force_reload) {
638 // If a reload is being forced we mark all libraries as having
639 // been modified.
640 const auto& libs = GrowableObjectArray::Handle(
641 isolate_group->object_store()->libraries());
642 intptr_t num_libs = libs.Length();
643 Library& lib = dart::Library::Handle(zone);
644 for (intptr_t i = 0; i < num_libs; i++) {
645 lib ^= libs.At(i);
646 if (!lib.is_dart_scheme()) {
647 modified_libs->Add(lib.index());
648 }
649 }
650 return;
651 }
652
653 if (p_num_classes != nullptr) {
654 *p_num_classes = 0;
655 }
656 if (p_num_procedures != nullptr) {
657 *p_num_procedures = 0;
658 }
659
660 // Now go through all the libraries that are present in the incremental
661 // kernel files, these will constitute the modified libraries.
662 *is_empty_program = true;
663 if (program->is_single_program()) {
664 KernelLoader loader(program, /*uri_to_source_table=*/nullptr);
665 loader.walk_incremental_kernel(modified_libs, is_empty_program,
666 p_num_classes, p_num_procedures);
667 }
668
669 GrowableArray<intptr_t> subprogram_file_starts;
670 {
671 kernel::Reader reader(program->binary());
672 index_programs(&reader, &subprogram_file_starts);
673 }
674
675 // Create "fake programs" for each sub-program.
676 intptr_t subprogram_count = subprogram_file_starts.length() - 1;
677 for (intptr_t i = 0; i < subprogram_count; ++i) {
678 intptr_t subprogram_start = subprogram_file_starts.At(i);
679 intptr_t subprogram_end = subprogram_file_starts.At(i + 1);
680 const auto& component = TypedDataBase::Handle(
681 program->binary().ViewFromTo(subprogram_start, subprogram_end));
682 Reader reader(component);
683 const char* error = nullptr;
684 std::unique_ptr<Program> subprogram = Program::ReadFrom(&reader, &error);
685 if (subprogram == nullptr) {
686 FATAL("Failed to load kernel file: %s", error);
687 }
688 ASSERT(subprogram->is_single_program());
689 KernelLoader loader(subprogram.get(), /*uri_to_source_table=*/nullptr);
690 loader.walk_incremental_kernel(modified_libs, is_empty_program,
691 p_num_classes, p_num_procedures);
692 }
693 }
694}
695
696void KernelLoader::walk_incremental_kernel(BitVector* modified_libs,
697 bool* is_empty_program,
698 intptr_t* p_num_classes,
699 intptr_t* p_num_procedures) {
700 intptr_t length = program_->library_count();
701 *is_empty_program = *is_empty_program && (length == 0);
702 bool collect_library_stats =
703 p_num_classes != nullptr || p_num_procedures != nullptr;
704 intptr_t num_classes = 0;
705 intptr_t num_procedures = 0;
706 Library& lib = Library::Handle(Z);
707 for (intptr_t i = 0; i < length; i++) {
708 intptr_t kernel_offset = library_offset(i);
709 helper_.SetOffset(kernel_offset);
710 LibraryHelper library_helper(&helper_);
711 library_helper.ReadUntilIncluding(LibraryHelper::kCanonicalName);
712 lib = LookupLibraryOrNull(library_helper.canonical_name_);
713 if (!lib.IsNull() && !lib.is_dart_scheme()) {
714 // This is a library that already exists so mark it as being modified.
715 modified_libs->Add(lib.index());
716 }
717 if (collect_library_stats) {
718 intptr_t library_end = library_offset(i + 1);
719 library_kernel_data_ =
720 helper_.reader_.ViewFromTo(kernel_offset, library_end);
721 LibraryIndex library_index(library_kernel_data_);
722 num_classes += library_index.class_count();
723 num_procedures += library_index.procedure_count();
724 }
725 }
726 if (p_num_classes != nullptr) {
727 *p_num_classes += num_classes;
728 }
729 if (p_num_procedures != nullptr) {
730 *p_num_procedures += num_procedures;
731 }
732}
733
734void KernelLoader::ReadInferredType(const Field& field,
735 intptr_t kernel_offset) {
736 const InferredTypeMetadata type =
737 inferred_type_metadata_helper_.GetInferredType(kernel_offset,
738 /*read_constant=*/false);
739 if (type.IsTrivial()) {
740 return;
741 }
742 field.set_guarded_cid(type.cid);
743 field.set_is_nullable(type.IsNullable());
744 field.set_guarded_list_length(Field::kNoFixedLength);
745 if (FLAG_precompiled_mode) {
746 field.set_is_unboxed(!field.is_late() && !field.is_static() &&
747 !field.is_nullable() &&
748 ((field.guarded_cid() == kDoubleCid &&
750 (field.guarded_cid() == kFloat32x4Cid &&
752 (field.guarded_cid() == kFloat64x2Cid &&
754 type.IsInt()));
755 }
756}
757
758void KernelLoader::CheckForInitializer(const Field& field) {
759 if (helper_.PeekTag() == kSomething) {
760 field.set_has_initializer(true);
761 SimpleExpressionConverter converter(&H, &helper_);
762 const bool has_simple_initializer =
763 converter.IsSimple(helper_.ReaderOffset() + 1);
764 if (!has_simple_initializer ||
765 (!field.is_static() && !converter.SimpleValue().IsNull())) {
766 field.set_has_nontrivial_initializer(true);
767 }
768 return;
769 }
770 field.set_has_initializer(false);
771 field.set_has_nontrivial_initializer(false);
772}
773
774LibraryPtr KernelLoader::LoadLibrary(intptr_t index) {
775 if (!program_->is_single_program()) {
776 FATAL(
777 "Trying to load a concatenated dill file at a time where that is "
778 "not allowed");
779 }
780
781 // Read library index.
782 library_kernel_offset_ = library_offset(index);
783 correction_offset_ = library_kernel_offset_;
784 intptr_t library_end = library_offset(index + 1);
785 intptr_t library_size = library_end - library_kernel_offset_;
786
787 // NOTE: Since |helper_| is used to load the overall kernel program,
788 // it's reader's offset is an offset into the overall kernel program.
789 // Hence, when setting the kernel offsets of field and functions, one
790 // has to subtract the library's kernel offset from the reader's
791 // offset.
792 helper_.SetOffset(library_kernel_offset_);
793
794 LibraryHelper library_helper(&helper_);
795 library_helper.ReadUntilIncluding(LibraryHelper::kCanonicalName);
796 if (!FLAG_precompiled_mode && !IG->should_load_vmservice()) {
797 StringIndex lib_name_index =
798 H.CanonicalNameString(library_helper.canonical_name_);
799 if (H.StringEquals(lib_name_index, kVMServiceIOLibraryUri)) {
800 // We are not the service isolate and we are not generating an AOT
801 // snapshot so we skip loading 'dart:vmservice_io'.
802 skip_vmservice_library_ = library_helper.canonical_name_;
803 ASSERT(H.IsLibrary(skip_vmservice_library_));
804 return Library::null();
805 }
806 }
807
808 Library& library =
809 Library::Handle(Z, LookupLibrary(library_helper.canonical_name_));
810
811 if (library.Loaded()) return library.ptr();
812
813 if (!library_helper.IsNonNullableByDefault()) {
814 H.ReportError(
815 "Library '%s' was compiled without sound null safety (in weak mode) "
816 "and it cannot be used at runtime",
817 String::Handle(library.url()).ToCString());
818 }
819 const NNBDCompiledMode mode =
820 library_helper.GetNonNullableByDefaultCompiledMode();
821 if (mode == NNBDCompiledMode::kInvalid) {
822 H.ReportError(
823 "Library '%s' was compiled in an unsupported mixed mode between sound "
824 "null safety and not sound null safety.",
825 String::Handle(library.url()).ToCString());
826 }
827 if (mode == NNBDCompiledMode::kWeak) {
828 H.ReportError(
829 "Library '%s' was compiled without sound null safety (in weak mode) "
830 "and it cannot be used at runtime",
831 String::Handle(library.url()).ToCString());
832 }
833
834 library_kernel_data_ = helper_.reader_.ViewFromTo(
835 library_kernel_offset_, library_kernel_offset_ + library_size);
836 library.set_kernel_library_index(index);
837 library.set_kernel_program_info(kernel_program_info_);
838
839 const intptr_t start_offset =
840 kernel_program_info_.KernelLibraryStartOffset(index);
841 const intptr_t end_offset =
842 kernel_program_info_.KernelLibraryEndOffset(index);
843 library_kernel_data_ = helper_.reader_.ViewFromTo(start_offset, end_offset);
844 LibraryIndex library_index(library_kernel_data_);
845 intptr_t class_count = library_index.class_count();
846
847 library_helper.ReadUntilIncluding(LibraryHelper::kName);
848 library.SetName(H.DartSymbolObfuscate(library_helper.name_index_));
849
850 // The bootstrapper will take care of creating the native wrapper classes, but
851 // we will add the synthetic constructors to them here.
852 if (library.name() ==
853 Symbols::Symbol(Symbols::kDartNativeWrappersLibNameId).ptr()) {
854 ASSERT(library.LoadInProgress());
855 loading_native_wrappers_library_ = true;
856 } else {
857 loading_native_wrappers_library_ = false;
858 library.SetLoadInProgress();
859 }
860
861 if (library.url() == Symbols::vm_ffi_native_assets().ptr()) {
862 const auto& native_assets_library =
863 Library::Handle(IG->object_store()->native_assets_library());
864 ASSERT(native_assets_library.IsNull());
865 IG->object_store()->set_native_assets_library(library);
866 }
867
868 library_helper.ReadUntilIncluding(LibraryHelper::kSourceUriIndex);
869 const Script& script =
870 Script::Handle(Z, ScriptAt(library_helper.source_uri_index_));
871
872 library_helper.ReadUntilExcluding(LibraryHelper::kAnnotations);
873 intptr_t annotations_kernel_offset =
874 helper_.ReaderOffset() - correction_offset_;
875 const intptr_t annotation_count =
876 helper_.ReadListLength(); // read list length.
877 for (intptr_t i = 0; i < annotation_count; ++i) {
878 helper_.SkipExpression(); // read ith annotation.
879 }
880 library_helper.SetJustRead(LibraryHelper::kAnnotations);
881
882 // Setup toplevel class (which contains library fields/procedures).
883
884 // We do not register expression evaluation classes with the VM:
885 // The expression evaluation functions should be GC-able as soon as
886 // they are not reachable anymore and we never look them up by name.
887 const bool register_class =
888 library.ptr() != expression_evaluation_library_.ptr();
889
890 Class& toplevel_class =
891 Class::Handle(Z, Class::New(library, Symbols::TopLevel(), script,
892 TokenPosition::kNoSource, register_class));
893 toplevel_class.set_is_abstract();
894 toplevel_class.set_is_declaration_loaded();
895 toplevel_class.set_is_type_finalized();
896 toplevel_class.set_num_type_arguments_unsafe(0);
897 library.set_toplevel_class(toplevel_class);
898
899 library_helper.ReadUntilExcluding(LibraryHelper::kDependencies);
900 LoadLibraryImportsAndExports(&library, toplevel_class);
901 library_helper.SetJustRead(LibraryHelper::kDependencies);
902
903 // Everything up til the classes are skipped implicitly, and library_helper
904 // is no longer used.
905
906 const GrowableObjectArray& classes =
907 GrowableObjectArray::Handle(Z, IG->object_store()->pending_classes());
908
909 // Load all classes.
910 intptr_t next_class_offset = library_index.ClassOffset(0);
911 Class& klass = Class::Handle(Z);
912 for (intptr_t i = 0; i < class_count; ++i) {
913 helper_.SetOffset(next_class_offset);
914 next_class_offset = library_index.ClassOffset(i + 1);
915 LoadClass(library, toplevel_class, next_class_offset, &klass);
916 if (register_class) {
917 classes.Add(klass, Heap::kOld);
918 }
919 }
920
921 if (loading_native_wrappers_library_ || !register_class) {
922 FinishTopLevelClassLoading(toplevel_class, library, library_index);
923 }
924
925 // Used for mirrors and allows VM to recognize @pragma annotations on
926 // libraries.
927 if (annotation_count > 0) {
928 ASSERT(annotations_kernel_offset > 0);
929 library.AddMetadata(library, annotations_kernel_offset);
930 }
931
932 if (register_class) {
933 helper_.SetOffset(library_index.SourceReferencesOffset());
934 intptr_t count = helper_.ReadUInt();
935 const GrowableObjectArray& used_scripts =
936 GrowableObjectArray::Handle(library.used_scripts());
937 Script& script = Script::Handle(Z);
938 for (intptr_t i = 0; i < count; i++) {
939 intptr_t uri_index = helper_.ReadUInt();
940 script = ScriptAt(uri_index);
941 used_scripts.Add(script);
942 }
943 }
944 if (!library.Loaded()) library.SetLoaded();
945
946 return library.ptr();
947}
948
949void KernelLoader::FinishTopLevelClassLoading(
950 const Class& toplevel_class,
951 const Library& library,
952 const LibraryIndex& library_index) {
953 if (toplevel_class.is_loaded()) {
954 return;
955 }
956 TIMELINE_DURATION(Thread::Current(), Isolate, "FinishTopLevelClassLoading");
957
958 ActiveClassScope active_class_scope(&active_class_, &toplevel_class);
959
960 // Offsets within library index are whole program offsets and not
961 // relative to the library.
962 const intptr_t correction = correction_offset_ - library_kernel_offset_;
963 helper_.SetOffset(library_index.ClassOffset(library_index.class_count()) +
964 correction);
965
966 const intptr_t extension_count = helper_.ReadListLength();
967 for (intptr_t i = 0; i < extension_count; ++i) {
968 helper_.ReadTag(); // read tag.
969 helper_.SkipCanonicalNameReference(); // skip canonical name.
970 helper_.SkipStringReference(); // skip name.
971 helper_.SkipListOfExpressions(); // skip annotations.
972 helper_.ReadUInt(); // read source uri index.
973 helper_.ReadPosition(); // read file offset.
974 helper_.ReadByte(); // skip flags.
975 helper_.SkipTypeParametersList(); // skip type parameter list.
976 helper_.SkipDartType(); // skip on-type.
977
978 const intptr_t extension_member_count = helper_.ReadListLength();
979 for (intptr_t j = 0; j < extension_member_count; ++j) {
980 helper_.SkipName(); // skip name.
981 helper_.ReadByte(); // read kind.
982 helper_.ReadByte(); // read flags.
983 helper_.SkipCanonicalNameReference(); // skip member reference
984 helper_.SkipCanonicalNameReference(); // skip tear-off reference
985 }
986 }
987
988 const intptr_t extension_type_declaration_count = helper_.ReadListLength();
989 for (intptr_t i = 0; i < extension_type_declaration_count; ++i) {
990 helper_.ReadTag(); // read tag.
991 helper_.SkipCanonicalNameReference(); // skip canonical name.
992 helper_.SkipStringReference(); // skip name.
993 helper_.SkipListOfExpressions(); // skip annotations.
994 helper_.ReadUInt(); // read source uri index.
995 helper_.ReadPosition(); // read file offset.
996 helper_.ReadByte(); // skip flags.
997 helper_.SkipTypeParametersList(); // skip type parameter list.
998 helper_.SkipDartType(); // skip declared representation type.
999 helper_.SkipStringReference(); // skip representation name.
1000 helper_.SkipListOfDartTypes(); // skip implements types.
1001
1002 // Skip extension type procedures.
1003 const intptr_t extension_type_procedure_count =
1004 helper_.ReadListLength(); // read list length.
1005 for (intptr_t i = 0; i < extension_type_procedure_count; ++i) {
1006 ProcedureHelper procedure_helper(&helper_);
1007 procedure_helper.ReadUntilExcluding(ProcedureHelper::kEnd);
1008 }
1009
1010 const intptr_t extension_type_member_count = helper_.ReadListLength();
1011 for (intptr_t j = 0; j < extension_type_member_count; ++j) {
1012 helper_.SkipName(); // skip name.
1013 helper_.ReadByte(); // read kind.
1014 helper_.ReadByte(); // read flags.
1015 helper_.SkipCanonicalNameReference(); // skip member reference
1016 helper_.SkipCanonicalNameReference(); // skip tear-off reference
1017 }
1018 }
1019
1020 fields_.Clear();
1021 functions_.Clear();
1022
1023 // Load toplevel fields.
1024 const intptr_t field_count = helper_.ReadListLength(); // read list length.
1025 for (intptr_t i = 0; i < field_count; ++i) {
1026 intptr_t field_offset = helper_.ReaderOffset() - correction_offset_;
1027 ActiveMemberScope active_member_scope(&active_class_, nullptr);
1028 FieldHelper field_helper(&helper_);
1029 field_helper.ReadUntilExcluding(FieldHelper::kName);
1030
1031 const String& name = helper_.ReadNameAsFieldName();
1032 field_helper.SetJustRead(FieldHelper::kName);
1033
1034 field_helper.ReadUntilExcluding(FieldHelper::kAnnotations);
1035 intptr_t annotation_count = helper_.ReadListLength();
1036 uint32_t pragma_bits = 0;
1037 ReadVMAnnotations(annotation_count, &pragma_bits);
1038 field_helper.SetJustRead(FieldHelper::kAnnotations);
1039
1040 field_helper.ReadUntilExcluding(FieldHelper::kType);
1041 const Object& script_class =
1042 ClassForScriptAt(toplevel_class, field_helper.source_uri_index_);
1043 // In the VM all const fields are implicitly final whereas in Kernel they
1044 // are not final because they are not explicitly declared that way.
1045 const bool is_final = field_helper.IsConst() || field_helper.IsFinal();
1046 // Only instance fields could be covariant.
1047 ASSERT(!field_helper.IsCovariant() &&
1048 !field_helper.IsGenericCovariantImpl());
1049 const bool is_late = field_helper.IsLate();
1050 const bool is_extension_member = field_helper.IsExtensionMember();
1051 const bool is_extension_type_member = field_helper.IsExtensionTypeMember();
1052 const Field& field = Field::Handle(
1053 Z, Field::NewTopLevel(name, is_final, field_helper.IsConst(), is_late,
1054 script_class, field_helper.position_,
1055 field_helper.end_position_));
1056 field.set_kernel_offset(field_offset);
1057 field.set_has_pragma(HasPragma::decode(pragma_bits));
1058 field.set_is_extension_member(is_extension_member);
1059 field.set_is_extension_type_member(is_extension_type_member);
1060 const AbstractType& type = T.BuildType(); // read type.
1061 field.SetFieldType(type);
1062 ReadInferredType(field, field_offset + library_kernel_offset_);
1063 CheckForInitializer(field);
1064 // Static fields with initializers are implicitly late.
1065 if (field.has_initializer()) {
1066 field.set_is_late(true);
1067 }
1068 field_helper.SetJustRead(FieldHelper::kType);
1069 field_helper.ReadUntilExcluding(FieldHelper::kInitializer);
1070 intptr_t field_initializer_offset = helper_.ReaderOffset();
1071 field_helper.ReadUntilExcluding(FieldHelper::kEnd);
1072
1073 {
1074 AlternativeReadingScope alt(&helper_.reader_, field_initializer_offset);
1075 static_field_value_ = ReadInitialFieldValue(field, &field_helper);
1076 }
1077 GenerateFieldAccessors(toplevel_class, field, &field_helper);
1078 IG->RegisterStaticField(field, static_field_value_);
1079
1080 if ((FLAG_enable_mirrors || HasPragma::decode(pragma_bits)) &&
1081 annotation_count > 0) {
1082 library.AddMetadata(field, field_offset);
1083 }
1084 fields_.Add(&field);
1085 }
1086
1087 ASSERT(!toplevel_class.is_loaded());
1088
1089 // Load toplevel procedures.
1090 intptr_t next_procedure_offset =
1091 library_index.ProcedureOffset(0) + correction;
1092 const intptr_t procedure_count = library_index.procedure_count();
1093 for (intptr_t i = 0; i < procedure_count; ++i) {
1094 helper_.SetOffset(next_procedure_offset);
1095 next_procedure_offset = library_index.ProcedureOffset(i + 1) + correction;
1096 LoadProcedure(library, toplevel_class, false, next_procedure_offset);
1097 // LoadProcedure calls Library::GetMetadata which invokes Dart code
1098 // which may recursively trigger class finalization and
1099 // FinishTopLevelClassLoading.
1100 // In such case, return immediately and avoid overwriting already finalized
1101 // functions with freshly loaded and not yet finalized.
1102 if (toplevel_class.is_loaded()) {
1103 return;
1104 }
1105 }
1106
1107 toplevel_class.SetFields(Array::Handle(MakeFieldsArray()));
1108 toplevel_class.SetFunctions(Array::Handle(MakeFunctionsArray()));
1109
1110 String& name = String::Handle(Z);
1111 for (intptr_t i = 0, n = fields_.length(); i < n; ++i) {
1112 const Field* field = fields_.At(i);
1113 name = field->name();
1114 library.AddObject(*field, name);
1115 }
1116 for (intptr_t i = 0, n = functions_.length(); i < n; ++i) {
1117 const Function* function = functions_.At(i);
1118 name = function->name();
1119 library.AddObject(*function, name);
1120 }
1121
1122 ASSERT(!toplevel_class.is_loaded());
1123 toplevel_class.set_is_loaded(true);
1124}
1125
1126void KernelLoader::LoadLibraryImportsAndExports(Library* library,
1127 const Class& toplevel_class) {
1128 GrowableObjectArray& show_list = GrowableObjectArray::Handle(Z);
1129 GrowableObjectArray& hide_list = GrowableObjectArray::Handle(Z);
1130 Array& show_names = Array::Handle(Z);
1131 Array& hide_names = Array::Handle(Z);
1132 Namespace& ns = Namespace::Handle(Z);
1133 LibraryPrefix& library_prefix = LibraryPrefix::Handle(Z);
1134
1135 const intptr_t deps_count = helper_.ReadListLength();
1136 const Array& deps = Array::Handle(Array::New(deps_count));
1137 for (intptr_t dep = 0; dep < deps_count; ++dep) {
1138 LibraryDependencyHelper dependency_helper(&helper_);
1139
1140 dependency_helper.ReadUntilExcluding(LibraryDependencyHelper::kAnnotations);
1141 intptr_t annotations_kernel_offset =
1142 helper_.ReaderOffset() - correction_offset_;
1143
1144 dependency_helper.ReadUntilExcluding(LibraryDependencyHelper::kCombinators);
1145
1146 // Ignore the dependency if the target library is invalid.
1147 // The error will be caught during compilation.
1148 if (dependency_helper.target_library_canonical_name_ < 0) {
1149 const intptr_t combinator_count = helper_.ReadListLength();
1150 for (intptr_t c = 0; c < combinator_count; ++c) {
1151 helper_.SkipLibraryCombinator();
1152 }
1153 continue;
1154 }
1155
1156 // Prepare show and hide lists.
1159 const intptr_t combinator_count = helper_.ReadListLength();
1160 for (intptr_t c = 0; c < combinator_count; ++c) {
1161 uint8_t flags = helper_.ReadFlags();
1162 intptr_t name_count = helper_.ReadListLength();
1163 for (intptr_t n = 0; n < name_count; ++n) {
1164 String& show_hide_name =
1165 H.DartSymbolObfuscate(helper_.ReadStringReference());
1166 if ((flags & LibraryDependencyHelper::Show) != 0) {
1167 show_list.Add(show_hide_name, Heap::kOld);
1168 } else {
1169 hide_list.Add(show_hide_name, Heap::kOld);
1170 }
1171 }
1172 }
1173
1174 if (show_list.Length() > 0) {
1175 show_names = Array::MakeFixedLength(show_list);
1176 } else {
1177 show_names = Array::null();
1178 }
1179
1180 if (hide_list.Length() > 0) {
1181 hide_names = Array::MakeFixedLength(hide_list);
1182 } else {
1183 hide_names = Array::null();
1184 }
1185
1186 Library& target_library = Library::Handle(
1187 Z, LookupLibrary(dependency_helper.target_library_canonical_name_));
1188 if (!FLAG_enable_mirrors &&
1189 target_library.url() == Symbols::DartMirrors().ptr()) {
1190 H.ReportError(
1191 "import of dart:mirrors is not supported in the current Dart "
1192 "runtime");
1193 }
1194 if (!Api::IsFfiEnabled() &&
1195 target_library.url() == Symbols::DartFfi().ptr() &&
1196 library->url() != Symbols::DartCore().ptr() &&
1197 library->url() != Symbols::DartInternal().ptr() &&
1198 library->url() != Symbols::DartFfi().ptr()) {
1199 H.ReportError(
1200 "import of dart:ffi is not supported in the current Dart runtime");
1201 }
1202 String& prefix = H.DartSymbolPlain(dependency_helper.name_index_);
1203 ns = Namespace::New(target_library, show_names, hide_names, *library);
1204 if ((dependency_helper.flags_ & LibraryDependencyHelper::Export) != 0) {
1205 library->AddExport(ns);
1206 } else {
1207 if (prefix.IsNull() || prefix.Length() == 0) {
1208 library->AddImport(ns);
1209 } else {
1210 library_prefix = library->LookupLocalLibraryPrefix(prefix);
1211 if (!library_prefix.IsNull()) {
1212 library_prefix.AddImport(ns);
1213 } else {
1214 library_prefix = LibraryPrefix::New(
1215 prefix, ns,
1216 (dependency_helper.flags_ & LibraryDependencyHelper::Deferred) !=
1217 0,
1218 *library);
1219 library->AddObject(library_prefix, prefix);
1220 }
1221 }
1222 }
1223
1224 if (FLAG_enable_mirrors && dependency_helper.annotation_count_ > 0) {
1225 ASSERT(annotations_kernel_offset > 0);
1226 library->AddMetadata(ns, annotations_kernel_offset);
1227 }
1228
1229 if (prefix.IsNull()) {
1230 deps.SetAt(dep, ns);
1231 } else {
1232 deps.SetAt(dep, library_prefix);
1233 }
1234 }
1235
1236 library->set_dependencies(deps);
1237}
1238
1239void KernelLoader::LoadPreliminaryClass(ClassHelper* class_helper,
1240 intptr_t type_parameter_count) {
1241 const Class* klass = active_class_.klass;
1242
1243 // Enable access to type_parameters().
1245
1246 // Note: This assumes that ClassHelper is exactly at the position where
1247 // the length of the type parameters have been read, and that the order in
1248 // the binary is as follows: [...], kTypeParameters, kSuperClass, kMixinType,
1249 // kImplementedClasses, [...].
1250
1251 // Set type parameters.
1252 T.LoadAndSetupTypeParameters(&active_class_, Object::null_function(), *klass,
1253 Object::null_function_type(),
1254 type_parameter_count);
1255
1256 ActiveTypeParametersScope scope(&active_class_, nullptr, Z);
1257
1258 T.LoadAndSetupBounds(&active_class_, Object::null_function(), *klass,
1259 Object::null_function_type(), type_parameter_count);
1260
1261 // Set super type. Some classes (e.g., Object) do not have one.
1262 Tag type_tag = helper_.ReadTag(); // read super class type (part 1).
1263 if (type_tag == kSomething) {
1264 AbstractType& super_type =
1265 T.BuildTypeWithoutFinalization(); // read super class type (part 2).
1266 klass->set_super_type(Type::Cast(super_type));
1267 }
1268
1269 class_helper->SetJustRead(ClassHelper::kSuperClass);
1270 class_helper->ReadUntilIncluding(ClassHelper::kMixinType);
1271
1272 // Build implemented interface types
1273 intptr_t interface_count = helper_.ReadListLength();
1274 if (interface_count == 0) {
1275 klass->set_interfaces(Object::empty_array());
1276 } else {
1277 const Array& interfaces =
1278 Array::Handle(Z, Array::New(interface_count, Heap::kOld));
1279 for (intptr_t i = 0; i < interface_count; i++) {
1280 const AbstractType& type =
1281 T.BuildTypeWithoutFinalization(); // read ith type.
1282 interfaces.SetAt(i, type);
1283 }
1284 klass->set_interfaces(interfaces);
1285 }
1286 class_helper->SetJustRead(ClassHelper::kImplementedClasses);
1287
1288 if (class_helper->is_abstract()) {
1289 klass->set_is_abstract();
1290 }
1291 if (class_helper->is_transformed_mixin_application()) {
1292 klass->set_is_transformed_mixin_application();
1293 }
1294 if (class_helper->has_const_constructor()) {
1295 klass->set_is_const();
1296 }
1297 if (class_helper->is_sealed()) {
1298 klass->set_is_sealed();
1299 }
1300 if (class_helper->is_mixin_class()) {
1301 klass->set_is_mixin_class();
1302 }
1303 if (class_helper->is_base()) {
1304 klass->set_is_base_class();
1305 }
1306 if (class_helper->is_interface()) {
1307 klass->set_is_interface_class();
1308 }
1309 if (class_helper->is_final()) {
1310 klass->set_is_final();
1311 }
1312}
1313
1314void KernelLoader::LoadClass(const Library& library,
1315 const Class& toplevel_class,
1316 intptr_t class_end,
1317 Class* out_class) {
1318 intptr_t class_offset = helper_.ReaderOffset();
1319 ClassIndex class_index(program_->binary(), class_offset,
1320 class_end - class_offset);
1321
1322 ClassHelper class_helper(&helper_);
1323 class_helper.ReadUntilIncluding(ClassHelper::kCanonicalName);
1324 *out_class = LookupClass(library, class_helper.canonical_name_);
1325 out_class->set_kernel_offset(class_offset - correction_offset_);
1326
1327 // The class needs to have a script because all the functions in the class
1328 // will inherit it. The predicate Function::IsOptimizable uses the absence of
1329 // a script to detect test functions that should not be optimized.
1330 if (out_class->script() == Script::null()) {
1331 class_helper.ReadUntilIncluding(ClassHelper::kSourceUriIndex);
1332 const Script& script =
1333 Script::Handle(Z, ScriptAt(class_helper.source_uri_index_));
1334 out_class->set_script(script);
1335 }
1336 if (out_class->token_pos() == TokenPosition::kNoSource) {
1337 class_helper.ReadUntilIncluding(ClassHelper::kEndPosition);
1338 out_class->set_token_pos(class_helper.start_position_);
1339 out_class->set_end_token_pos(class_helper.end_position_);
1340 }
1341
1342 class_helper.ReadUntilIncluding(ClassHelper::kFlags);
1343 if (class_helper.is_enum_class()) {
1344 out_class->set_is_enum_class();
1345 }
1346
1347 class_helper.ReadUntilExcluding(ClassHelper::kAnnotations);
1348 intptr_t annotation_count = helper_.ReadListLength();
1349 uint32_t pragma_bits = 0;
1350 ReadVMAnnotations(annotation_count, &pragma_bits);
1351 if (IsolateUnsendablePragma::decode(pragma_bits)) {
1352 out_class->set_is_isolate_unsendable_due_to_pragma(true);
1353 }
1354 if (DeeplyImmutablePragma::decode(pragma_bits)) {
1355 out_class->set_is_deeply_immutable(true);
1356 // Ensure that the pragma implies deeply immutability for VM recognized
1357 // classes.
1358 ASSERT(out_class->id() >= kNumPredefinedCids ||
1359 IsDeeplyImmutableCid(out_class->id()));
1360 }
1361 if (HasPragma::decode(pragma_bits)) {
1362 out_class->set_has_pragma(true);
1363 }
1364 class_helper.SetJustRead(ClassHelper::kAnnotations);
1365 class_helper.ReadUntilExcluding(ClassHelper::kTypeParameters);
1366 intptr_t type_parameter_counts =
1367 helper_.ReadListLength(); // read type_parameters list length.
1368
1369 ActiveClassScope active_class_scope(&active_class_, out_class);
1370 if (!out_class->is_declaration_loaded()) {
1371 LoadPreliminaryClass(&class_helper, type_parameter_counts);
1372 } else {
1373 ASSERT(type_parameter_counts == 0);
1374 class_helper.SetJustRead(ClassHelper::kTypeParameters);
1375 }
1376
1377 if ((FLAG_enable_mirrors || HasPragma::decode(pragma_bits)) &&
1378 annotation_count > 0) {
1379 library.AddMetadata(*out_class, class_offset - correction_offset_);
1380 }
1381
1382 // We do not register expression evaluation classes with the VM:
1383 // The expression evaluation functions should be GC-able as soon as
1384 // they are not reachable anymore and we never look them up by name.
1385 const bool register_class =
1386 library.ptr() != expression_evaluation_library_.ptr();
1387 if (!register_class) {
1388 H.SetExpressionEvaluationClass(*out_class);
1389 }
1390
1391 if (loading_native_wrappers_library_ || !register_class) {
1392 FinishClassLoading(*out_class, library, toplevel_class, class_offset,
1393 class_index, &class_helper);
1394 }
1395
1396 helper_.SetOffset(class_end);
1397}
1398
1399void KernelLoader::FinishClassLoading(const Class& klass,
1400 const Library& library,
1401 const Class& toplevel_class,
1402 intptr_t class_offset,
1403 const ClassIndex& class_index,
1404 ClassHelper* class_helper) {
1405 if (klass.is_loaded()) {
1406 return;
1407 }
1408
1409 TIMELINE_DURATION(Thread::Current(), Isolate, "FinishClassLoading");
1410
1411 ActiveClassScope active_class_scope(&active_class_, &klass);
1412
1413 // If this is a dart:internal.ClassID class ignore field declarations
1414 // contained in the Kernel file and instead inject our own const
1415 // fields.
1416 const bool discard_fields = klass.InjectCIDFields();
1417
1418 fields_.Clear();
1419 functions_.Clear();
1420 if (!discard_fields) {
1421 class_helper->ReadUntilExcluding(ClassHelper::kFields);
1422 int field_count = helper_.ReadListLength(); // read list length.
1423 for (intptr_t i = 0; i < field_count; ++i) {
1424 intptr_t field_offset = helper_.ReaderOffset() - correction_offset_;
1425 ActiveMemberScope active_member(&active_class_, nullptr);
1426 FieldHelper field_helper(&helper_);
1427
1428 field_helper.ReadUntilIncluding(FieldHelper::kSourceUriIndex);
1429 const Object& script_class =
1430 ClassForScriptAt(klass, field_helper.source_uri_index_);
1431
1432 field_helper.ReadUntilExcluding(FieldHelper::kName);
1433 const String& name = helper_.ReadNameAsFieldName();
1434 field_helper.SetJustRead(FieldHelper::kName);
1435
1436 field_helper.ReadUntilExcluding(FieldHelper::kAnnotations);
1437 const intptr_t annotation_count = helper_.ReadListLength();
1438 uint32_t pragma_bits = 0;
1439 ReadVMAnnotations(annotation_count, &pragma_bits);
1440 field_helper.SetJustRead(FieldHelper::kAnnotations);
1441
1442 field_helper.ReadUntilExcluding(FieldHelper::kType);
1443 const AbstractType& type =
1444 T.BuildTypeWithoutFinalization(); // read type.
1445 field_helper.SetJustRead(FieldHelper::kType);
1446
1447 const bool is_reflectable =
1448 field_helper.position_.IsReal() &&
1449 !(library.is_dart_scheme() && library.IsPrivate(name));
1450 // In the VM all const fields are implicitly final whereas in Kernel they
1451 // are not final because they are not explicitly declared that way.
1452 const bool is_final = field_helper.IsConst() || field_helper.IsFinal();
1453 const bool is_late = field_helper.IsLate();
1454 const bool is_extension_member = field_helper.IsExtensionMember();
1455 const bool is_extension_type_member =
1456 field_helper.IsExtensionTypeMember();
1457 Field& field = Field::Handle(
1458 Z, Field::New(name, field_helper.IsStatic(), is_final,
1459 field_helper.IsConst(), is_reflectable, is_late,
1460 script_class, type, field_helper.position_,
1461 field_helper.end_position_));
1462 field.set_kernel_offset(field_offset);
1463 field.set_has_pragma(HasPragma::decode(pragma_bits));
1464 field.set_is_covariant(field_helper.IsCovariant());
1465 field.set_is_generic_covariant_impl(
1466 field_helper.IsGenericCovariantImpl());
1467 field.set_is_extension_member(is_extension_member);
1468 field.set_is_extension_type_member(is_extension_type_member);
1469 ReadInferredType(field, field_offset + library_kernel_offset_);
1470 CheckForInitializer(field);
1471 // Static fields with initializers are implicitly late.
1472 if (field_helper.IsStatic() && field.has_initializer()) {
1473 field.set_is_late(true);
1474 }
1475 field_helper.ReadUntilExcluding(FieldHelper::kInitializer);
1476 intptr_t field_initializer_offset = helper_.ReaderOffset();
1477 field_helper.ReadUntilExcluding(FieldHelper::kEnd);
1478
1479 {
1480 AlternativeReadingScope alt(&helper_.reader_, field_initializer_offset);
1481 static_field_value_ = ReadInitialFieldValue(field, &field_helper);
1482 }
1483 GenerateFieldAccessors(klass, field, &field_helper);
1484 if (field.is_static()) {
1485 IG->RegisterStaticField(field, static_field_value_);
1486 }
1487 if ((FLAG_enable_mirrors || HasPragma::decode(pragma_bits)) &&
1488 annotation_count > 0) {
1489 library.AddMetadata(field, field_offset);
1490 }
1491 fields_.Add(&field);
1492 }
1493 class_helper->SetJustRead(ClassHelper::kFields);
1494
1495 if (klass.is_enum_class()) {
1496 // Add static field 'const _deleted_enum_sentinel'.
1497 // This field does not need to be of type E.
1498 Field& deleted_enum_sentinel = Field::ZoneHandle(Z);
1499 deleted_enum_sentinel =
1500 Field::New(Symbols::_DeletedEnumSentinel(),
1501 /* is_static = */ true,
1502 /* is_final = */ true,
1503 /* is_const = */ true,
1504 /* is_reflectable = */ false,
1505 /* is_late = */ false, klass, Object::dynamic_type(),
1506 TokenPosition::kNoSource, TokenPosition::kNoSource);
1507 IG->RegisterStaticField(deleted_enum_sentinel, Object::Handle());
1508 fields_.Add(&deleted_enum_sentinel);
1509 }
1510
1511 // TODO(https://dartbug.com/44454): Make VM recognize the Struct class.
1512 //
1513 // The FfiTrampolines currently allocate subtypes of structs and store
1514 // TypedData in them, without using guards because they are force
1515 // optimized. We immediately set the guarded_cid_ to kDynamicCid, which
1516 // is effectively the same as calling this method first with Pointer and
1517 // subsequently with TypedData with field guards.
1518 if (klass.UserVisibleName() == Symbols::Compound().ptr() &&
1519 Library::Handle(Z, klass.library()).url() == Symbols::DartFfi().ptr()) {
1520 ASSERT_EQUAL(fields_.length(), 2);
1521 ASSERT(String::Handle(Z, fields_[0]->name())
1522 .StartsWith(Symbols::_typedDataBase()));
1523 fields_[0]->set_guarded_cid(kDynamicCid);
1524 fields_[0]->set_is_nullable(true);
1525 }
1526
1527 // Check that subclasses of AbiSpecificInteger have a mapping for the
1528 // current ABI.
1529 //
1530 // TODO(https://github.com/dart-lang/language/issues/1889): If we make
1531 // kernel know about the target platform, we can move this check to the
1532 // frontend.
1533 const auto& super_class = Class::Handle(Z, klass.SuperClass());
1534 if (!super_class.IsNull() &&
1535 super_class.UserVisibleName() == Symbols::AbiSpecificInteger().ptr() &&
1536 Library::Handle(Z, super_class.library()).url() ==
1537 Symbols::DartFfi().ptr()) {
1538 const char* error = nullptr;
1540 Z, AbstractType::Handle(Z, klass.DeclarationType()), &error);
1541 if (error != nullptr) {
1542 H.ReportError("%s", error);
1543 }
1544 }
1545
1546 // Due to ReadVMAnnotations(), the klass may have been loaded at this point
1547 // (loading the class while evaluating annotations).
1548 if (klass.is_loaded()) {
1549 return;
1550 }
1551
1552 klass.SetFields(Array::Handle(Z, MakeFieldsArray()));
1553 }
1554
1555 class_helper->ReadUntilExcluding(ClassHelper::kConstructors);
1556 int constructor_count = helper_.ReadListLength(); // read list length.
1557 for (intptr_t i = 0; i < constructor_count; ++i) {
1558 intptr_t constructor_offset = helper_.ReaderOffset() - correction_offset_;
1559 ActiveMemberScope active_member_scope(&active_class_, nullptr);
1560 ConstructorHelper constructor_helper(&helper_);
1561 constructor_helper.ReadUntilExcluding(ConstructorHelper::kAnnotations);
1562 const intptr_t annotation_count = helper_.ReadListLength();
1563 uint32_t pragma_bits = 0;
1564 ReadVMAnnotations(annotation_count, &pragma_bits);
1565 constructor_helper.SetJustRead(ConstructorHelper::kAnnotations);
1566 constructor_helper.ReadUntilExcluding(ConstructorHelper::kFunction);
1567
1568 const String& name =
1569 H.DartConstructorName(constructor_helper.canonical_name_);
1570
1571 // We can have synthetic constructors, which will not have a source uri
1572 // attached to them (which means the index into the source uri table is 0,
1573 // see `package:kernel/binary/ast_to_binary::writeUriReference`.
1574 const Object* owner = &klass;
1575 const intptr_t source_uri_index = constructor_helper.source_uri_index_;
1576 if (source_uri_index != 0) {
1577 owner = &ClassForScriptAt(klass, source_uri_index);
1578 }
1579
1580 FunctionType& signature = FunctionType::Handle(Z, FunctionType::New());
1581 const Function& function = Function::ZoneHandle(
1582 Z, Function::New(signature, name, UntaggedFunction::kConstructor,
1583 false, // is_static
1584 constructor_helper.IsConst(),
1585 false, // is_abstract
1586 constructor_helper.IsExternal(),
1587 false, // is_native
1588 *owner, constructor_helper.start_position_));
1589 function.set_end_token_pos(constructor_helper.end_position_);
1590 function.set_kernel_offset(constructor_offset);
1591 signature.set_result_type(T.ReceiverType(klass));
1592 function.set_has_pragma(HasPragma::decode(pragma_bits));
1593 function.set_is_visible(!InvisibleFunctionPragma::decode(pragma_bits));
1594
1595 FunctionNodeHelper function_node_helper(&helper_);
1596 function_node_helper.ReadUntilExcluding(
1598 T.SetupFunctionParameters(klass, function,
1599 true, // is_method
1600 false, // is_closure
1601 &function_node_helper);
1602 T.SetupUnboxingInfoMetadata(function, library_kernel_offset_);
1603
1604 if (library.is_dart_scheme() &&
1605 H.IsPrivate(constructor_helper.canonical_name_)) {
1606 function.set_is_reflectable(false);
1607 }
1608
1609 if (constructor_helper.IsSynthetic()) {
1610 function.set_is_debuggable(false);
1611 }
1612
1613 function_node_helper.ReadUntilExcluding(FunctionNodeHelper::kEnd);
1614 constructor_helper.SetJustRead(ConstructorHelper::kFunction);
1615 constructor_helper.ReadUntilExcluding(ConstructorHelper::kEnd);
1616
1617 if (klass.is_finalized()) {
1618 // The owner class has already been marked as finalized (e.g. class
1619 // 'NativeFieldWrapperClass1'), so the signature of this added constructor
1620 // must be finalized here, since finalization of member types will not be
1621 // called anymore.
1622 signature ^= ClassFinalizer::FinalizeType(signature);
1623 function.SetSignature(signature);
1624 }
1625 functions_.Add(&function);
1626
1627 if ((FLAG_enable_mirrors || HasPragma::decode(pragma_bits)) &&
1628 annotation_count > 0) {
1629 library.AddMetadata(function, constructor_offset);
1630 }
1631 }
1632
1633 // Due to ReadVMAnnotations(), the klass may have been loaded at this point
1634 // (loading the class while evaluating annotations).
1635 if (klass.is_loaded()) {
1636 return;
1637 }
1638
1639 // Everything up til the procedures are skipped implicitly, and class_helper
1640 // is no longer used.
1641
1642 intptr_t procedure_count = class_index.procedure_count();
1643 // Procedure offsets within a class index are whole program offsets and not
1644 // relative to the library of the class. Hence, we need a correction to get
1645 // the currect procedure offset within the current data.
1646 intptr_t correction = correction_offset_ - library_kernel_offset_;
1647 intptr_t next_procedure_offset = class_index.ProcedureOffset(0) + correction;
1648 for (intptr_t i = 0; i < procedure_count; ++i) {
1649 helper_.SetOffset(next_procedure_offset);
1650 next_procedure_offset = class_index.ProcedureOffset(i + 1) + correction;
1651 LoadProcedure(library, klass, true, next_procedure_offset);
1652 // LoadProcedure calls Library::GetMetadata which invokes Dart code
1653 // which may recursively trigger class finalization and FinishClassLoading.
1654 // In such case, return immediately and avoid overwriting already finalized
1655 // functions with freshly loaded and not yet finalized.
1656 if (klass.is_loaded()) {
1657 return;
1658 }
1659 }
1660
1661 klass.SetFunctions(Array::Handle(MakeFunctionsArray()));
1662
1663 ASSERT(!klass.is_loaded());
1664 klass.set_is_loaded(true);
1665}
1666
1668 ASSERT(klass.IsTopLevel() || (klass.kernel_offset() > 0));
1669
1670 Zone* zone = Thread::Current()->zone();
1671 const Library& library = Library::Handle(zone, klass.library());
1672 const Class& toplevel_class = Class::Handle(zone, library.toplevel_class());
1673 const auto& library_kernel_data =
1674 TypedDataView::Handle(zone, library.KernelLibrary());
1675 ASSERT(!library_kernel_data.IsNull());
1676
1677 const auto& kernel_info =
1679 const intptr_t library_kernel_offset =
1680 kernel_info.KernelLibraryStartOffset(library.kernel_library_index());
1681
1682 KernelLoader kernel_loader(kernel_info, library_kernel_data,
1683 library_kernel_offset);
1684
1685 LibraryIndex library_index(library_kernel_data);
1686
1687 if (klass.IsTopLevel()) {
1688 ASSERT(klass.ptr() == toplevel_class.ptr());
1689 kernel_loader.FinishTopLevelClassLoading(klass, library, library_index);
1690 return;
1691 }
1692
1693 const intptr_t class_offset = klass.kernel_offset();
1694 ClassIndex class_index(
1695 library_kernel_data, class_offset,
1696 // Class offsets in library index are whole program offsets.
1697 // Hence, we need to add |library_kernel_offset| to
1698 // |class_offset| to lookup the entry for the class in the library
1699 // index.
1700 library_index.SizeOfClassAtOffset(class_offset + library_kernel_offset));
1701
1702 kernel_loader.helper_.SetOffset(class_offset);
1703 ClassHelper class_helper(&kernel_loader.helper_);
1704
1705 kernel_loader.FinishClassLoading(klass, library, toplevel_class, class_offset,
1706 class_index, &class_helper);
1707}
1708
1709// Read annotations on a procedure or a class to identify potential VM-specific
1710// directives.
1711//
1712// Output parameters:
1713//
1714// `native_name`: the native name if @pragma('vm:external-name)` was found.
1715//
1716// `pragma_bits`: any recognized pragma that was found
1717//
1718void KernelLoader::ReadVMAnnotations(intptr_t annotation_count,
1719 uint32_t* pragma_bits,
1720 String* native_name) {
1721 *pragma_bits = 0;
1722 if (annotation_count == 0) {
1723 return;
1724 }
1725
1726 for (intptr_t i = 0; i < annotation_count; ++i) {
1727 const intptr_t tag = helper_.PeekTag();
1728 if (tag == kConstantExpression || tag == kFileUriConstantExpression) {
1729 helper_.ReadByte(); // Skip the tag.
1730 helper_.ReadPosition(); // Skip fileOffset.
1731 if (tag == kFileUriConstantExpression) {
1732 helper_.ReadUInt(); // Skip uri.
1733 }
1734 helper_.SkipDartType(); // Skip type.
1735 const intptr_t index_in_constant_table = helper_.ReadUInt();
1736
1737 // Prepare lazy constant reading.
1738 ConstantReader constant_reader(&helper_, &active_class_);
1739
1740 intptr_t name_index = -1;
1741 intptr_t options_index = -1;
1742 if (constant_reader.IsPragmaInstanceConstant(
1743 index_in_constant_table, &name_index, &options_index)) {
1744 *pragma_bits = HasPragma::update(true, *pragma_bits);
1745
1746 if (constant_reader.IsStringConstant(name_index, "vm:invisible")) {
1747 *pragma_bits = InvisibleFunctionPragma::update(true, *pragma_bits);
1748 }
1749 if (constant_reader.IsStringConstant(name_index, "vm:external-name")) {
1750 *pragma_bits = ExternalNamePragma::update(true, *pragma_bits);
1751 constant_reader.GetStringConstant(options_index, native_name);
1752 }
1753 if (constant_reader.IsStringConstant(name_index,
1754 "vm:isolate-unsendable")) {
1755 *pragma_bits = IsolateUnsendablePragma::update(true, *pragma_bits);
1756 }
1757 if (constant_reader.IsStringConstant(name_index,
1758 "vm:deeply-immutable")) {
1759 *pragma_bits = DeeplyImmutablePragma::update(true, *pragma_bits);
1760 }
1761 if (constant_reader.IsStringConstant(name_index, "vm:ffi:native")) {
1762 *pragma_bits = FfiNativePragma::update(true, *pragma_bits);
1763 }
1764 }
1765 } else {
1766 helper_.SkipExpression();
1767 continue;
1768 }
1769 }
1770}
1771
1772void KernelLoader::LoadProcedure(const Library& library,
1773 const Class& owner,
1774 bool in_class,
1775 intptr_t procedure_end) {
1776 intptr_t procedure_offset = helper_.ReaderOffset() - correction_offset_;
1777 ProcedureHelper procedure_helper(&helper_);
1778
1779 procedure_helper.ReadUntilExcluding(ProcedureHelper::kAnnotations);
1780 // CFE adds 'member signature' abstract functions to a legacy class deriving
1781 // or implementing an opted-in interface. The signature of these functions is
1782 // legacy erased and used as the target of interface calls. They are used for
1783 // static reasoning about the program by CFE, but not really needed by the VM.
1784 // In certain situations (e.g. issue 162073826), a large number of these
1785 // additional functions can cause strain on the VM. They are therefore skipped
1786 // in jit mode and their associated origin function is used instead as
1787 // interface call target.
1788 if (!FLAG_precompiled_mode && procedure_helper.IsMemberSignature()) {
1789 helper_.SetOffset(procedure_end);
1790 return;
1791 }
1792 const String& name = H.DartProcedureName(procedure_helper.canonical_name_);
1793 bool is_method = in_class && !procedure_helper.IsStatic();
1794 bool is_abstract = procedure_helper.IsAbstract();
1795 bool is_external = procedure_helper.IsExternal();
1796 bool is_extension_member = procedure_helper.IsExtensionMember();
1797 bool is_extension_type_member = procedure_helper.IsExtensionTypeMember();
1798 bool is_synthetic = procedure_helper.IsSynthetic();
1799 String& native_name = String::Handle(Z);
1800 uint32_t pragma_bits = 0;
1801 const intptr_t annotation_count = helper_.ReadListLength();
1802 ReadVMAnnotations(annotation_count, &pragma_bits, &native_name);
1803 is_external = is_external && native_name.IsNull();
1804 procedure_helper.SetJustRead(ProcedureHelper::kAnnotations);
1805 const Object& script_class =
1806 ClassForScriptAt(owner, procedure_helper.source_uri_index_);
1807 UntaggedFunction::Kind kind = GetFunctionType(procedure_helper.kind_);
1808
1809 // We do not register expression evaluation libraries with the VM:
1810 // The expression evaluation functions should be GC-able as soon as
1811 // they are not reachable anymore and we never look them up by name.
1812 const bool register_function = !name.Equals(Symbols::DebugProcedureName());
1813
1814 const bool is_ffi_native = FfiNativePragma::decode(pragma_bits);
1815 const FunctionType& signature = FunctionType::Handle(Z, FunctionType::New());
1816 const Function& function = Function::ZoneHandle(
1817 Z, Function::New(signature, name, kind,
1818 !is_method, // is_static
1819 false, // is_const
1820 is_abstract, is_external,
1821 !native_name.IsNull() || is_ffi_native, // is_native
1822 script_class, procedure_helper.start_position_));
1823 function.set_has_pragma(HasPragma::decode(pragma_bits));
1824 function.set_end_token_pos(procedure_helper.end_position_);
1825 function.set_is_synthetic(procedure_helper.IsNoSuchMethodForwarder() ||
1826 procedure_helper.IsMemberSignature() ||
1827 is_synthetic);
1828 function.set_is_visible(!InvisibleFunctionPragma::decode(pragma_bits));
1829 if (register_function) {
1830 functions_.Add(&function);
1831 } else {
1832 H.SetExpressionEvaluationFunction(function);
1833 }
1834 function.set_kernel_offset(procedure_offset);
1835 function.set_is_extension_member(is_extension_member);
1836 function.set_is_extension_type_member(is_extension_type_member);
1837 if ((library.is_dart_scheme() &&
1838 H.IsPrivate(procedure_helper.canonical_name_)) ||
1839 (function.is_static() && (library.ptr() == Library::InternalLibrary()))) {
1840 function.set_is_reflectable(false);
1841 }
1842 if (procedure_helper.IsMemberSignature()) {
1843 function.set_is_reflectable(false);
1844 }
1845
1846 ActiveMemberScope active_member(&active_class_, &function);
1847
1848 procedure_helper.ReadUntilExcluding(ProcedureHelper::kFunction);
1849
1850 FunctionNodeHelper function_node_helper(&helper_);
1851 function_node_helper.ReadUntilIncluding(FunctionNodeHelper::kDartAsyncMarker);
1852 if (function_node_helper.async_marker_ == FunctionNodeHelper::kAsync) {
1853 function.set_modifier(UntaggedFunction::kAsync);
1854 function.set_is_inlinable(false);
1855 ASSERT(function.IsAsyncFunction());
1856 } else if (function_node_helper.async_marker_ ==
1859 function.set_is_inlinable(false);
1860 ASSERT(function.IsAsyncGenerator());
1861 } else if (function_node_helper.async_marker_ ==
1864 function.set_is_inlinable(false);
1865 ASSERT(function.IsSyncGenerator());
1866 } else {
1867 ASSERT(function_node_helper.async_marker_ == FunctionNodeHelper::kSync);
1868 ASSERT(!function.IsAsyncFunction());
1869 ASSERT(!function.IsAsyncGenerator());
1870 ASSERT(!function.IsSyncGenerator());
1871 }
1872
1873 if (!native_name.IsNull()) {
1874 function.set_native_name(native_name);
1875 }
1876
1877 function_node_helper.ReadUntilExcluding(FunctionNodeHelper::kTypeParameters);
1878 T.SetupFunctionParameters(owner, function, is_method,
1879 false, // is_closure
1880 &function_node_helper);
1881 T.SetupUnboxingInfoMetadata(function, library_kernel_offset_);
1882
1883 function_node_helper.ReadUntilExcluding(
1885 function.set_is_redirecting_factory(helper_.ReadTag() == kSomething);
1886
1887 // Everything else is skipped implicitly, and procedure_helper and
1888 // function_node_helper are no longer used.
1889 helper_.SetOffset(procedure_end);
1890
1891 if (annotation_count > 0) {
1892 library.AddMetadata(function, procedure_offset);
1893 }
1894}
1895
1896const Object& KernelLoader::ClassForScriptAt(const Class& klass,
1897 intptr_t source_uri_index) {
1898 const Script& correct_script = Script::Handle(Z, ScriptAt(source_uri_index));
1899 if (klass.script() != correct_script.ptr()) {
1900 // Lazily create the [patch_classes_] array in case we need it.
1901 if (patch_classes_.IsNull()) {
1902 const Array& scripts = Array::Handle(Z, kernel_program_info_.scripts());
1903 ASSERT(!scripts.IsNull());
1904 patch_classes_ = Array::New(scripts.Length(), Heap::kOld);
1905 }
1906
1907 // Use cache for patch classes. This works best for in-order usages.
1908 PatchClass& patch_class = PatchClass::Handle(Z);
1909 patch_class ^= patch_classes_.At(source_uri_index);
1910 if (patch_class.IsNull() || patch_class.wrapped_class() != klass.ptr()) {
1911 const auto& lib = Library::Handle(klass.library());
1912 patch_class =
1913 PatchClass::New(klass, kernel_program_info_, correct_script);
1914 patch_class.set_kernel_library_index(lib.kernel_library_index());
1915 patch_classes_.SetAt(source_uri_index, patch_class);
1916 }
1917 return patch_class;
1918 }
1919 return klass;
1920}
1921
1922ScriptPtr KernelLoader::LoadScriptAt(intptr_t index,
1923 UriToSourceTable* uri_to_source_table) {
1924 const String& uri_string = helper_.SourceTableUriFor(index);
1925 const String& import_uri_string = helper_.SourceTableImportUriFor(index);
1926 auto& constant_coverage = TypedDataView::Handle(Z);
1927 NOT_IN_PRODUCT(constant_coverage = helper_.GetConstantCoverageFor(index));
1928
1929 String& sources = String::Handle(Z);
1930 TypedData& line_starts = TypedData::Handle(Z);
1931
1932 if (uri_to_source_table != nullptr) {
1933 UriToSourceTableEntry wrapper;
1934 wrapper.uri = &uri_string;
1935 UriToSourceTableEntry* pair = uri_to_source_table->LookupValue(&wrapper);
1936 if (pair != nullptr) {
1937 sources = pair->sources->ptr();
1938 line_starts = pair->line_starts->ptr();
1939 }
1940 }
1941
1942 if (sources.IsNull() || line_starts.IsNull()) {
1943 const String& script_source = helper_.GetSourceFor(index);
1944 line_starts = helper_.GetLineStartsFor(index);
1945
1946 if (script_source.ptr() == Symbols::Empty().ptr() &&
1947 line_starts.Length() == 0 && uri_string.Length() > 0) {
1948 // Entry included only to provide URI - actual source should already exist
1949 // in the VM, so try to find it.
1950 Library& lib = Library::Handle(Z);
1951 Script& script = Script::Handle(Z);
1952 const GrowableObjectArray& libs =
1953 GrowableObjectArray::Handle(IG->object_store()->libraries());
1954 for (intptr_t i = 0; i < libs.Length(); i++) {
1955 lib ^= libs.At(i);
1956 script = lib.LookupScript(uri_string, /* useResolvedUri = */ true);
1957 if (!script.IsNull()) {
1958 sources = script.Source();
1959 line_starts = script.line_starts();
1960 break;
1961 }
1962 }
1963 } else {
1964 sources = script_source.ptr();
1965 }
1966 }
1967
1968 const Script& script =
1969 Script::Handle(Z, Script::New(import_uri_string, uri_string, sources));
1970 script.InitializeFromKernel(kernel_program_info_, index, line_starts,
1971 constant_coverage);
1972 return script.ptr();
1973}
1974
1975ObjectPtr KernelLoader::ReadInitialFieldValue(const Field& field,
1976 FieldHelper* field_helper) {
1977 const Tag tag = helper_.PeekTag();
1978 const bool has_initializer = (tag == kSomething);
1979
1980 if (has_initializer) {
1981 SimpleExpressionConverter converter(&H, &helper_);
1982 const bool has_simple_initializer =
1983 converter.IsSimple(helper_.ReaderOffset() + 1); // ignore the tag.
1984 if (has_simple_initializer) {
1985 if (field_helper->IsStatic()) {
1986 return converter.SimpleValue().ptr();
1987 } else {
1988 field.RecordStore(converter.SimpleValue());
1989 }
1990 }
1991 }
1992
1993 if (field_helper->IsStatic()) {
1994 if (!has_initializer && !field_helper->IsLate()) {
1995 // Static fields without an initializer are implicitly initialized to
1996 // null.
1997 return Instance::null();
1998 }
1999 }
2000 ASSERT(field.NeedsGetter());
2001
2002 // If static, we do need a getter that evaluates the initializer if necessary.
2003 return field_helper->IsStatic() ? Object::sentinel().ptr() : Object::null();
2004}
2005
2006void KernelLoader::GenerateFieldAccessors(const Class& klass,
2007 const Field& field,
2008 FieldHelper* field_helper) {
2009 const bool needs_getter = field.NeedsGetter();
2010 const bool needs_setter = field.NeedsSetter();
2011
2012 if (!needs_getter && !needs_setter) {
2013 return;
2014 }
2015
2016 const Object& script_class =
2017 ClassForScriptAt(klass, field_helper->source_uri_index_);
2018 const AbstractType& field_type = AbstractType::Handle(Z, field.type());
2019
2020 if (needs_getter) {
2021 const String& getter_name =
2022 H.DartGetterName(field_helper->canonical_name_getter_);
2023 const FunctionType& signature =
2025 Function& getter = Function::ZoneHandle(
2026 Z,
2028 signature, getter_name,
2029 field_helper->IsStatic() ? UntaggedFunction::kImplicitStaticGetter
2030 : UntaggedFunction::kImplicitGetter,
2031 field_helper->IsStatic(),
2032 // The functions created by the parser have is_const for static
2033 // fields that are const (not just final) and they have is_const
2034 // for non-static fields that are final.
2035 field_helper->IsStatic() ? field_helper->IsConst()
2036 : field_helper->IsFinal(),
2037 false, // is_abstract
2038 false, // is_external
2039 false, // is_native
2040 script_class, field_helper->position_));
2041 functions_.Add(&getter);
2042 getter.set_end_token_pos(field_helper->end_position_);
2043 getter.set_kernel_offset(field.kernel_offset());
2044 signature.set_result_type(field_type);
2045 getter.set_is_debuggable(false);
2046 getter.set_accessor_field(field);
2047 getter.set_is_extension_member(field.is_extension_member());
2048 getter.set_is_extension_type_member(field.is_extension_type_member());
2049 H.SetupFieldAccessorFunction(klass, getter, field_type);
2050 T.SetupUnboxingInfoMetadataForFieldAccessors(getter,
2051 library_kernel_offset_);
2052 }
2053
2054 if (needs_setter) {
2055 // Only static fields can be const.
2056 ASSERT(!field_helper->IsConst());
2057 const String& setter_name =
2058 H.DartSetterName(field_helper->canonical_name_setter_);
2059 const FunctionType& signature =
2061 Function& setter = Function::ZoneHandle(
2062 Z,
2063 Function::New(signature, setter_name, UntaggedFunction::kImplicitSetter,
2064 field_helper->IsStatic(),
2065 false, // is_const
2066 false, // is_abstract
2067 false, // is_external
2068 false, // is_native
2069 script_class, field_helper->position_));
2070 functions_.Add(&setter);
2071 setter.set_end_token_pos(field_helper->end_position_);
2072 setter.set_kernel_offset(field.kernel_offset());
2073 signature.set_result_type(Object::void_type());
2074 setter.set_is_debuggable(false);
2075 setter.set_accessor_field(field);
2076 setter.set_is_extension_member(field.is_extension_member());
2077 setter.set_is_extension_type_member(field.is_extension_type_member());
2078 H.SetupFieldAccessorFunction(klass, setter, field_type);
2079 T.SetupUnboxingInfoMetadataForFieldAccessors(setter,
2080 library_kernel_offset_);
2081 }
2082}
2083
2084LibraryPtr KernelLoader::LookupLibraryOrNull(NameIndex library) {
2085 LibraryPtr result;
2086 name_index_handle_ = Smi::New(library);
2087 {
2088 result = kernel_program_info_.LookupLibrary(thread_, name_index_handle_);
2089 NoSafepointScope no_safepoint_scope(thread_);
2090 if (result != Library::null()) {
2091 return result;
2092 }
2093 }
2094 const String& url = H.DartString(H.CanonicalNameString(library));
2095 {
2096 result = Library::LookupLibrary(thread_, url);
2097 NoSafepointScope no_safepoint_scope(thread_);
2098 if (result == Library::null()) {
2099 return result;
2100 }
2101 }
2102 const Library& handle = Library::Handle(Z, result);
2103 name_index_handle_ = Smi::New(library);
2104 return kernel_program_info_.InsertLibrary(thread_, name_index_handle_,
2105 handle);
2106}
2107
2108LibraryPtr KernelLoader::LookupLibrary(NameIndex library) {
2109 name_index_handle_ = Smi::New(library);
2110 {
2111 LibraryPtr result =
2112 kernel_program_info_.LookupLibrary(thread_, name_index_handle_);
2113 NoSafepointScope no_safepoint_scope(thread_);
2114 if (result != Library::null()) {
2115 return result;
2116 }
2117 }
2118
2119 Library& handle = Library::Handle(Z);
2120 const String& url = H.DartSymbolPlain(H.CanonicalNameString(library));
2121 // We do not register expression evaluation libraries with the VM:
2122 // The expression evaluation functions should be GC-able as soon as
2123 // they are not reachable anymore and we never look them up by name.
2124 if (url.Equals(Symbols::EvalSourceUri())) {
2125 if (expression_evaluation_library_.IsNull()) {
2126 handle = Library::New(url);
2127 expression_evaluation_library_ = handle.ptr();
2128 }
2129 return expression_evaluation_library_.ptr();
2130 }
2131 handle = Library::LookupLibrary(thread_, url);
2132 if (handle.IsNull()) {
2133 handle = Library::New(url);
2134 handle.Register(thread_);
2135 }
2136 ASSERT(!handle.IsNull());
2137 name_index_handle_ = Smi::New(library);
2138 return kernel_program_info_.InsertLibrary(thread_, name_index_handle_,
2139 handle);
2140}
2141
2142LibraryPtr KernelLoader::LookupLibraryFromClass(NameIndex klass) {
2143 return LookupLibrary(H.CanonicalNameParent(klass));
2144}
2145
2146ClassPtr KernelLoader::LookupClass(const Library& library, NameIndex klass) {
2147 name_index_handle_ = Smi::New(klass);
2148 {
2149 ClassPtr raw_class =
2150 kernel_program_info_.LookupClass(thread_, name_index_handle_);
2151 NoSafepointScope no_safepoint_scope(thread_);
2152 if (raw_class != Class::null()) {
2153 return raw_class;
2154 }
2155 }
2156
2157 ASSERT(!library.IsNull());
2158 const String& name = H.DartClassName(klass);
2159 Class& handle = Class::Handle(Z, library.LookupClass(name));
2160 bool register_class = true;
2161 if (handle.IsNull()) {
2162 // We do not register expression evaluation classes with the VM:
2163 // The expression evaluation functions should be GC-able as soon as
2164 // they are not reachable anymore and we never look them up by name.
2165 register_class = library.ptr() != expression_evaluation_library_.ptr();
2166
2167 handle = Class::New(library, name, Script::Handle(Z),
2168 TokenPosition::kNoSource, register_class);
2169 if (register_class) {
2170 library.AddClass(handle);
2171 }
2172 }
2173 ASSERT(!handle.IsNull());
2174 if (register_class) {
2175 name_index_handle_ = Smi::New(klass);
2176 kernel_program_info_.InsertClass(thread_, name_index_handle_, handle);
2177 }
2178 return handle.ptr();
2179}
2180
2181UntaggedFunction::Kind KernelLoader::GetFunctionType(
2182 ProcedureHelper::Kind procedure_kind) {
2183 intptr_t lookuptable[] = {
2184 UntaggedFunction::kRegularFunction, // Procedure::kMethod
2185 UntaggedFunction::kGetterFunction, // Procedure::kGetter
2186 UntaggedFunction::kSetterFunction, // Procedure::kSetter
2187 UntaggedFunction::kRegularFunction, // Procedure::kOperator
2188 UntaggedFunction::kConstructor, // Procedure::kFactory
2189 };
2190 intptr_t kind = static_cast<int>(procedure_kind);
2191 ASSERT(0 <= kind && kind <= ProcedureHelper::kFactory);
2192 return static_cast<UntaggedFunction::Kind>(lookuptable[kind]);
2193}
2194
2195FunctionPtr KernelLoader::LoadClosureFunction(const Function& parent_function,
2196 const Object& closure_owner) {
2197 const intptr_t func_decl_offset = helper_.ReaderOffset();
2198 const Tag tag = helper_.ReadTag();
2199 ASSERT((tag == kFunctionExpression) || (tag == kFunctionDeclaration));
2200 const bool is_declaration = (tag == kFunctionDeclaration);
2201
2202 TokenPosition position = helper_.ReadPosition(); // read position.
2203
2204 uint32_t pragma_bits = 0;
2205 intptr_t annotation_count = 0;
2206 const String* name;
2207 if (is_declaration) {
2208 // Read variable declaration.
2209 VariableDeclarationHelper variable_helper(&helper_);
2210
2211 variable_helper.ReadUntilExcluding(VariableDeclarationHelper::kAnnotations);
2212 const intptr_t annotation_count = helper_.ReadListLength();
2213 ReadVMAnnotations(annotation_count, &pragma_bits);
2214 variable_helper.SetJustRead(VariableDeclarationHelper::kAnnotations);
2215
2216 variable_helper.ReadUntilExcluding(VariableDeclarationHelper::kEnd);
2217 name = &H.DartSymbolObfuscate(variable_helper.name_index_);
2218 } else {
2219 name = &Symbols::AnonymousClosure();
2220 }
2221
2222 const intptr_t func_node_offset = helper_.ReaderOffset();
2223
2224 FunctionNodeHelper function_node_helper(&helper_);
2225 function_node_helper.ReadUntilExcluding(FunctionNodeHelper::kTypeParameters);
2226
2227 Function& function = Function::Handle(Z);
2228 if (!closure_owner.IsNull()) {
2230 UntaggedFunction::kClosureFunction, *name, parent_function,
2231 parent_function.is_static(), position, closure_owner);
2232 } else {
2233 function = Function::NewClosureFunction(*name, parent_function, position);
2234 }
2235
2236 const bool has_pragma = HasPragma::decode(pragma_bits);
2237 function.set_has_pragma(has_pragma);
2238 function.set_is_visible(!InvisibleFunctionPragma::decode(pragma_bits));
2239 if ((FLAG_enable_mirrors && (annotation_count > 0)) || has_pragma) {
2240 const auto& lib =
2241 Library::Handle(Z, Class::Handle(Z, function.Owner()).library());
2242 lib.AddMetadata(function, func_decl_offset);
2243 }
2244
2245 if (function_node_helper.async_marker_ == FunctionNodeHelper::kAsync) {
2246 function.set_modifier(UntaggedFunction::kAsync);
2247 function.set_is_inlinable(false);
2248 ASSERT(function.IsAsyncFunction());
2249 } else if (function_node_helper.async_marker_ ==
2252 function.set_is_inlinable(false);
2253 ASSERT(function.IsAsyncGenerator());
2254 } else if (function_node_helper.async_marker_ ==
2257 function.set_is_inlinable(false);
2258 ASSERT(function.IsSyncGenerator());
2259 } else {
2260 ASSERT(function_node_helper.async_marker_ == FunctionNodeHelper::kSync);
2261 ASSERT(!function.IsAsyncFunction());
2262 ASSERT(!function.IsAsyncGenerator());
2263 ASSERT(!function.IsSyncGenerator());
2264 }
2265
2266 // If the start token position is synthetic, the end token position
2267 // should be as well.
2268 function.set_end_token_pos(
2269 position.IsReal() ? function_node_helper.end_position_ : position);
2270
2271 function.set_kernel_offset(func_node_offset);
2272 T.SetupFunctionParameters(Class::Handle(Z), function,
2273 false, // is_method
2274 true, // is_closure
2275 &function_node_helper);
2276 // type_translator->SetupUnboxingInfoMetadata is not called here at the
2277 // moment because closures do not have unboxed parameters and return
2278 // value
2279
2280 // Finalize function type.
2281 FunctionType& signature = FunctionType::Handle(Z, function.signature());
2282 signature ^= ClassFinalizer::FinalizeType(signature);
2283 function.SetSignature(signature);
2284
2286
2287 return function.ptr();
2288}
2289
2291 intptr_t func_decl_offset,
2292 const Function& member_function,
2293 const Function& parent_function,
2294 const Object& closure_owner) {
2295 Zone* zone = thread->zone();
2297 intptr_t func_node_offset = -1;
2298
2299 const auto& kernel_info =
2300 KernelProgramInfo::Handle(zone, member_function.KernelProgramInfo());
2301 const auto& library_kernel_data =
2302 TypedDataView::Handle(zone, member_function.KernelLibrary());
2303 ASSERT(!library_kernel_data.IsNull());
2304 const intptr_t library_kernel_offset = member_function.KernelLibraryOffset();
2305
2306 KernelLoader kernel_loader(kernel_info, library_kernel_data,
2307 library_kernel_offset);
2308 {
2309 // TODO(alexmarkov): Use func_decl_offset as a key in ClosureFunctionsCache
2310 // instead of func_node_offset and avoid this reading.
2311 kernel_loader.helper_.SetOffset(func_decl_offset);
2312 kernel_loader.helper_.ReadUntilFunctionNode();
2313 func_node_offset = kernel_loader.helper_.ReaderOffset();
2314
2315 {
2316 SafepointReadRwLocker ml(thread, thread->isolate_group()->program_lock());
2318 member_function, func_node_offset);
2319 if (!function.IsNull()) {
2320 return function.ptr();
2321 }
2322 }
2323 }
2324
2325 SafepointWriteRwLocker ml(thread, thread->isolate_group()->program_lock());
2327 member_function, func_node_offset);
2328 if (function.IsNull()) {
2329 ActiveClassScope active_class_scope(
2330 &kernel_loader.active_class_,
2331 &Class::Handle(zone, member_function.Owner()));
2332 ActiveMemberScope active_member(&kernel_loader.active_class_,
2333 &member_function);
2334 ActiveTypeParametersScope active_type_params(
2335 &kernel_loader.active_class_, member_function,
2336 &FunctionType::Handle(zone, parent_function.signature()), zone);
2337 kernel_loader.helper_.SetOffset(func_decl_offset);
2338 function =
2339 kernel_loader.LoadClosureFunction(parent_function, closure_owner);
2340 }
2341 return function.ptr();
2342}
2343
2345 Zone* zone,
2346 const Field& field) {
2348
2349 String& init_name = String::Handle(zone, field.name());
2350 init_name = Symbols::FromConcat(thread, Symbols::InitPrefix(), init_name);
2351
2352 // Static field initializers are not added as members of their owning class,
2353 // so they must be preemptively given a patch class to avoid the meaning of
2354 // their kernel/token position changing during a reload. Compare
2355 // Class::PatchFieldsAndFunctions().
2356 // This might also be necessary for lazy computation of local var descriptors.
2357 // Compare https://codereview.chromium.org//1317753004
2358 const Script& script = Script::Handle(zone, field.Script());
2359 const Class& field_owner = Class::Handle(zone, field.Owner());
2360 const auto& kernel_program_info =
2362 const PatchClass& initializer_owner = PatchClass::Handle(
2363 zone, PatchClass::New(field_owner, kernel_program_info, script));
2364 const Library& lib = Library::Handle(zone, field_owner.library());
2365 initializer_owner.set_kernel_library_index(lib.kernel_library_index());
2366
2367 // Create a static initializer.
2369 const Function& initializer_fun = Function::Handle(
2370 zone,
2371 Function::New(signature, init_name, UntaggedFunction::kFieldInitializer,
2372 field.is_static(), // is_static
2373 false, // is_const
2374 false, // is_abstract
2375 false, // is_external
2376 false, // is_native
2377 initializer_owner, TokenPosition::kNoSource));
2378 if (!field.is_static()) {
2379 signature.set_num_fixed_parameters(1);
2380 signature.set_parameter_types(
2382 signature.SetParameterTypeAt(
2383 0, AbstractType::Handle(zone, field_owner.DeclarationType()));
2384 initializer_fun.CreateNameArray();
2385 initializer_fun.SetParameterNameAt(0, Symbols::This());
2386 }
2387 signature.set_result_type(AbstractType::Handle(zone, field.type()));
2388 initializer_fun.set_is_reflectable(false);
2389 initializer_fun.set_is_inlinable(false);
2390 initializer_fun.set_token_pos(field.token_pos());
2391 initializer_fun.set_end_token_pos(field.end_token_pos());
2392 initializer_fun.set_accessor_field(field);
2393 initializer_fun.InheritKernelOffsetFrom(field);
2394 initializer_fun.set_is_extension_member(field.is_extension_member());
2395 initializer_fun.set_is_extension_type_member(
2396 field.is_extension_type_member());
2397
2398 signature ^= ClassFinalizer::FinalizeType(signature);
2399 initializer_fun.SetSignature(signature);
2400
2401 field.SetInitializerFunction(initializer_fun);
2402 return initializer_fun.ptr();
2403}
2404
2405} // namespace kernel
2406} // namespace dart
2407#endif // !defined(DART_PRECOMPILED_RUNTIME)
int count
#define IG
#define UNREACHABLE()
Definition assert.h:248
#define ASSERT_EQUAL(expected, actual)
Definition assert.h:309
#define Z
static bool IsFfiEnabled()
static ArrayPtr New(intptr_t len, Heap::Space space=Heap::kNew)
Definition object.h:10933
ObjectPtr At(intptr_t index) const
Definition object.h:10854
static ArrayPtr MakeFixedLength(const GrowableObjectArray &growable_array, bool unique=false)
Definition object.cc:25014
void SetAt(intptr_t index, const Object &value) const
Definition object.h:10858
KeyValueTrait::Value LookupValue(typename KeyValueTrait::Key key) const
Definition hash_map.h:159
void Insert(typename KeyValueTrait::Pair kv)
Definition hash_map.h:230
void Add(const T &value)
const T & At(intptr_t index) const
intptr_t length() const
static constexpr T decode(S value)
Definition bitfield.h:173
static constexpr S update(T value, S original)
Definition bitfield.h:190
void Add(intptr_t i)
Definition bit_vector.h:63
static const Bool & Get(bool value)
Definition object.h:10780
static AbstractTypePtr FinalizeType(const AbstractType &type, FinalizationKind finalization=kCanonicalize)
static bool ProcessPendingClasses()
intptr_t kernel_offset() const
Definition object.h:1806
LibraryPtr library() const
Definition object.h:1335
void set_is_declaration_loaded() const
Definition object.cc:5682
TypePtr DeclarationType() const
Definition object.cc:5882
static ClassPtr New(IsolateGroup *isolate_group, bool register_class=true)
Definition object.cc:3114
KernelProgramInfoPtr KernelProgramInfo() const
Definition object.cc:5615
bool IsTopLevel() const
Definition object.cc:6176
bool is_finalized() const
Definition object.h:1725
static void AddClosureFunctionLocked(const Function &function, bool allow_implicit_closure_functions=false)
static FunctionPtr LookupClosureFunctionLocked(const Function &member_function, intptr_t kernel_offset)
static DoublePtr New(double d, Heap::Space space=Heap::kNew)
Definition object.cc:23481
static ExternalTypedDataPtr New(intptr_t class_id, uint8_t *data, intptr_t len, Heap::Space space=Heap::kNew, bool perform_eager_msan_initialization_check=true)
Definition object.cc:25705
FunctionPtr InitializerFunction() const
Definition object.h:4777
ClassPtr Owner() const
Definition object.cc:11911
ScriptPtr Script() const
Definition object.cc:11922
void SetInitializerFunction(const Function &initializer) const
Definition object.cc:12369
@ kNoFixedLength
Definition object.h:4702
bool is_static() const
Definition object.h:4418
bool is_extension_member() const
Definition object.h:4423
StringPtr name() const
Definition object.h:4408
static FieldPtr NewTopLevel(const String &name, bool is_final, bool is_const, bool is_late, const Object &owner, TokenPosition token_pos, TokenPosition end_token_pos)
Definition object.cc:12090
AbstractTypePtr type() const
Definition object.h:4523
bool is_extension_type_member() const
Definition object.h:4426
TokenPosition end_token_pos() const
Definition object.h:4563
TokenPosition token_pos() const
Definition object.h:4562
KernelProgramInfoPtr KernelProgramInfo() const
Definition object.cc:11936
static bool SupportsUnboxedDoubles()
static bool SupportsUnboxedSimd128()
void set_result_type(const AbstractType &value) const
Definition object.cc:8633
void SetParameterTypeAt(intptr_t index, const AbstractType &value) const
Definition object.cc:8648
void set_num_fixed_parameters(intptr_t value) const
Definition object.cc:11659
void set_parameter_types(const Array &value) const
Definition object.cc:8655
static FunctionTypePtr New(intptr_t num_parent_type_arguments=0, Nullability nullability=Nullability::kLegacy, Heap::Space space=Heap::kOld)
Definition object.cc:11682
void set_accessor_field(const Field &value) const
Definition object.cc:8215
void set_end_token_pos(TokenPosition value) const
Definition object.h:3442
void InheritKernelOffsetFrom(const Function &src) const
Definition object.cc:10909
void CreateNameArray(Heap::Space space=Heap::kOld) const
Definition object.cc:8735
static FunctionPtr New(const FunctionType &signature, const String &name, UntaggedFunction::Kind kind, bool is_static, bool is_const, bool is_abstract, bool is_external, bool is_native, const Object &owner, TokenPosition token_pos, Heap::Space space=Heap::kOld)
Definition object.cc:10301
void set_token_pos(TokenPosition value) const
Definition object.cc:8959
void SetParameterNameAt(intptr_t index, const String &value) const
Definition object.cc:8681
intptr_t KernelLibraryOffset() const
Definition object.cc:10999
static FunctionPtr NewClosureFunctionWithKind(UntaggedFunction::Kind kind, const String &name, const Function &parent, bool is_static, TokenPosition token_pos, const Object &owner)
Definition object.cc:10382
static FunctionPtr NewClosureFunction(const String &name, const Function &parent, TokenPosition token_pos)
Definition object.cc:10406
TypedDataViewPtr KernelLibrary() const
Definition object.cc:10994
KernelProgramInfoPtr KernelProgramInfo() const
Definition object.cc:10977
void SetSignature(const FunctionType &value) const
Definition object.cc:8604
ClassPtr Owner() const
Definition object.cc:10899
static GrowableObjectArrayPtr New(Heap::Space space=Heap::kNew)
Definition object.h:11118
static Table::Storage::ArrayPtr New(intptr_t initial_capacity, Heap::Space space=Heap::kNew)
Definition hash_table.h:574
@ kNew
Definition heap.h:38
@ kOld
Definition heap.h:39
static IntegerPtr New(const String &str, Heap::Space space=Heap::kNew)
Definition object.cc:23063
ObjectStore * object_store() const
Definition isolate.h:505
SafepointRwLock * program_lock()
Definition isolate.h:532
void set_constants(const Array &constants) const
Definition object.cc:15136
intptr_t KernelLibraryStartOffset(intptr_t library_index) const
Definition object.cc:15140
intptr_t KernelLibraryEndOffset(intptr_t library_index) const
Definition object.cc:15161
LibraryPtr LookupLibrary(Thread *thread, const Smi &name_index) const
Definition object.cc:15181
ClassPtr LookupClass(Thread *thread, const Smi &name_index) const
Definition object.cc:15230
ArrayPtr constants() const
Definition object.h:5492
ArrayPtr scripts() const
Definition object.h:5489
TypedDataViewPtr constants_table() const
Definition object.h:5483
LibraryPtr InsertLibrary(Thread *thread, const Smi &name_index, const Library &lib) const
Definition object.cc:15203
ClassPtr InsertClass(Thread *thread, const Smi &name_index, const Class &klass) const
Definition object.cc:15252
bool Loaded() const
Definition object.h:5082
TypedDataViewPtr KernelLibrary() const
Definition object.cc:13648
ClassPtr LookupClassAllowPrivate(const String &name) const
Definition object.cc:14160
ClassPtr toplevel_class() const
Definition object.h:5179
intptr_t index() const
Definition object.h:5241
static LibraryPtr LookupLibrary(Thread *thread, const String &url)
Definition object.cc:14646
bool is_dart_scheme() const
Definition object.h:5259
static LibraryPtr InternalLibrary()
Definition object.cc:14850
StringPtr url() const
Definition object.h:5068
intptr_t kernel_library_index() const
Definition object.h:5280
jmp_buf * Set()
Definition longjump.cc:16
static ObjectPtr null()
Definition object.h:433
ObjectPtr ptr() const
Definition object.h:332
virtual const char * ToCString() const
Definition object.h:366
bool IsNull() const
Definition object.h:363
static Object & Handle()
Definition object.h:407
static Object & ZoneHandle()
Definition object.h:419
void set_kernel_library_index(intptr_t index) const
Definition object.h:2260
static ScriptPtr New(const String &url, const String &source)
Definition object.cc:13498
static SmiPtr New(intptr_t value)
Definition object.h:9985
bool EndsWith(const String &other) const
Definition object.cc:23751
bool Equals(const String &str) const
Definition object.h:13311
intptr_t CompareTo(const String &other) const
Definition object.cc:23717
static const char * ToCString(Thread *thread, StringPtr ptr)
Definition object.cc:24205
static const String & Symbol(intptr_t index)
Definition symbols.h:606
static StringPtr FromConcat(Thread *thread, const String &str1, const String &str2)
Definition symbols.cc:235
static const String & This()
Definition symbols.h:691
static const String & Empty()
Definition symbols.h:687
Zone * zone() const
static Thread * Current()
Definition thread.h:361
DART_WARN_UNUSED_RESULT ErrorPtr StealStickyError()
Definition thread.cc:243
IsolateGroup * isolate_group() const
Definition thread.h:540
intptr_t Length() const
Definition object.h:11492
virtual bool CanonicalizeEquals(const Instance &other) const
Definition object.cc:25629
static TypedDataPtr New(intptr_t class_id, intptr_t len, Heap::Space space=Heap::kNew)
Definition object.cc:25666
static constexpr bool IsAligned(T x, uintptr_t alignment, uintptr_t offset=0)
Definition utils.h:77
static const NativeType * FromAbstractType(Zone *zone, const AbstractType &type, const char **error)
virtual ClassPtr LookupClassByKernelClass(NameIndex klass, bool required=true)
virtual LibraryPtr LookupLibraryByKernelLibrary(NameIndex library, bool required=true)
ClassIndex(const TypedDataBase &kernel_data, intptr_t class_offset, intptr_t class_size)
InferredTypeMetadata GetInferredType(intptr_t node_offset, bool read_constant=true)
static void index_programs(kernel::Reader *reader, GrowableArray< intptr_t > *subprogram_file_starts)
ObjectPtr LoadExpressionEvaluationFunction(const String &library_url, const String &klass)
void LoadLibrary(const Library &library)
KernelLoader(Program *program, DirectChainedHashMap< UriToSourceTableTrait > *uri_to_source_table)
static void FinishLoading(const Class &klass)
static void FindModifiedLibraries(Program *program, IsolateGroup *isolate_group, BitVector *modified_libs, bool force_reload, bool *is_empty_program, intptr_t *p_num_classes, intptr_t *p_num_procedures)
ObjectPtr LoadProgram(bool process_pending_classes=true)
static FunctionPtr GetClosureFunction(Thread *thread, intptr_t func_decl_offset, const Function &member_function, const Function &parent_function, const Object &closure_owner)
const String & GetSourceFor(intptr_t index)
Tag ReadTag(uint8_t *payload=nullptr)
Tag PeekTag(uint8_t *payload=nullptr)
TypedDataViewPtr GetConstantCoverageFor(intptr_t index)
TypedDataPtr GetLineStartsFor(intptr_t index)
intptr_t SizeOfClassAtOffset(intptr_t class_offset) const
LibraryIndex(const TypedDataView &kernel_data)
intptr_t offset() const
void set_offset(intptr_t offset)
uint32_t ReadUInt32At(intptr_t offset) const
TypedDataViewPtr ViewFromTo(intptr_t start, intptr_t end)
intptr_t size() const
SimpleExpressionConverter(TranslationHelper *translation_helper, KernelReaderHelper *reader_helper)
bool IsSimple(intptr_t kernel_offset)
#define ASSERT(E)
#define FATAL(error)
FlutterSemanticsFlag flags
const uint8_t uint32_t uint32_t GError ** error
GAsyncResult * result
Dart_NativeFunction function
Definition fuchsia.cc:51
void Init()
size_t length
DirectChainedHashMap< UriToSourceTableTrait > UriToSourceTable
static constexpr int SpecializedIntLiteralBias
FunctionPtr CreateFieldInitializerFunction(Thread *thread, Zone *zone, const Field &field)
static const char *const kVMServiceIOLibraryUri
static const char *const names[]
Definition symbols.cc:24
const char *const name
@ kNumPredefinedCids
Definition class_id.h:257
@ kDynamicCid
Definition class_id.h:253
NNBDCompiledMode
Definition object.h:1128
constexpr intptr_t kWordSize
Definition globals.h:509
bool IsDeeplyImmutableCid(intptr_t predefined_cid)
Definition class_id.h:485
it will be possible to load the file into Perfetto s trace viewer disable asset Prevents usage of any non test fonts unless they were explicitly Loaded via prefetched default font Indicates whether the embedding started a prefetch of the default font manager before creating the engine run In non interactive mode
Definition switches.h:228
Definition main.py:1
#define Pd
Definition globals.h:408
#define DISALLOW_COPY_AND_ASSIGN(TypeName)
Definition globals.h:581
#define T
Definition SkMD5.cpp:130
#define TIMELINE_DURATION(thread, stream, name)
Definition timeline.h:39
#define NOT_IN_PRODUCT(code)
Definition globals.h:84