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